Deno 跟 Node.js 的主要差異

什麼是 Deno ?

Deno 是一個全新的 JavaScript, TypeScript 執行環境,改善了許多 Node.js 為人詬病的缺點。此外, Deno 內建了許多實用的功能,非常建議大家學習。

貼心提醒:如果你在閱讀這篇文章之前不曾寫過JS、TS,你可能會有很大的疑惑。

因此,筆者建議你可以在閱讀完之後TypeScript基礎語法的全部篇章後再回來閱讀本文。

進入正題

筆者第一次聽到 Deno 是在 YouTube 上看到 JSConf 的議程 -- 10 Things I Regret About Node.js

當中提到了很多 Node.Js 的缺陷,其中像是:

  • 沒有在 API 中支持 JavaScript 的 Promise

    在2009/6時, Node.Js 是支援 Promise 的,不過開發團隊在2020/2將它移除了。

    雖然在之後開發團隊還是將 Promise 加了回來,但也因為這樣,許多 Node.Js 的原生 API 都是使用 CallBack Function 而不是 Promise 去進行實作。

    毫無疑問的, Deno 原生支持 Promise 。

  • 安全問題

    V8 引擎本身是很安全的 SandBox ,不過 Node.Js 在應用層面上並沒有承襲這樣良好的傳統。

    使用 V8 引擎 實作的 Node.js 卻能夠在沒有授權的情況下,直接訪問網路、檔案系統,甚至是取得記憶體的相關資訊。

    筆者認為這邊是十分重要的關鍵,這個缺陷也影響到了我們之後使用 Deno 的方式。

  • 建構系統

    使用 GYP 作為建構項目的系統而不是使用 GN (Generate Ninja)。

    這個部分作者認為是 Node.Js 的最大疏失,我們先看看在 WiK i上是如何介紹 Ninja 的:

    Evan Martin 從2007年到2012年在 Chrome 團隊工作。在加入初期, Chrome 只能夠在 Windows 上執行,他的主要任務是把代碼移植到其它平台,而面臨的第一個任務就是確定構建系統。

    Chrome 團隊的成員提出了 GYP 增量解決方案,它的作用是從進階的描述規則生成平台相關的構建檔案。

    在 Linux 上,他最開始嘗試把 Scons 作為 GYP 的目標構建系統,但當檔案發生變化,啟動構建就需要花費30秒時間。因為他的工作是移植代碼,涉及到頻繁的更改檔案和重新編譯,所以這被認為是不可接受的。

    後來,他又嘗試 make 作為 GYP 的目標構建系統。在剛開始的時候速度相當快,但當檔案越來越多時,它變慢了。後來,他注意到make中的一些問題,覺得可以最佳化,因此有了開發Ninja的想法。

    在使用 Ninja 後,修改檔案後 Chrome 增量構建的時間降到了6秒鐘。

    使用「Ninja」命名是因為作者覺得它速度很快。

    -- wikipedia

    使用 C++ 所編寫 Ninja 比起由 Python 編寫的 GYP 效能差了將近20倍,你可能會有疑問說:對啊!那為什麼 Node.Js 在初步建構時是採用 GYP 呢?

    由於 Chrome V8 最初也是由 GYP 所建構,不過我們可以從 wikipedia 所引用的資料得知, Chrome V8 後來改採 Ninja 建構系統,只可惜當時 Node.Js 的生態鏈已經形成並且很難做修正了,因此我們才會看到現在這樣的結果。

  • NPM, Package.json, node_modules 的設計缺陷

    • NPM 過度極權,只要 NPM 在安全性上產生漏洞,全球用戶也跟著遭殃。

    • Package.json 成為 Node.Js 專案的必需品,裡面常常放了很多多餘的資訊。

    • 因為採用 CommonJS 標準,在引入其他 Module 時我們會自動忽略副檔名,導致系統需要浪費效能來做判斷。

    • node_modules 沒有標準的規範,導致不同套件都有不同的結構。

    因為這些小小的瑕疵,也造就了 Deno 與 Node.Js 最大的不同:

    Deno 沒有額外的套件管理系統,並且預設的模組系統是採用 ES Module 而不是 CommonJS

看完這個議程紀錄片以後,不知為何我想到大家常常說的一句話:

每場分手都是經過精心策劃的。

分手是不需要理由的。

不過 Deno 的出生並不是沒有理由的, Node.Js 的確有著許多設計上的小瑕疵。

Node.Js 的生態圈中也很努力的想要把這些問題給解決掉 (遠望 PHP)

總結

本章的最後,筆者來幫大家做個總整理:

  • Deno 所使用的模組系統為 ES Module

    在這邊幫 Node.Js 澄清一下:

    Node.Js 並不是完全遵守 CommonJS 的規範,它是參考了 CommonJS 的規範,請知悉。

    Node.Js 也逐漸加強了對於 ES Module 的支援,請參考 Node.js v14.5.0 Documentation

  • 我們在 Deno 上執行 JS or TS 程式碼時,若有需要用到網路、檔案讀取,都需要在 CLI 中下額外指令以確保安全性。

  • Deno 並沒有額外的套件管理系統,若需要導入其他模組,只需要將該模組的 Url 引入就好。

  • 原生支持 Promise 並且能夠直接使用 TypeScript 進行撰寫,無需額外編譯。

對於初學者而言,上面琳瑯滿目的專業名詞可能會讓你感到緊張。

不過這些名詞在之後的 TypeScript 基礎篇中筆者都會額外進行補充,大家不用擔心。

Last updated