Deno vs Node.js:哪個更勝一籌?
譯文?譯者 | 布加迪
審校 | 孫淑娟
您在本文中將了解Node.js和Deno、CommonJS與ECMAScript模塊之間的區別、將TypeScript與Deno結合使用,以及使用Deno Deploy進行更快的部署。末尾附有注釋,幫助您決定下一個開發項目使用Node.js還是Deno。
Node.js簡介
Node.js是跨平臺的JavaScript運行時環境,對服務器應用程序和桌面應用程序都很有用。它運行向系統注冊的單線程事件循環來處理連接,每個新連接都會觸發JavaScript回調函數?;卣{函數可以使用非阻塞I/O調用處理請求。若有必要,它可以從池中生成線程,以執行阻塞型或CPU密集型操作,并在CPU核心之間平衡負載。
大多數競爭性架構使用線程進行擴展,包括Apache HTTP Server、各種Java應用服務器、IIS和ASP.NET以及Ruby on Rails。相比之下,Node使用回調函數進行擴展,這種方法只需較少的內存就能處理更多的連接。
Node應用程序并不僅限于純粹的JavaScript。您可以使用任何轉譯成JavaScript的語言,比如TypeScript和CoffeeScript。Node.js包含Google Chrome V8 JavaScript引擎,該引擎支持ECMAScript 2015 (ES6) 語法,根本不需要Babel之類的ES6-to-ES5轉譯器。
Node的用途主要來自其龐大的軟件包庫,該庫可通過npm命令來訪問。NPM的全稱是Node軟件包管理器,是標準Node.js安裝系統的一部分,不過它有自己的網站。
基于JavaScript的Node.js平臺由Ryan Dahl于2009年推出。當初開發這個更具可擴展性的平臺是為了替代面向Linux和MacOS的Apache HTTP Server。NPM由Isaac Schlueter編寫,于2010年推出。Node.js的原生Windows版本于2011年首次亮相。
Deno簡介
Deno是面向JavaScript和TypeScript的安全運行時環境,已針對WebAssembly、JavaScript XML(JSX)及其TypeScript擴展TSX進行了擴展。Deno由Node.js的創建者開發,試圖重新構思Node,充分利用自2009年以來JavaScript方面的進步,包括TypeScript編譯器。
與Node.js一樣,Deno本質上是Google V8 JavaScript引擎外面的外殼。與Node不同,它在其可執行映像中包含TypeScript編譯器。創建了這兩個運行時環境的Dahl曾表示,Node.js存在三個主要問題:基于集中式分發的設計欠佳的模塊系統、必須支持的許多遺留API以及缺乏安全性。Deno全部解決了這三個問題。
Node的模塊系統問題通過2022年年中的更新得到了解決。
CommonJS模塊和ECMAScript模塊
Node創建之時,JavaScript模塊的事實標準是CommonJS,這是npm最初支持的。此后,ECMAScript委員會正式支持ECMAScript模塊(又叫ES模塊),它得到jspm軟件包管理器的支持。Deno也支持ES模塊。
對ES模塊的實驗性支持已添加在Node.js 12.12中,從Node.js 16版本成了穩定功能。 TypeScript 4.7也為Node.js 16支持ES模塊。
在JavaScript中加載CommonJS模塊的方法是使用require語句。加載ECMAScript模塊的方法是使用import語句以及匹配的export語句。
最新的Node.js擁有CommonJS和ES模塊的加載器。它們有何不同?CommonJS加載器是完全同步的,負責處理require()調用;支持文件夾作為模塊;如果在require()調用中省略了擴展名(.js、.json或.node),可以嘗試添加擴展名。CommonJS加載器不能用于加載ECMAScript模塊。ES模塊加載器則是異步的,負責處理import語句和import()表達式;不支持文件夾作為模塊(必須完整指定目錄索引,比如./startup/index.js);不搜索擴展名;并且只接受JavaScript文本文件的.js、.mjs和.cjs擴展名。ES模塊可用于加載JavaScript CommonJS模塊。
為什么Deno的安全性更高?
眾所周知,Deno提高了Node.js的安全性。這主要是由于Deno在默認情況下不允許程序訪問磁盤、網絡、子進程或環境變量。如果您需要訪問其中任何一項,可以使用命令行標志選擇加入,這個標志的細粒度有多高就看您喜歡了,比如--allow-read=/tmp或--allow-net=google.com。Deno的另一個安全改進是,它總是一發現未捕獲的錯誤就終結。相比之下,Node允許在未捕獲的錯誤后繼續執行,結果無法預測。
可以結合使用Node.js和Deno嗎?
當您考慮是否將Node.js或Deno用于下一個服務器端JavaScript項目時,可能想知道是否可以結合使用兩者。答案是“也許可以”。
首先,從Deno使用Node軟件包往往是可行的。更棒的是,許多常見的阻礙有解決的方法。這包括使用Deno 標準庫的std/node模塊來“polyfill”Node的內置模塊;使用CDN訪問絕大多數npm軟件包,并確保適用于Deno;使用導入圖(import maps)。此外,從Deno1.15 開始,Deno擁有Node兼容模式。
缺點是,Node 的插件系統與Deno不兼容;Deno的Node兼容模式不支持TypeScript;幾個內置的Node模塊(比如vm)與Deno不兼容。
如果您是考慮換成Deno的Node用戶,這里有一份??速成表??有所幫助。
將TypeScript與Deno一起使用
Deno將TypeScript視為頭等語言,就像JavaScript或WebAssembly一樣。它結合使用Deno中內置的TypeScript編譯器和名為swc的Rust庫,將TypeScript(以及TSX和JSX)轉換成JavaScript。代碼經過類型檢查(如果啟用檢查)并轉換后,存儲在緩存中。換句話說,與Node.js或瀏覽器不同,您不需要使用tsc編譯器手動為Deno轉譯TypeScript。
從Deno 1.23開始,默認情況下Deno中沒有TypeScript類型檢查。由于大多數開發人員通過編輯器與類型檢查器進行交互,因此在Deno啟動時再次進行類型檢查沒多大意義。話雖如此,您可以使用--check標志啟用類型檢查。
Deno Deploy實現更快的部署
Deno Deploy是一個分布式系統,允許您在全球各地靠近用戶的地方(即邊緣)運行JavaScript、TypeScript和WebAssembly。Deno Deploy服務器與V8運行時環境深度集成,提供最小的延遲,消除不必要的抽象。您可以使用Deno CLI在本地開發腳本,然后在不到一秒的時間內將其部署到Deno Deploy的托管基礎??架構,無需進行任何配置。
Deno Deploy建立在與Deno CLI相同的現代系統上,以全球可擴展的方式提供最新、最出色的Web技術:
- 在Web上構建:使用fetch、WebSocket或URL,就像在瀏覽器中一樣。
- 對TypeScript和JSX的內置支持:類型安全的代碼和直觀的服務器端渲染,無需構建這一步。
- 與Web兼容的ECMAScript模塊:像在瀏覽器中一樣導入依賴項,無需顯式安裝。
- GitHub 集成:推送到分支,查看已部署的預覽,并合并以發布到生產環境。
- 速度極快:不到一秒即可部署;服務全球,靠近用戶。
?從URL來部署:僅使用URL即可部署代碼。
Deno Deploy有兩種版本。免費版僅限于每天100000個請求、每月100 GiB數據傳輸量以及每個請求10毫秒的CPU時間。專業版每月收費10美元,包括每月500萬次請求和100 GiB數據傳輸量,加上每月每多出1百萬次請求就收費2美元,以及超過配額后每傳輸1 GiB 數據就收費0.30美元;專業版允許每個請求50毫秒的CPU時間。
選擇哪一個:Node.js還是Deno?
如您所料,至于哪種技術更適合您的用例,答案取決于許多因素。我的結論是,如果您現有的Node.js部署沒壞掉,別修復它。如果您打算用TypeScript編寫一個新項目,我強烈建議考慮Deno。然而,如果您的TypeScript項目需要使用多個沒有Deno同等軟件包的 Node.js軟件包,需要權衡Deno項目的可行性。從概念驗證入手幾乎必不可少:如果不嘗試一下,很難預測您是否可以讓某個Node.js軟件包在Deno中工作。
原文標題:??Deno vs. Node.js: Which is better????,作者:Martin Heller?
?