什麼是Deno?與Node.js的區別是什麼?

2021-06-24 13:00:43
Deno是為解決Node的一些內在問題而建立的,那麼與的區別是什麼?下面本篇文章帶大家詳細瞭解一下Deno,介紹一下Deno和Node.js的區別。

【推薦學習:《》】

Node.js的作者Ryan Dahl,過去一年半的時間都在打造一個新的JavaScript執行環境Deno來解決Node的一些內在問題。

不過不要誤會,得益於JavaScript龐大的社群生態和使用範圍,Node是一個非常不錯的JavaScript執行環境。然而,Dahl 也承認在Node的某些方面他應該考慮得更全面一些,比如:安全性,模組機制,依賴管理等。

在他的計劃中,他並不會去預想Deno在短時間內能夠發展成一個多大規模的平臺。當然咯,把時間調回2009年,JavaScript還是人人都能取笑的一個有些怪異的小語言,也木有現在這麼多語言特性。

什麼是Deno,以及它的主要特性是哪些?

Deno是基於Google V8引擎構建的安全的TypeScript執行環境。 下面是構建Deno的一些物料:

  • Rust(Deno的核心模組使用Rust編寫,Node的核心模組是用C++實現的)
  • Tokio(Rust實現的非同步程式設計框架)
  • TypeScript(Deno對JavaScript和TypeScript都支援開箱即用)
  • V8(Google出品JavaScript執行時,主要用在Chrome和Node中)

接下來看看Deno提供了哪些特性。

安全性(許可權管理)

Deno最重要的特性就是安全性。

相較於Node,Deno預設使用沙箱環境執行程式碼,這意味著執行環境沒有操作以下模組許可權:

  • 檔案系統
  • 網路
  • 執行其他的指令碼
  • 系統環境變數

讓我們瞅一眼Deno的許可權系統是如何工作滴。

(async () => {
 const encoder = new TextEncoder();
 const data = encoder.encode('Hello world\n');

 await Deno.writeFile('hello.txt', data);
 await Deno.writeFile('hello2.txt', data);
})();

這個指令碼分別建立了兩個名為hello.txthello2.txt的檔案,並在其中寫入Hello world。但是這段程式碼執行在沙箱環境中,所以是沒有檔案系統的操作許可權滴。

還有一點值得注意,在上面的指令碼中我們使用Deno名稱空間來操作檔案,而不像在Node中使用fs模組。Deno名稱空間提供了超多基礎方法。不過使用Deno名稱空間會導致我們的程式碼失去了對瀏覽器的相容性,這個問題我們晚點再聊。

使用下面的命令執行上述指令碼:

$ deno run write-hello.ts

執行之後,我們會收到下面的提示:

Deno requests write access to "/Users/user/folder/hello.txt". Grant? [a/y/n/d (a = allow always, y = allow once, n = deny once, d = deny always)]

實際上,基於上面建立檔案的指令碼我們會收到兩次來自沙箱環境的許可權提示。不過如果我們選擇allow always選項,就只會被詢問一次啦。

如果我們選了deny,會丟擲一個PermissionDenied的錯誤,如果我們沒寫錯誤處理邏輯的話,程序在此時就被終止啦。

如果我們用下面的命令來執行指令碼:

deno run --allow-write write-hello.ts

會在沒有提示的情況下建立這兩個檔案。

Deno針對檔案系統的命令列標誌位,除了--allow-write,還有--allow-net/--allow-env/--allow-run,分別用來開啟針對網路、系統環境變數和操作子程序的許可權。

模組機制

Deno使用瀏覽器一樣的方式,通過URL來載入模組。很多人第一次見到在伺服器端的import語句中見到URL會感到有點困惑,但對我來說這還蠻好理解的:

import { assertEquals } from "https://deno.land/std/testing/asserts.ts";

你覺得通過URL來引入模組會有啥大不了的嗎?答案其實蠻簡單的:通過使用URL來載入模組,Deno就可以避免引入一個類似npm的中心化系統來發布package,npm最近受到了很多吐槽

