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

做者:Maciej Cieslarjavascript

翻譯:瘋狂的技術宅前端

原文:blog.logrocket.com/what-is-den…java

未經容許嚴禁轉載node

What Is Deno?

Node.js 的建立者 Ryan Dahl 花了一年半的時間研究 Deno,這是一個新的 JavaScript 運行時環境,能夠解決Node 的全部問題。webpack

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

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

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

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

它由如下技術構建:npm

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

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

安全性(權限)

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/liltest@0.0.5/dist/liltest.js

瀏覽器兼容性

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

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

由本身決定咱們的主要目標是什麼,並相應地作出選擇。

TypeScript支持開箱即用

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

總結

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

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

Dahl 說他但願在夏天結束前發佈 1.0 版本,因此若是你對 Deno 的將來發展感興趣,能夠訪問它的 GitHub

歡迎關注前端公衆號:前端先鋒,領取前端工程化實用工具包。

相關文章
相關標籤/搜索