什麼是Deno,它與Node.js有什麼不同?

作者:Maciej Cieslar

翻譯:瘋狂的技術宅

原文:https://blog.logrocket.com/wh...

未經允許嚴禁轉載

Node.js 的創建者 Ryan Dahl 花了一年半的時間研究 Deno,這是一個新的 JavaScript 運行時環境,可以解決Node 的所有問題。

不要誤解我的意思,Node 本身就是一個很棒的服務器端 JavaScript 運行時環境,主要是因爲它擁有龐大的生態和 JavaScript。然而,Dahl 承認他應該考慮更多的東西:安全性、模塊和依賴性等。

並不是說 Dahl 認爲這個平臺在短時間內會增長多少。不過早在 2009 年,JavaScript 仍然是這種奇怪的小衆語言,每個人都在取笑它,而且還確實許多功能。

什麼是Deno,它的主要特點是什麼?

Deno 是一個基於 V8 構建的安全的 Typescript 運行時,V8 是 Google 的 JavaScript 運行時引擎。

它由以下技術構建:

  • Rust(Deno的核心是用Rust編寫的,Node用C ++編寫)
  • Tokio(用Rust編寫的事件循環)
  • TypeScript(Deno 支持 JavaScript 和開箱即用的 TypeScript)
  • V8(google 在 Chrome 和 Node 等中使用的 JavaScript 運行時)

那麼讓我們來看看 Deno 提供的功能。

安全性(權限)

Deno 最重要的功能之一就是注重安全性。

與 Node 相反,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 命名空間而不是 fs 模塊,就像在 Node 中一樣。 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

會發現沒有提示,兩個文件都已被創建。

除了文件系統的 --allow-write 標誌外,還有 --allow-net--allow-env--allow-run標誌用來啓用網絡請求、訪問環境、以及運行子進程。

模塊

Deno 就像瀏覽器一樣,通過URL加載模塊。很多人起初在看到服務器端帶有 URL 的 import 語句時感到困惑,但它確實有意義 —— 只要你能忍受:

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

您可能會問,通過 URL 導入包有什麼大不了的?答案很簡單:通過 URL,Deno 軟件包可以在沒有集中註冊的情況下進行分發,例如 npm,還有很多問題的解釋可以在這裏找到。

通過URL導入代碼,我們使包的創建者能夠在他們認爲合適的地方託管自己的代碼。 不需要 morepackage.json 和 node_modules。

當啓動應用程序時,Deno 會下載所有導入的模塊並對其進行緩存。一旦它們被緩存,Deno 將不會再次進行下載,直到通過 --reload 標誌特別要求。

這裏有幾個重要的問題:

如果網站出現故障怎麼辦?

由於它不是集中式的註冊,託管該模塊的網站可能會因多種原因而被刪除。這取決於它在開發期間的狀態——或者更糟糕的是,在生產過程中是有風險的。

正如前面提到過的,Deno 緩存了下載的模塊。由於緩存存儲在本地磁盤上,Deno 的創建者建議在版本控制系統(即git)中檢查它並將其保存在存儲庫中。這樣,即使網站出現故障,所有開發人員都可以訪問下載的版本。

Deno 將緩存存儲在 $DENO_DIR 環境變量下指定的目錄中。如果不自己設置變量,它將被設置爲系統的默認緩存目錄。可以在本地存儲庫中的某處設置 $DENO_DIR 並將其簽入版本控制系統。

我是否必須一直通過URL導入?

不斷輸入網址將非常繁瑣。值得慶幸的是,Deno 爲我們提供了兩種選擇避免這樣做。

第一個選項是從本地文件重新導被出導入的模塊,如下所示:

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

假設上面的文件名爲 local-test-utils.ts。現在,如果想再次使用 testassertEquals 函數,可以像這樣引用它:

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

因此,是否從 URL 加載它並不重要。

第二個選項是創建一個導入映射,可以先在 JSON文 件中指定:

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

然後導入它:

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

爲了使它工作,必須通過包含 --importmap 標誌告訴 Deno 導入映射:

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

那麼包版本控制呢?

包提供程序必須支持版本控制,但從客戶端來看,只需在 URL 中設置版本號即可,如下所示:https://unpkg.com/[email protected]/dist/liltest.js

瀏覽器兼容性

Deno 旨在與瀏覽器兼容。從技術上講在使用ES模塊時,可以不必藉助任何構建工具(如 webpack)來使我們的程序可以在瀏覽器中使用。

但是,像 Babel 這樣的工具會將代碼轉換爲 ES5 版本的 JavaScript,因此,即使在不支持該語言所有最新功能的舊版瀏覽器中,代碼也可以運行。但這也是以在最終文件中包含大量不必要的代碼並使輸出文件膨脹爲代價的。

由自己決定我們的主要目標是什麼,並相應地做出選擇。

TypeScript支持開箱即用

Deno 可以無需任何配置文件就能夠輕鬆使用 TypeScript。同時可以用純 JavaScript 編寫程序並執行它們而不會有任何麻煩。

總結

Deno 是 TypeScript 和 JavaScript 新的運行時,是一個有趣的項目,現在已經穩定發展了很長一段時間。但是在被認爲能夠穩定用於生產環境之前還有很長的路要走。

藉助它的分佈式方法,它需要從集中式軟件包註冊表(即npm)中釋放 JavaScript 生態系統。

Dahl 說他希望在夏天結束前發佈 1.0 版本,所以如果你對 Deno 的未來發展感興趣,可以訪問它的 GitHub


本文首發微信公衆號:前端先鋒

歡迎掃描二維碼關注公衆號,每天都給你推送新鮮的前端技術文章

歡迎掃描二維碼關注公衆號,每天都給你推送新鮮的前端技術文章

歡迎繼續閱讀本專欄其它高贊文章:


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章