如果 Node 是今天寫的,它會是什麼樣子?一言以蔽之: Deno 。 JS 執行時內建了 Typescript 並簡化了模組解析。最重要的是,它將安全性提升到了一個新的水平,並縮小了我們在後端編寫 javascript 的方式與瀏覽器之間的差距。
2009 年發布的 node 以令人難以置信的速度席捲了世界。儘管最初對在後端執行 javascript 持懷疑態度,但社區的支持是無與倫比的。很快,複雜的工具出現了,幾年後(2014 年),微軟發布了 Typescript,對 Javascript 進行了雙重押注。
如今,Node 是後端開發最受歡迎的選擇之一。基於事件的伺服器理念確保了高效能/吞吐量比。執行 Javascript 對許多開發人員來說是一種易於使用的工具。在某種程度上,可以說,Node 透過降低進入門檻實現了後端開發的民主化。在過去的五年裡,我一直很高興地使用 Node,但同時,我想知道未來在等待著什麼?
如網站所述,Deno 專案於 2018 年啟動,為 Javascript 和 Typescript 提供安全的執行時間。它基本上由兩部分組成: TypeScript 前端和 Rust 後端。兩者之間的通訊是透過使用TypedArrays
進行訊息傳遞來進行。
Deno 是 JavaScript/TypeScript 執行時,具有安全的預設設定和出色的開發人員體驗。 — Deno 網站
在底層,我們找到了 Typescript 編譯器、V8 引擎和 Tokio 事件循環的快照版本。總而言之,以小於 10 MB 的二進位檔案或 Rust 箱子的形式提供。
早在 2010 年就取消了 Node 的承諾,這在早期階段對社群有所幫助。但隨著 JavaScript 開始變得越來越快並引入了等待和非同步功能,Node 的 API 開始老化。
今天我們付出了巨大的努力來讓他們加快速度,同時保持一致的版本控制。許多 API 呼叫仍必須包裝在建構函式(如promisify
中才能與Promise
語法一起使用。這個額外的步驟增加了開發的開銷並增加了應用程式中的樣板檔案。
相比之下,Promise 是 Deno 異步行為的本機綁定。 Rust 後端透過 Rust Futures 鏡像從 Typescript 前端接收的 Promise 物件。 Deno 中的非同步操作總是會傳回Promise
。
Node 的另一個值得注意的是它依賴Buffer
物件來讀寫資料。為了實現瀏覽器介面的統一,Deno 在各處都使用了TypedArrays
。使用相同的資料結構時,在後端和前端讀寫檔案時保持一致會容易得多。
如果你使用 Typescript,你就會知道它是一個出色的工具。它引入了一個可以隨著應用程式的成長而強制執行的類型系統。這透過提供靈活性減少了傳統靜態類型的開銷。專案可以在請求中進行部分類型化,並且類型覆蓋範圍可以隨著應用程式的成長而擴展。
在 Node 中,Typescript 可以直接與ts-node
一起使用,儘管在生產中必須小心。最安全、效能最好的選擇是使用ts-node
進行開發。然後編譯為 javascript 以進行生產。開發的設定可能很複雜,尤其是與熱程式碼重新載入等其他功能一起使用時。
另一方面,Deno 完全是關於 Typescript 的。它使用編譯器的快照版本並捕獲未更改的檔案。你想執行 Typescript 程式碼嗎?只需執行 Deno 二進位檔案即可。沒有配置。沒有喧囂。是不是很簡單,當然它也支援javascript。
Node 目前的解析方案使模組解析過於複雜。該演算法在文件位置和命名方面提供了靈活性,但在複雜性方面做出了相當大的權衡。
require
呼叫將先搜尋具有相同名稱和.js
、 .json
或.node
副檔名的檔案。如果指定的路徑不包含前導'/'
、 './'
或'../'
node ,則假定該模組是核心模組或node_modules
資料夾中的依賴項。如果名稱不匹配,核心模組 node 將檢查該位置的node_modules。如果沒有找到任何內容,它將到達父目錄並繼續這樣做,直到到達檔案系統的根目錄。
此外,資料夾可以在package.json
檔案中指定為模組。 require
函數也知道開始檢查的所有資料夾的package.json
檔案。一旦找到資料夾,Node 將在其中查找index.js
或index.node
檔案。不必提供檔案副檔名的自由和package.json
的靈活性會顯著增加複雜性並降低效能。
Deno 透過提供兩種類型的模組解析(相對解析和基於 URL 解析)來簡化演算法:
import * from "https://deno.land/std/testing/asserts.ts";
另外,解析演算法不使用package.json
檔案或node_modules
資料夾。它使用 ES 模組導入而不是require
。這使我們能夠使用現代方法進行程式碼管理,而無需預編譯器,並使我們再次更接近 Javascript 在瀏覽器中的使用方式。
目前,無伺服器的採用率每年翻倍。開發人員通常將單體應用程式拆分為微服務。現在我們將微服務拆分為功能。為什麼?嗯,一方面,沒有人願意處理編排,除非我們也有。另一方面,分散式系統更加靈活,可以更快地改變。最重要的是,應用程式正在成為由更小且獨立的部分組成的系統。
典型的 JavaScript 後端應用程式僅使用 0.3% 的程式碼。其餘部分由node_modules
資料夾中的套件組成。而且許多在執行時幾乎不被使用。同時,整個生態系統依賴一個集中的套件管理器: npm
。
Deno帶來了一種分散式套件管理方法。套件可以透過 URL 解析並隨後捕獲。應用程式更輕,更少依賴單一的集中式套件註冊表。
在進行後端開發時,我希望安全性能夠在盒子之外發揮作用。我最不想考慮的是存取網路或檔案系統的 linter 檔案或 node 模組。
在 Deno 中,內部函數不能像在 Node 中那樣任意呼叫 V8 API。 Deno 的 API 和 JS 引擎之間的通訊是集中且統一的,基於類型化陣列的訊息傳遞。
除非特別允許,否則腳本無法存取檔案、環境或網路。 — 德諾.蘭
只有當使用者明確指定時,使用 Deno 執行的腳本才能存取檔案系統和網路。更好的是,可以使用 —allow 標誌在檔案、資料夾層級或網路路徑層級授予權限。這為開發人員提供了對執行時發生的讀寫操作的精細控制。
$ deno --allow-net https://deno.land/std/examples/echo_server.ts
與應用於從npn
提取的依賴項的「信任」策略相比,預設的安全性是一項重大升級。借助 Deno,您可以執行和開發應用程式,並確信它們會執行預期的操作。
如果 Node 在今天建置, Deno就是它的樣子。它提高了安全性、簡化了模組解析並執行 Typescript。
當我寫這篇文章時,我們仍處於 0.33 版本並且正在快速發展。我確信您來到這裡是因為您在某種程度上使用了 Node 或 Javascript。如果你像我一樣,你可能會喜歡它。但正如他們所說,愛某樣東西真正意味著放手。
我期待看到 Deno 超越單純的腳本執行時,並聽到生產中的第一次經驗。只要開發人員繼續顛覆自己,我們總是能期待更快、更簡單、更可靠的軟體。
最初發佈於bogdanned.com 。
原文出處:https://dev.to/bogdanned/on-deno-and-the-future-of-node-1l0p