Oursky Team

We Develop for Developers. We open source best practices for product development for web and mobile. Visit us at oursky.com

Follow publication

Node.js 開發之父:「十個Node.js 的設計錯誤」- 以及其終極解決辦法

David Ng
Oursky Team
Published in
8 min readJun 20, 2018

--

“10 Things I Regret About Node.js” — Ryan Dahl

「養不教,父之過」- Node.js founder Ryan Dahl 在 JSconf 2018 點評了十個在設計和更新 Node.js 時犯下的錯誤。

發現中文圈子還沒有太多關於這資訊的整理,在這裡輕輕的寫一下。

2008年 Chrome 才剛剛出現(現在已經更新到v66.0了);而 Node.js 也其實也是至十年冒起的代表 - 它只是2009年的產物,現在出到version 10 ,卻在軟件界家傳戶曉了。

不過有用過 Node.js 作 production 的工程師,應該很同意,Node.js 其中的一個中重要的 f̵e̵a̵t̵u̵r̵e̵ 就是:Memory leak。所以在實戰時,往往都要用 forever 來自動定時重啟 Node.js Server。

🔧 很多基層的設計錯誤

要了解這些錯誤及其重要性,可能要對程式語言設計和軟件工程有深入點的認識。Ryan Dahl 在Node.js 中的設計和應用,都直接或間接都影響了不少重要的軟件,甚至整個軟件行業。(因為有不少軟件和平台都以 Node 為根基)

Ryan Dahl 在演講中用了個很嚴重的說法指出:

動態語言適合用於一次性的科學用演算,而 JavaScript就是最好的例子。

不然,Node中充滿著值得投訴的缺陷。

原文:

Dynamic languages are the right tool for scientific computing, where often you do quick one-off calculations. And JavaScript is a the best dynamic language.

Rather I will complain about all the warts in Node.

真的是相當嚴重的悔懊。 因此,他以「Design mistakes in Node」為題,指出了十個「悔不當初」的錯誤:

後悔之一:沒有堅持使用 Promise

2009年六月在 Node 中開始引入 JavaScript 的 Promises,但又在 2010年二月就移除掉了。

結果,隨著日子久遠,Node裏面就遍佈著 async/await 和 promise 的不同 async API設計,直至現時都極難整合。

後悔之二:看輕了安全性(Security)

JavaScript Engine V8 本身有很好的 sandbox 架構,但是有時候 Node.js 本身沒有好好善用到,例如有可以直接讀取 Memory 的 例子、或者 linter 可以直接使用網絡功能等的漏洞。

後悔之三:沒有從 GYP 建構系統轉到 GN

Node.js 用到的 JavaScript Engine V8 一開始是使用 GYP 來建構的,Node 理所當然也跟隨;後來 V8 轉用了 GN (Generate Ninja),只剩下Node 成為唯一的用家。GN 比用 Python 寫的 GYP 快近起碼 20倍,對於使用者來說,簡直是天淵之別。

Ryan 更這樣說:

繼續使用 GYP 該是Node 核心的最大失誤。

The continued usage of GYP is the probably largest failure of Node core.

後悔之四:繼續使用 GYP,沒有提供 FFI

繼續用 GYP 引伸到另一個難題,就是怎樣去提供跨程式語言的接口。

現在Node 只提供了由 C++ 到 V8 的 binding 指南,事實上對開發者來說是嚴重不足的。很多人建議過轉用 Foreign Function Interface (FFI)的模式,但都一一被當時的 Ryan 漠視了。

後悔之五:package.json (以及依賴了 npm)

npm 的 Issac 發明了 package.json,Ryan 認為把 Node 能在 main program 中 用 require() 讀取 npm 的 package.json 是一個壞的開始。

後來,演化至 Node 中包含 npm 作為標準,以致現在Node 的 Module 變成了由 npm「中央集權」了。

事實上,因為 npm 而引起的「災難性」事件也有不少,其中最有名的應該算是 2016 年發生的 left-pad chaos

後悔之六:在任何地方也可以 require(“somemodule”)

