Web平臺能從Node.js學到什麼

轉自:http://www.infoq.com/cn/news/2015/12/what-webplatform-learn-from-node

Will Binns-Smith是一位熱愛JavaScript的全棧工程師,喜歡通過技術來解決實際問題。他開發了Bonobos.com的前端購物車功能。Will喜歡與設計師一對一工作,將PC網站轉換爲針對更小的觸摸設備的站點。近日,Will撰寫了一篇文章,談到了Node.js有哪些做法和特性值得Web平臺學習。

作爲一名Web開發者,我們會非常感激jQuery之類的庫,因爲他們消除了底層平臺的各種不一致與笨拙的情況。曾幾何時,構建一個XMLHTTPRequest對象需要好幾行代碼,但現在只需一行$.ajax調用即可;通過jQuery與DOM交互很少需要我們針對特定的平臺採取一些非常規手段,因爲這一切jQuery都幫我們做好了。

使用過Python或是Java語言的開發者都知道這些語言自帶了標準庫。在瀏覽器端,jQuery就是這樣的標準庫,此外還有諸如underscore之類的工具集。就像大多數標準庫一樣,我們所編寫的代碼都會嚴重依賴於他們。當越來越多的代碼開始依賴這些APIs時,我們就很難在不破壞既有Web的情況下向前邁進了。不要妄圖爲了兼容性而包含進這些庫的多個版本,他們常常會有30KB的大小,而且默認情況下會向全局的window對象寫入。

過去,我認爲這是軟件開發不可避免的一個問題。但現在一切都變了,至少對於我來說是這樣的,因爲Node.js生態圈出現了。

小模塊與組合的出現

Node是一個構建在Chrome V8引擎之上的JavaScript運行時,它幾乎沒有多少標準庫。相反,其他生態圈中的那些標準庫都不在其核心平臺中,而是通過npm獲取的。

在npm中,小模塊已經成爲了標準,像是substack和Sindre Sorhus這樣的用戶分別已經發布了685和760個模塊,這些模塊都遵循着UNIX一次只做一件事,並將這件事做好的原則。像是array-union(返回兩個數組的並集)與svg-create-element(提供了用於在DOM中創建SVG的優秀API)這樣的模塊都是非常小的,看起來應該與語言或是平臺一同發佈。

Sindre甚至還有一個名爲negative-zero的模塊,它只是判斷一個值是否是-0,實現只有一行代碼。看起來爲這樣簡單的功能創建一個包有些極端,因爲用戶可以在自己的代碼中實現這樣的功能,不過通過這種方式,我們可以集中修改代碼,而不必重複實現細節。Sindre對此有個很詳盡的介紹,感興趣的讀者可以看看。

甚至連非常流行的Express Web框架也只提供了Web應用的核心功能而已。與諸如Ruby on Rails或是Django這樣的大型框架不同(本身帶有模板、ORMs、csrf防護,以及其他特性),Express本身只提供了託管靜態文件的中間件。相反,應用開發者可以自由使用他們喜歡的這些特性的實現,並將其組合起來創建應用。隨着想法的不斷改進,很多中間件包創建又消亡,一些發展起來了,另一些則消失了。這就是Node的哲學。

因此,小模塊(以及由這些模塊所構成的應用)會擁有非常龐大的依賴圖(比如說,Bitbucket的前端包含了1000多個JavaScript模塊,其中一些是內部模塊,另外一些則來自於npm)。

這些模塊最棒的一點就是他們並沒有緊密綁定到平臺上:他們不會受到標準庫的影響,藉助於語義版本化,他們可以對其API進行迭代而不會對依賴他們的用戶造成困擾。

流介紹

Node包含了流,它是異步流動數據的一個抽象,常常用於連接和轉換I/O源。Node對流的初始實現(隨Node 0.4發佈)並不完善,使用不當會導致數據丟失。爲了解決這一問題,Node 0.10對流進行了修正(也叫做Streams2)。不過,Streams2並不是對流模式的一個簡單迭代,實際上在Node 0.10發佈前經歷了很多的變化。在發佈時,它與運行在Node 0.8上的應用兼容。

這怎麼可能呢?Streams2源自於readable-stream模塊,一開始它就是Isaac Schlueter在2012年7月發佈的獨立模塊,這距離2013年3月它隨着Node 0.10的發佈已經相隔很長時間了。它經歷了多次迭代,在這個過程中API與功能也不斷成熟,Node社區發現它非常適合於作爲流的實現。

時至今日,readable-stream的最新實現也是作爲用戶模塊在npm中維護的,可用於Node 0.8及之前的版本中。很多用戶都喜歡使用用戶模塊而不是綁定的模塊,這樣可以實現生態圈的兼容性。

一系列不幸的APIs

與此相反,JavaScript與Web平臺中現有的APIs都是很難改變的。對JavaScript語言的迭代變更(不能有任何的向後不兼容變化以防止現有系統出現問題)必須要通過添加新特性來實現。比如說,在發現Mutation Events API的性能問題後,人們引入了Mutation Observers來解決這個問題;廢棄WebSQL,擁抱更加底層但使用起來卻略顯笨重的IndexedDB;逐步淘汰Application Cache,擁抱更加底層但更通用的ServiceWorker。Object.observe是ES2016的一個提案,通過它可以觀測對象的屬性,不過在React的單向數據流逐步流行起來併爲主流所採用後,Object.observe提案則被撤回了。

對這些感到困惑麼?我們不應該期待着一下子就將事情做對,不過我們需要一個平臺,通過這個平臺可以試錯,然後逐步向好的方向迭代。

平臺演化

可擴展的Web宣言的支持者們希望Web能夠像Node那樣提供彈性的用戶試錯空間。其使命是讓平臺提供儘可能多的底層構建塊,這樣瀏覽器之外的庫就可以自由嘗試,從而避免正式的標準化流程所經歷的代價高昂且冗長的過程。其中一種這樣的底層原語就是Web Components的APIs,它向開發者提供了通過JavaScript來創建動態自定義元素與屬性的能力,這一切都是通過封裝來實現的。一個庫無論大小都實現了對話框功能,不過API的迭代可以交給用戶來完成,一開始無需放在平臺內部實現。藉助於底層原語,用戶可以通過小模塊的形式自由探索更高層次的抽象。換句話說,我們不再需要AppCache了。

幸好,我們已經看到了這種做法的好處。我們無需再陷入諸如AppCache這種實際使用很少的特性了。相反,我們有了一個Promises A+ Specification的標準化實現,npm中的Q已經證明了這一點,並且在年初已經成爲了ES2015的一部分。WHATWG也在制訂流的規範,在很大程度上它受到了來源於Node的流的演化的影響。

就像平臺的其他方面一樣,這些新標準是很難改變的,不過幸運的是,其想法與APIs都是通過用戶來實現的,這一切都要歸功於Node!

發佈了93 篇原創文章 · 獲贊 22 · 訪問量 7萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章