通過URL來引入程式碼,可以讓包的作者們使用自己最喜愛的方式來維護和釋出自己的程式碼。再也不會有package.jsonnode_modules了。

當我們啟動應用之後,Deno會下載所有被參照的檔案,並將它們快取到本地。一旦參照被快取下來,Deno就不會再去下載它們了,除非我們使用-- relaod標誌位去觸發重新下載。

還有幾個問題值得我們討論一哈:

萬一存放參照的站點掛了咋辦?

由於沒有了一箇中心化的包管理站點,那些存放模組的站點可能因為各種各樣的原因掛掉。如果在開發甚至生產環境出現這種情況是非常危險滴!

我們在上一節提到,Deno會快取好已下載的模組。由於快取是存放在我們的本地磁碟的,Deno的作者建議將這些快取提交到程式碼倉庫裡。這樣一來,即使存放參照的站點掛了,開發者們還是可以使用已經下載好的模組(只不過版本是被鎖住的啦)。

Deno會把快取儲存在環境變數$DENO_DIR所指定的目錄下,如果我們不去設定這個變數,它會指向系統預設的快取目錄。我們可以把$DENO_DIR指定我們的本地倉庫,然後把它們提交到版本管理系統中(比如:git

只能使用URL來參照模組嗎?

總是敲URL顯得有點XX,還好,Deno提供了兩種方案來避免我們成為XX。

第一種,你可以在本地檔案中將已經參照的模組重新export出來,比如:

export { test, assertEquals } from "https://deno.land/std/testing/mod.ts";

假如上面這個檔案叫local-test-utils.ts。現在,如果我們想再次使用test或者assertEquals方法,只需要像下面這樣參照它們:

import { test, assertEquals } from './local-test-utils.ts';

看得出來,是不是通過URL來參照它們並不是最重要的啦。

第二種方案,建一個參照對映表,比如像下面這樣一個JSON檔案:

{
   "imports": {
      "http/": "https://deno.land/std/http/"
   }
}

然後把它像這樣import到程式碼裡:

import { serve } from "http/server.ts";

為了讓它生效,我們還需要通過--importmap標誌位讓Deno來引入import對映表:

$ deno run --importmap=import_map.json hello_server.ts

如何進行版本管理

版本管理必須由包作者來支援,這樣在client端可以通過在URL中設定版本號來下載:https://unpkg.com/[email protected]/dist/liltest.js

瀏覽器相容性

Deno有計劃做到相容瀏覽器。從技術上講,在使用ES module的前提下,我們不需要使用任何類似webpack的打包工具就能在瀏覽器上執行Deno程式碼。

不過呢,你可以使用類似Babel這樣的工具可以把程式碼轉化成ES5版本的JavaScript,這樣可以相容那些不支援所有最新語言特性的低版本瀏覽器中,帶來的後果就是最終檔案裡有很多不是必須的冗餘程式碼,增大程式碼的體積。

結果取決於我們的主要目的是啥。

支援TypeScript開箱即用

不需要任何組態檔就能在Deno中輕易地使用TypeScript。當然咯,你也可以編寫純JavaScript程式碼,並使用Deno去執行它。

總結

Deno,作為一個新的TypeScript和JavaScript的執行環境,是一個非常有趣的技術專案,並且至今已經穩定發展了一段時間。但是距離在生產環境中去使用它還有比較長的一段路要走。

通過去中心化(或者翻譯成分散式?)的機制,把JavaScript生態系統從npm這樣中心化的包管理系統中解放了出來。

Dahl希望在這個夏天快結束的時候能夠釋出1.0版本,所以如果你對Deno未來的新進展感興趣的話,可以給它個star

最後還有一個紀錄檔系統的廣告,大家可以去原文檢視。

更多程式設計相關知識,請存取:!!

以上就是什麼是Deno?與Node.js的區別是什麼?的詳細內容,更多請關注TW511.COM其它相關文章!