你可以不必在 package.json 中註明 dependency,在Node 中近乎是任何地方也能夠 require local 或者是 remote 的程式碼。

後悔之七:package.json 提供了錯誤的「module」觀念

你以為放在同一個 folder 裏的就是一個「module」,少年你太年輕了。其實並沒有這樣的一個機制。

其實現在package.json並沒有「公認標準」,裏面可以包含很多毫無關係的資訊,例如名稱、版本、 License、詳細說明等,以致 package.json 這個檔案像是雜物房一樣。

例如我們用 URL 導入檔案的話,URL 裏就以包含了所需的版本資訊,而不應再寫在 package.json 裏了。

後悔之八:設計了軟件界黑洞 node_modules…

有試過 npm install 後,要等很久,然後發現應用下載了幾百 mb 的 node_module嗎?

這是因為 Node 裏「Vendored-by-default」 機制有點「好心做壞事」。從而令 node_module 「主動地」安裝了所有module 的 dependencies。這個設計令要處理 node_module 的方式變得超複雜,也變成 Node 裏面最令人苦惱的一個地方。

Ryan 對這個設計應該是徹底地後悔了。

「這是我的錯-十分抱歉。

不幸的是,現在已經無法砍掉了。」

It’s my fault and I’m very sorry.

Unfortunately it’s impossible to undo now.

後悔之九:require(“module”) 沒有逼人用file extension”.js”

不知道為甚麼要這樣「簡潔」。

在瀏覽器中 <script> tag 是不能省略「.js」部分的,這令Node要多用幾次不必要的檔案系統查詢,才能猜到工程師想要import 甚麼檔案。

後悔之十:index.js

由於 index.html 的傳統,「很合理」有 index.js 吧? 但其實有了 package.json後, index.js 就變得不必要了。

結論

Node.js 現在遇到的問題,其實大多上都是軟件管理上的問題, 例如 API、FFI 、導入檔案的方法和 dependency management 上的痛苦。

結果,Ryan 針對以上的反思,提出了一個方案:就是開發以安全性、程式碼清潔性、符合 2018 年標準為原則的框架 - deno。

deno 是以 Golang + yarn + TS 為主要的 Tech stack,捨棄了Node.js 本來 C++ 和 JavaScript。deno 暫時還是在超初步的階段,要試玩的話,還是要由 source code 自行compile。

不過, Ryan 看來相當滿意 deno 暫時的設計(起碼應該不會犯和 Node 相同的錯誤了)。

有興趣的可以看看 JSConf 的錄影,相當精彩。

[Slides] http://tinyclouds.org/jsconf2018.pdf

小花絮

這個「可能會取代 Node.js 」的新產品,好像在中國大陸惹起不少討論。

但其實deno 並不是想要直接取代 Node.js 的,而是提出一個新的框架去協助工程師去建構未來更加合用的軟件。

看來Ryan 和其他人都看好它的未來, 我們就好好期待 deno 吧!

後記

ry 又發布了 deno2 的原型,主要是是用 GN 作為建構工具。新版本的 deno 有不少改動,包括移除了 golang、加入了 C++的 libdeno,未來甚至可能用 rust 去重練 C++ 的部分。

deno2 的實體:

喜歡我們的創作嗎?你也可以透過 Likecoin 來支持我們(以及所有創作者!)🥇

另外,Oursky 的 Medium 帳號也有不少的中文技術文章。如果你喜歡這篇文章,歡迎追蹤獲得更多有關新創 / 企業家創業 / 專案管理 / app 開發 / 設計發想有關的消息!

Sign up to discover human stories that deepen your understanding of the world.

Free

Distraction-free reading. No ads.

Organize your knowledge with lists and highlights.

Tell your story. Find your audience.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

--

--

Published in Oursky Team

We Develop for Developers. We open source best practices for product development for web and mobile. Visit us at oursky.com

Written by David Ng

Software Engineer | Previously Growth @ SCMP | davidng.hk | Love hiking and camping.

Responses (4)

Write a response