Deno 是什麼?他和 nodejs 有什麼不一樣之處?

Ryan Dahl 創造 nodejs 的大牛,去年花了一年半的時間在新的項目Deno上。Deno 是什麼呢?一個被認爲是修復完善 nodejs 內在問題的新的 JavaScript 運行時的工具。javascript

不要理解錯了,在我本身看來 node 是一個很好的服務端 JavaScript 運行時工具,同時也由於它的生態系統的龐大和使用的語言是 JavaScript。然鵝,Dahl 也認可有一些東西在 node 裏面是支持不多的——安全性、模塊化、依賴性等等。java

在他的辯護中,他並無想到這個平臺會在如此短的時間裏增加這麼快。此外,早在 2009 年,JavaScript 仍然是一種奇怪的小語言,每一個人都看不起,並且它的許多功能尚未。node

什麼是 Deno?它有什麼主要的特性

Deno 是一個基於 V8 引擎的安全的 Typescript 運行時工具(V8 是谷歌的 JavaScript 運行時引擎)。
它是由如下組成:webpack

  • Rust——Deno 的核心是用 Rust 寫的,就如同 nodejs 是用 c++寫的同樣。
  • Tokio——Rust 編程語言的異步運行時,提供異步事件驅動平臺,構建快速,可靠和輕量級網絡應用。利用 Rust 的全部權和併發模型確保線程安全(用 Rust 寫的事件循環)
  • Typescript——Deno 支持 JavaScript 和 Typescript(開箱即用)
  • V8——谷歌的 JavaScript 運行時引擎,被用在 Chrome 和 node 中

那咱們來看一下 Deno 提供了那些特性。c++

安全性(權限控制)

Deno 最重要的特性是聚焦在安全性上。
與 nodejs 相反,Deno 默認在沙箱中執行代碼,它意味着運行時不能去作一些事情:git

  • 文件系統的訪問
  • 網絡的訪問
  • 執行其餘文件
  • 訪問環境變量

一塊兒看一下權限控制系統怎麼工做的。web

(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.txt 和 hello2.txt,裏面的內容都是Hello word文本。當這個代碼在沙箱中開始執行的時候,它是沒有權限訪問文件系統的。typescript

這個也要注意。咱們使用的是 Deno 命名空間,而不是 fs 模塊,也正如咱們在 nodejs 中,Deno 的命名空間提供了許多基礎輔助函數。經過使用命名空間,也會失去瀏覽器兼容性,這個咱們後面討論。npm

當咱們執行如下命令時:編程

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 { assertEquals } from "https://deno.land/std/testing/asserts.ts";
複製代碼

經過 URL 引入報有什麼好處,你可能會這麼說。這個答案是簡單的:經過 URL,Deno 的包能夠不是集中的彙集在一箇中心倉庫,好比npm。不久前就發生了一些事情,這裏就不詳細闡述了。

經過 URL 引入代碼,咱們可讓包的建立者把代碼託管到他們本身想託管的地方——去中心化。 沒有多餘的 package.json 和 node_modules。

當咱們開始運行一個 Deno 的程序時,他會下載全部的依賴包,而且緩存他們,一旦它們緩存到了本地,Deno 就不會再下載他們了,除非你在運行的時候加上--reload符號標識。

這兒有一些比較重要的問題:

若是存在包的網站蹦了呢?

因爲它再也不是中心倉庫來管理,存包的網站可能由於一些緣由崩了。對於正在開發的項目,這是一個很糟糕的狀況,對於已經上線的項目,這更是毀滅性的打擊。

正如咱們前面提到的,Deno 會緩存模塊包,因爲緩存是存在咱們的本地的硬盤上的,Deno 的建立者建議在咱們的版本控制系統(即 git)中檢查它並將其保存在存儲庫中。這樣,即便網站崩了,開發者仍然保留了下載的版本。

Deno 將緩存存儲在$DENO_DIR環境變量下指定的目錄中。若是咱們不本身設置變量,它將被設置爲系統的默認緩存目錄。咱們能夠在咱們的本地存儲庫中的某處設置$DENO_DIR並將其檢入版本控制系統。

每次我都必須經過 URL 來引入嘛?

老是經過 URL 來引入文件,可能會變得特別複雜或者說麻煩,比較好的是,Deno 目前有兩個選項提供給咱們。
第一個選項是從本地文件從新導出導入的模塊,像這樣:

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 { 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 執行它們而不會有任何麻煩。

摘要

Deno 是 TypeScript 和 JavaScript 的新運行時,是一個有趣的項目,如今已經穩定增加了很長一段時間。可是在它被認爲是生產就緒以前還有很長的路要走。

因爲它的去中心化特色,它須要從集中式軟件包註冊表(即 npm)中釋放 JavaScript 生態系統。

Dahl 表示他但願在夏季結束前發佈 1.0 版本,因此若是你對 Deno 的將來發展感興趣,那麼就 star 它吧。

相關文章
相關標籤/搜索