書名: JavaScript語言精髓與編程實踐(第3版)作者名: 周愛民本章字?jǐn)?shù): 3356字更新時間: 2020-07-02 15:37:32
1.5 大型系統(tǒng)開發(fā)
1.5.1 框架與架構(gòu)是不同的
我加入阿里巴巴工作的時候,前端并不算在技術(shù)部門:當(dāng)時的支付寶,前端是產(chǎn)品部里的一個小型團(tuán)隊。而我也并不負(fù)責(zé)前端方面的工作—事實上直到現(xiàn)在,我也并沒有在前端部門中工作過—我當(dāng)時收到的Offer是業(yè)務(wù)架構(gòu)師。
那正是在國內(nèi)前端研發(fā)開始崛起的時候。我參加了2008年的D2大會(Designer&Developer Frontend Technology Forum),記得那時,Hedger主講的話題就是Yahoo的前端框架YUI。而在隨后的SD2C大會(Software Development 2.0 Conference)上,我將之前在JavaScript、Delphi和Erlang三種語言上的研究打包,通過“Erlang in Delphi”項目公布了出來。差不多直到2010年,我在前端方面的主要工作集中在一些商業(yè)推廣和技術(shù)推動性質(zhì)的大會上。類似地,這一年的QCon大會北京站,Douglas Crockford帶來的《JavaScript的現(xiàn)狀和未來》,也事實上代表了ES5在國內(nèi)的正式推動。
與2008年的D2大會僅僅相距兩年,整個行業(yè)已經(jīng)將話題從“一種框架的使用”轉(zhuǎn)向了對JavaScript的前途與命運(yùn)的探討上。緣于我的工作性質(zhì),我得以有更多的時間來與前端討論架構(gòu)問題,例如,什么是架構(gòu)、框架與庫,以及它們的實戰(zhàn)
。不過即便如此,我仍然一直游離于前端工作之外,唯一一次對前端的影響,大概是在Kissy.js的評審和重構(gòu)
中為核心架構(gòu)添加了seed的概念(即具有meta性質(zhì)的host對象)。就是因為這件工作的無心插柳,我的名字也被記入這個項目的交付歷史中。這算是我從WEUI、Qomo、QoBean等項目一路行來,多年來所思所得的最后一點印記。
正是在這些看似與前端不著邊際的工作中,我漸漸了解到前端對框架和架構(gòu)有著獨立的、深刻的而又迫切的需求。然而這時的Qomo項目卻是實實在在地停下來了:一方面我沒有了語言探索上的動力,另一方面也缺乏將它們應(yīng)用于大型項目的推動能力與業(yè)務(wù)環(huán)境。因為Qomo與QoBean在本質(zhì)上是探討了JavaScript這門語言的一種擴(kuò)展模式,即基于語言自身的原子特性進(jìn)行二次實現(xiàn)的能力。這種能力是代碼級別的組織變化,而對工程對象(即具體的項目)影響很小。
我只是在探索JavaScript這門語言的邊界,然而現(xiàn)實卻走向了工程化的大型系統(tǒng)開發(fā)。
1.5.2 大型系統(tǒng)與分布式的環(huán)境
最先對“工程化”做出響應(yīng)的就是林林總總的“模塊加載”方案。這些方案既嘗試通過類似名字空間的方法來解構(gòu)大型系統(tǒng)的復(fù)雜性,又試圖對JavaScript的全局環(huán)境進(jìn)行再次規(guī)劃。不過歸結(jié)起來,所有的努力其實都是在為“ES5否定了ES4”這件事償還技術(shù)債。
然而我所面臨的問題卻與此不同。這時我已經(jīng)辭去在支付寶的工作,在2013年4月加入了豌豆莢。在很長的一段時間里,我工作在后端,并致力于解決資金、賬戶等系統(tǒng)中的風(fēng)控問題。更確切地說,關(guān)鍵的架構(gòu)決策是如何在Nginx環(huán)境下尋求一個高效的技術(shù)方案,以使風(fēng)控系統(tǒng)對其他業(yè)務(wù)系統(tǒng)的影響最小。而我最終的選擇是嘗試將整個服務(wù)端環(huán)境理解為統(tǒng)一調(diào)度的可計算資源,將每一個風(fēng)控對象(例如資金操作的行為路徑或用戶賬戶)理解為一個可計算節(jié)點,并將這一切構(gòu)建在一起變成一個實時計算的集群。這樣一來,每一個風(fēng)控對象的行為(數(shù)據(jù)的或用戶的等)在這個集群節(jié)點的任意位置都可以得到處理,例如推送風(fēng)控告警或者實施系統(tǒng)決策的風(fēng)控措施。
于是我得到了一個稱為N4C的分布式架構(gòu),它看起來與JavaScript沒什么關(guān)系,因為它其實是基于Nginx上的Lua來實現(xiàn)的。不過從一開始,N4C就借鑒了ECMAScript實現(xiàn)并行系統(tǒng)的思想:使用Promise。為此我還專門完成了Promise類在Lua上的實現(xiàn)。當(dāng)然,對前端歷史了解得多一些的讀者也會知道,這也是我后來被卷入“紅綠燈大戰(zhàn)”的緣由。
隨后我將N4C發(fā)布為一個通用分布式并行架構(gòu)的規(guī)范,在這個規(guī)范下分別交付了它的Lua和JavaScript實現(xiàn)。后者就是被稱為Sandpiper的項目,它使用etcd實現(xiàn)集群中的核心數(shù)據(jù)存儲和心跳通知。并且,(當(dāng)然,)它使用Node.js作為運(yùn)行環(huán)境。
到了2016年上半年,也就是在這個風(fēng)控系統(tǒng)以及相關(guān)的開源項目發(fā)布之后不久,豌豆莢被阿里巴巴收購了。我沒有回到阿里巴巴,而是來到了一家旨在簡化智能硬件開發(fā)的互聯(lián)網(wǎng)公司(ruff.io)。在Ruff項目中,我們試圖將JavaScript編譯到嵌入式操作系統(tǒng)的內(nèi)核,以便在芯片或模組級別提供類似Node.js的開發(fā)環(huán)境,并且最終使JavaScript引擎在這樣的操作系統(tǒng)環(huán)境下解釋執(zhí)行。基于這個理念,Ruff提供了一個與Node.js+NPM類似的開發(fā)環(huán)境,以及遠(yuǎn)程操作嵌入式系統(tǒng)內(nèi)核的方式—最后,將這一切集成在開發(fā)板上。
然而這與互聯(lián)網(wǎng)有什么關(guān)系呢?我隨后需要解決的問題正在于此:如何將一個開發(fā)板(以及它所代表的、設(shè)備化的物聯(lián)網(wǎng)絡(luò))帶入互聯(lián)網(wǎng)環(huán)境中。我提出了稱為Sluff的項目,并在這個項目中再一次啟用了Promise這個“大殺器”,以實現(xiàn)各個物聯(lián)設(shè)備的并行計算和集中調(diào)度。有了Sluff,就可以將一個或多個子級的物聯(lián)網(wǎng)理解為全局的、整體的物聯(lián)網(wǎng)的一個節(jié)點,通過各自的、邊緣化的計算來交付數(shù)據(jù)或響應(yīng)網(wǎng)絡(luò)消息。Sluff的核心在于管理這些設(shè)備的抽象(將它們映射為邏輯對象),并讓設(shè)備中的行為變成一個個Promised的數(shù)據(jù)、時間點、動作或者失效處理。
ES5之后的十年,無論是金融級的風(fēng)控系統(tǒng)還是物聯(lián)網(wǎng)環(huán)境,我所見到的,是JavaScript在不停地向它周邊的領(lǐng)域滲透。不可否認(rèn),是ECMA賦予了JavaScript新的能力和活力,然而JavaScript自身作為混合語言的原始設(shè)計與思想,仍然是這門語言的核心所在。
1.5.3 劃時代的ES6
在ES5成功發(fā)布之后,JavaScript也迎來了它的好時代。一方面,ES5總算對已有的那些JavaScript實現(xiàn)版本中存在的諸多不同現(xiàn)象給出了結(jié)論,另一方面則從規(guī)范層面杜絕了在“多種特性的進(jìn)化路線”這一問題上選邊站隊—盡管其結(jié)果是什么選擇都沒有做,但實際上也是開放了各種選擇的可能。
得益于TC39工作小組的創(chuàng)新性的努力以及強(qiáng)大的包容性,許多在社區(qū)中的聲音被關(guān)注到,大量提議作為語言的新特性得以采納。ECMAScript走上了一條不同以往的進(jìn)化之路,并在盡量滿足社區(qū)愿望和控制語言一致性之間取得了平衡。通過各種shims或第三方包,新的語言特性在規(guī)范定義之前就被開發(fā)人員“嘗鮮”,因此再將這些特性寫進(jìn)規(guī)范就幾乎不會碰到什么阻力。甚至有些語言特性在還沒有進(jìn)入規(guī)范的提案階段,就已經(jīng)成了立時可用的、流行的事實標(biāo)準(zhǔn)。
社區(qū)強(qiáng)大而豐富的能量灌注以及TC39孜孜不倦的努力,終于聯(lián)手打造了ECMAScript史上最大的一次升級:在2015年6月,ES6發(fā)布了。這個ECMAScript版本幾乎集成了當(dāng)時其他語言夢寐以求的所有明星特性,并優(yōu)雅地、不留后患地解決了幾乎所有的JavaScript遺留問題—當(dāng)然,其中那些最大的、最本質(zhì)的和核心的問題其實都已經(jīng)在ES5推出時通過“嚴(yán)格模式(strict mode)”解決了。
ES6提出了四大組件:Promise、類、模塊、生成器/迭代器。這事實上是在并行語言、面向?qū)ο笳Z言、結(jié)構(gòu)化語言和函數(shù)式語言四個方向上的奠基工作。相對于這種重要性來說,其他類似于解構(gòu)、展開、代理等看起來很炫很實用的特性,反倒是浮在表面的繁華了。隨后各大引擎紛紛對這一新版本規(guī)范明確表明歡迎和支持,其中類似Chrome V8這樣的引擎由于一開始就參與規(guī)范的制定工作,所以大量特性已經(jīng)在先期版本中發(fā)布過了,因而也收獲了滿滿的技術(shù)紅利。盡管一部分應(yīng)用環(huán)境仍然需要較簡捷的語言特性的支持,并推動了一股在ES5規(guī)范上發(fā)展的潛流,其中包括duktape、JerryScript、Espruino、mJS等。然而隨著支持ES6的新引擎如雨后春筍般崛起,ES5的時代終歸已經(jīng)落幕,繁華不再。
主流引擎廠商開始通過ES6釋放出它們的能量,于是JavaScript在許多新的環(huán)境中被應(yīng)用起來,大量的新技術(shù)得以推動,例如,WebAssembly、Ohm、Deeplearn.js、TensorFlow.js、GPU.js、GraphQL、NativeScript等。有了Babel這類項目的強(qiáng)大助力,新規(guī)范得以“讓少數(shù)人先用起來”,而標(biāo)準(zhǔn)的發(fā)布也一路披荊斬棘,以至于實現(xiàn)了“一年一更”。眾多利好迅速反饋給前端,現(xiàn)在它們有了:
■ Chrome等瀏覽器中由內(nèi)置高性能JavaScript引擎所釋放出來的強(qiáng)大算力。
■ W3C+ECMAScript推動的Web環(huán)境全面標(biāo)準(zhǔn)化帶來的統(tǒng)一且一致的技術(shù)藍(lán)圖。
■ Node.js等推動的前后端同構(gòu)的開發(fā)語言和執(zhí)行環(huán)境。
于是,之前被框架技術(shù)所引領(lǐng)的前端開始將注意力投放到本地渲染和工程化上。主流的技術(shù)方向從此開始進(jìn)入工程化時代,帶來了面向統(tǒng)一用戶接觸層的前端工程化、平臺化和標(biāo)準(zhǔn)化等明顯的跨代與跨界特征。試圖將應(yīng)用或產(chǎn)品邏輯前移的所謂“大前端”應(yīng)運(yùn)而生。至此,無論是在技術(shù)、工程還是組織等各個方面,前端都贏得了開創(chuàng)性的局面。
隨著工程與項目規(guī)模的擴(kuò)大,JavaScript語言的一項早期設(shè)計越來越成為一切發(fā)展的阻礙—它是一門弱類型、動態(tài)類型的語言。于是JavaScript不得不在推廣過程中面臨如何提供靜態(tài)類型系統(tǒng)的問題,從而推動了TypeScript和Dart這類以ECMAScript轉(zhuǎn)譯器作為賣點的新語言的誕生。類似地,還有Facebook推出的Flow在靜態(tài)類型檢查方面的努力。而在這些語言和輔助工具的背后還有一股更為新生的力量,即打算對類型注解(Type annotations)做出規(guī)范的ECMAScript,它們被稱為裝飾器(Decorator)。
無論是面向語言自身的發(fā)展,還是應(yīng)對語言應(yīng)用環(huán)境的變化,它們貌似推動JavaScript行進(jìn)在完全不同的道路上,但根本上卻有著基本相同的限制、策略,以及目的。
- Java深入解析:透析Java本質(zhì)的36個話題
- Banana Pi Cookbook
- SAS數(shù)據(jù)統(tǒng)計分析與編程實踐
- Hands-On Microservices with Kotlin
- AppInventor實踐教程:Android智能應(yīng)用開發(fā)前傳
- 區(qū)塊鏈技術(shù)與應(yīng)用
- Getting Started with Eclipse Juno
- Oracle GoldenGate 12c Implementer's Guide
- INSTANT Yii 1.1 Application Development Starter
- Geospatial Development By Example with Python
- 寫給程序員的Python教程
- Java Web應(yīng)用開發(fā)給力起飛
- Hadoop大數(shù)據(jù)分析技術(shù)
- 貫通Tomcat開發(fā)
- R語言編程:基于tidyverse