在稍早前的 JS Conf Berlin 上,被稱為 Nodejs 之父的 Ryan Dahl 發表了《10 Things I Regret About Node.js》演講,並且釋出了新專案 Deno,值得一提的是,這是 Ry 的第二次公開演講,而第一次是釋出 Node.js,本文將帶領大家回顧一下 Ry 演講上所提到的重點。
演講第一部分: Nodejs 的成功
這一部分,講了 Node 的發展歷程,Ry 認為 Node 在 I/0,事件驅動的 http server 方面已經做得很好了,提到了 Node 對一些協議的支援,跨平臺,以及 npm 生態系統等促成 Node 成功的因素,以及感謝了一些為 Node 做出過貢獻的人。 Ry 始終認為 JavaScript 是最好的動態語言,而動態語言用來做科學計算是合適不過了(這可能和 Ry 離開 Node 後加入 Google 的 Brain 團隊,從事深度學習方面的研究的歷程有關)。
演講第二部分: 對 Nodejs 的吐槽
這一部分可以說是整個演講的高潮,前後吐槽了 Node 上 7(不是應該 10 個麼???) 個讓 RY 覺得遺憾的設計。
1. 沒有堅持使用 Promise
Promise 是 async/await 的必要抽象,Promise 的沒有堅持使用導致後面 Node 的很多非同步 API 嚴重老化。
2. 沒有足夠的安全性
V8 本身是一個非常好的沙箱環境,但是 Node 在早期的設計中卻沒有利用好這一先天優勢,導致程式可以輕鬆訪問系統和網路。
3. 錯誤地堅持使用 GYP
由於 Chrome 放棄了 GYP,使得 Node 是 GYP 唯一的使用者,並且 Ry 認為這其中有太多的複雜且不必要的抽象,與其讓使用者自己去編寫 C++ 擴充套件來繫結 V8,不如提供一個核心外部函式介面來得更加可靠。Ry 認為在構建系統上的設計錯誤是 Node 的最大遺憾。
4. package.json
package.json 因為 require 的支援,使得這後來成了事實上的模組標準,可是很遺憾,因為默許了 package.json 的存在,可是 require(‘module') 又是不明確的,導致當出現本地依賴庫或者私有依賴庫時候,變得很混亂。並且 package.json 包含了太多冗餘描述,許可證,倉庫,描述等等,而且 package.json 提出的“module”作為檔案目錄也不是必要的抽象。
5. node_module
增加了模組的解析複雜度,並且是偏離了瀏覽器語義,但是現在已經沒法剔除出去了。
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,還為大型開源專案貢獻過原始碼....
參考資料: