【JSConf EU 2018】Ryan Dahl: Node.js 的設計錯誤

在稍早前的 JS Conf Berlin 上,被稱爲 Nodejs 之父的 Ryan Dahl 發表了《10 Things I Regret About Node.js》演講,而且發佈了新項目 Deno,值得一提的是,這是 Ry 的第二次公開演講,而第一次是發佈 Node.js,本文將帶領你們回顧一下 Ry 演講上所提到的重點。html

來自 twritter 網友 @malweene 的手繪歸納

演講第一部分: Nodejs 的成功

這一部分,講了 Node 的發展歷程,Ry 認爲 Node 在 I/0,事件驅動的 http server 方面已經作得很好了,提到了 Node 對一些協議的支持,跨平臺,以及 npm 生態系統等促成 Node 成功的因素,以及感謝了一些爲 Node 作出過貢獻的人。 Ry 始終認爲 JavaScript 是最好的動態語言,而動態語言用來作科學計算是合適不過了(這可能和 Ry 離開 Node 後加入 Google 的 Brain 團隊,從事深度學習方面的研究的歷程有關)。前端

演講第二部分: 對 Nodejs 的吐槽

這一部分能夠說是整個演講的高潮,先後吐槽了 Node 上 7(不是應該 10 個麼???) 個讓 RY 以爲遺憾的設計。java

1. 沒有堅持使用 Promise

Promise 是 async/await 的必要抽象,Promise 的沒有堅持使用致使後面 Node 的不少異步 API 嚴重老化。node

2. 沒有足夠的安全性

V8 自己是一個很是好的沙箱環境,可是 Node 在早期的設計中卻沒有利用好這一先天優點,致使程序能夠輕鬆訪問系統和網絡。git

3. 錯誤地堅持使用 GYP

因爲 Chrome 放棄了 GYP,使得 Node 是 GYP 惟一的用戶,而且 Ry 認爲這其中有太多的複雜且沒必要要的抽象,與其讓用戶本身去編寫 C++ 擴展來綁定 V8,不如提供一個核心外部函數接口來得更加可靠。Ry 認爲在構建系統上的設計錯誤是 Node 的最大遺憾。github

4. package.json

package.json 由於 require 的支持,使得這後來成了事實上的模塊標準,但是很遺憾,由於默許了 package.json 的存在,但是 require(‘module') 又是不明確的,致使當出現本地依賴庫或者私有依賴庫時候,變得很混亂。而且 package.json 包含了太多冗餘描述,許可證,倉庫,描述等等,並且 package.json 提出的「module」做爲文件目錄也不是必要的抽象。npm

5. node_module

增長了模塊的解析複雜度,而且是偏離了瀏覽器語義,可是如今已經無法剔除出去了。json

6. require('module') 沒有加上擴展名".js」

畫蛇添足的作法,模塊加載器必須得去猜想是‘.js’仍是’.json’,而且也是跟瀏覽器語義不符的。後端

7. index.js

實際上默認去加載 index.js 也是沒有必要的,由於可能會有 index.html….瀏覽器

以上提到的遺憾都主要集中在代碼管理上而非早期 Ry 關注的創建高性能服務器上。實際上在 Ry 提出這些遺憾的時候,至關於已經提出了新一代 js/ts 的 v8 runtime 的原型 -> Deno,而其主要目標就是解決以上問題。

演講第三部分: 對 Deno 的介紹和指望

1.安全性

Deno 將利用 JS 是安全沙箱的事實,容許安全運行不受信任的程序

  • 默認狀況下,不容許程序直接訪問網路或者文件系統
  • 能夠經過 —allow-net —allow-write 的方式訪問 不容許擴展函數直接綁定到 V8 上,簡化流程,也易於審計
  • 全部系統調用都經過消息傳遞完成(protobuf 序列化)
  • 兩個原生函數: send 和 recv

2.簡化模塊系統

  • 不會去嘗試和現有 Node 模塊系統兼容
  • 僅導入相對/絕對的 URL,而且導入路徑必須提供擴展名
  • 遠程 URL 在第一次加載以後將被永遠緩存,只有提供 --reload 才能再次獲取資源,能夠經過指定非默認緩存目錄來繞過

3.將 TypeScript 編譯器內置於可執行文件之中

  • Deno 內置 TS 編譯器以實現模塊解析與構建結果的增量緩存
  • 未修改的 TS 文件不會被從新編譯
  • 普通 JS 也一樣有效
  • 利用 V8 的 snapshot 來快速啓動,暫未在原型中設計 (參考《使用 v8 snapshot 將啓動速度提高 8 倍》)

4.單個可執行文件

5.充分利用 2018 技術優點

使用 Parcel 把 Node 模塊編譯打包,來實現運行時的自舉。

以原生代碼的方式提供強大的基礎設施

  • 已有其餘機制負責實現 HTTP,而此前的 Node 是沒法實現的
  • 目前 Deno 的非 JS 部分以 go 語言編寫,但還沒全面完成原型設計,其實 Rust 和 C++ 在某些方面也不錯

6.其它

  • 發生未捕獲 Promise 錯誤時直接終止程序
  • 支持 top-level 的 await
  • 兼容瀏覽器(當功能重疊時)

Ry 的演講大體就是以上這些內容,儘管 Deno 目前仍是不可用的,也沒有發行二進制版本,可是該項目推出短短很多天便得到了上萬個 Star。

後話:

目前大前端開發的工程化,SSR 等能力基本都由 Node 提供,加上一些利用 Node 優點而搭建的後端服務,都有必定發展時間,所以對於 JS 開發者而言 Node 在將來很長一段時間內依然是值得繼續學習的一個項目。

固然若是 Deno 有部分設計你是承認的,那如今最好的方法就是開始投資學習,從學習 Go 語言開始,學完 Go 就去看 Deno 源碼,邊看還能夠邊提 PR,看完 Deno 源碼後 API 也差很少出來了,你就能夠用 TypeScript 寫 Demo 了,最後即便 Deno 沒人用進了博物館,你還學會了 Go 和 Typescript,還爲大型開源項目貢獻過源碼....

參考資料:

相關文章
相關標籤/搜索