Deno 初探

champyin發表於2020-06-14

前言

Deno 已經被前端圈子提及有很長一段時間了,上個月 Deno 釋出了 1.0 版本,又掀起了一小股 Deno 熱。Deno 到底是什麼?它可以用來做什麼呢?它好用嗎?帶著一直以來的好奇心,趁著週末的時間,認真地接觸了一次 Deno。

一、什麼是Deno?

Deno 是一個更安全的 JavaScript 和 TypeScript 執行時,作者 Ryan Dahl 同時也是 Node.js 的建立者。

什麼是執行時?

執行時是一個執行環境,也叫執行平臺,開發者可以使用指定的語言,基於這個環境開發應用。可以認為執行時就是一個舞臺,能做什麼事情,取決於舞臺能提供什麼道具。比如瀏覽器就是一個執行時,我們可以在瀏覽器上通過 JS 呼叫瀏覽器提供的 API 操作 DOM。

Deno 的作用

Deno 的作用,是讓開發者可以使用 JavaScript 語言開發後端服務。

二、為什麼會有Deno?

我們知道 Node.js 也是一個讓開發者可以使用 JavaScript 語言開發後端服務的 JavaScript 執行時。那既然已經有一個 Node.js,而且已經非常成功,為什麼還要造另一個 JavaScript 執行時 Deno ?

兩年前(2018年6月),Ryan Dahl 在德國柏林召開的 JSConf EU 會議上發表了名為 “10 Things I Regret About Node.js” 的演講,有興趣可以到這裡下載 PPT

Ryan Dahl

在分享中,Ryan 回顧了在他看來當初開發 Node.js 時留下的10大遺憾。但由於Node.js 現在已經廣泛應用於各個領域,為了保證相容性,對 Node.js 底層進行大規模改造已經不現實。會上,Ryan 宣佈了他決定開發一個全新的 JavaScript Runtime 以解決當初的種種缺陷,這個專案就是 Deno。

Deno logo

Deno 的命名很有意思,就是把 node(no de) 倒過來 deno(de no),頗有顛覆 Node 的意味。

BTW,上個月(2020年5月15日),Deno 釋出了1.0版本。

三、走近 Deno

Deno 的開發語言

相比 Node.js 使用 C++ 開發,Deno 起初使用的開發語言是 GoLang,後來改為了 Rust。並且隨後把 C++ 寫的 libdeno 換成了 Rust 編寫的 V8 繫結:denoland/rusty_8。

Deno 目前是建立在 V8 引擎、Rust 、Tokio、TypeScript 的基礎之上。

  • V8 是 chrome 瀏覽器內的 JavaScript 執行時。
  • Rust 是一門系統程式語言,專注於安全,尤其是併發安全。它的效能和標準C++ 不相上下。
  • Tokio 是一個給 Rust 語言使用的非同步執行時,提供 event loop 和具體的 I/O 型別。
  • TypeScript 是 JavaScript 的超集。

Deno 的特性

  • 預設支援 ES Modules
  • 預設支援 TypeScript
  • 儘可能相容 Web 標準 APIs
  • 預設採用沙箱模式執行程式碼,更安全
  • 去中心化第三方模組機制
  • 提供標準庫

與 Node.js 的比較

  • 使用 ES 模組,不支援 require()
  • Deno 不使用 package.json
  • Deno 不使用 npm
  • Deno 中的所有非同步操作返回 promise,因此 Deno 提供與 Node 不同的 API
  • Deno 需要顯示指定檔案、網路和環境許可權
  • 第三方模組通過 URL 或者檔案路徑匯入
  • 當未捕獲的錯誤發生時,Deno 總是會異常退出
  • 相容 Web 的執行時 APIs,更利於前後端的程式碼同構。

四、如何使用 Deno

Deno 能夠在 macOS、Linux 和 Windows 上執行。Deno 是一個單獨的可執行檔案,它沒有額外的依賴。

1.安裝

在 macOS 下可以通過Shell命令安裝:

curl -fsSL https://deno.land/x/install/install.sh | sh

這個方式在國內安裝會很慢,慢到下不下來。。。so,不推薦。

也可以通過HomeBrew 安裝:

brew install deno

deno-install-brew

這個方式可以安裝下來,但是,安裝的版本是 v0.20.0,很低的版本:

deno-version-low.jpg

並且這個版本不帶 upgrade 命令,升級 deno 的時候很不方便。so,也不推薦。

安利通過國內加速器(映象源 https://x.deno.js.cn )來安裝:

curl -fsSL https://x.deno.js.cn/install.sh | sh

也可以指定版本:

curl -fsSL https://x.deno.js.cn/install.sh | sh -s v1.0.0 

deno-install-x.jpg

首次安裝,可以看到提示,需要手動配置一下環境變數,配置語句也已經給出:

$ touch ~/.bash_profile # 建立使用者環境變數檔案
$ vim ~/.bash_profile # 開啟檔案,將剛才命令列提示給出的配置語句貼上進去,儲存退出。

讓配置立即生效:

$ source ~/.bash_profile 

環境變數就設定好了,現在在任何一個新開啟的命令列裡面都可以使用 deno 命令了。

注意:如果之前使用 brew 安裝過低版本的 deno,請使用 brew uninstall deno 解除安裝 deno 之後,再使用加速器安裝高版本,不解除安裝直接安裝高版本不會生效。(別問我為什麼知道。。。都是淚。

其他作業系統環境的安裝可參考 https://github.com/denoland/deno_install。

如果要升級本地的 Deno,可以執行

deno upgrade

還可以安裝指定的版本:

deno upgrade --version 1.1.0

這個命令會從 github.com/denoland/deno/releases 獲取最新的釋出版本(一個可執行的二進位制檔案 zip 壓縮包),然後解壓並替換現有的版本。而 github release 的檔案使用的是 aws,在國內訪問不穩定。

So,升級也推薦使用國內加速器安裝指定版本來達到目的。

2.測試安裝

deno --version

deno-version-high.jpg

如果列印出 Deno 版本,說明安裝成功。

到這裡,我們就安裝好 Deno ,並且可以基於 Deno 進行開發了。

3.執行一個遠端的專案

跑一個遠端專案(官方的demo)

deno run https://deno.land/std/examples/welcome.ts

可以看到在控制檯輸出"Welcome to Deno ?”。

deno-run-remote.jpg

4.執行一個本地的專案

起一個最簡單的本地服務

// http.js
import { serve } from "https://deno.land/std@0.57.0/http/server.ts";

const s = serve({ port: 8000 });
console.log("http://localhost:8000/");

for await (const req of s) {
  req.respond({ body: "Hello World\n" });
}

可以看到 Deno 在引用第三方模組的方式為 ES6 的 import 語法,並且直接通過 URL 來引入,版本號也被鎖定在了 URL 中。

另外,Deno 支援 頂層的 await 語法,不用與 async 語法配對使用了。

執行:

deno run http.js

deno-run-local.jpg

首次引入第三方包,Deno 會去下載這個包和它的依賴,這些包會被快取到全域性,下次再引入的時候,將直接讀取快取。

這裡報了一個缺少網路許可權的錯,這是因為 Deno 採用沙箱模式執行程式碼,網路許可權必須通過手動新增 flag (--allow-net)來開啟。

帶上網路許可權執行:

deno run --allow-net http.js

deno-run-with-net.jpg

開啟localhost://8000

deno-run-with-net.jpg

可以看到一個簡單的本地服務就跑起來了。

5.其他相關配置

如果我們要高效地使用 Deno,最好還需要設定一些開發環境,比如環境變數、命令列自動補全、編輯器等。

  • 環境變數

DENO_DIR:
這是 Deno 在本地存放生成的程式碼和快取下載的模組的路徑,預設為 $HOME/Library/Caches/deno。

NO_COLOR:
這個會關閉輸出的文字顏色。

HTTP_PROXY 和 HTTPS_PROXY :
這兩個變數用來設定 HTTP 和 HTTPS 的代理地址。

  • 命令自動補全
    通過 deno completions 命令可以生成補全指令碼。他會輸出到 stdout,應該將它重定向到適當的檔案。

Deno 支援的 shell 有 zsh、bash、fish、powershell、elvish。

  • 編輯器外掛
    我們可以給 VS Code 配置 Deno 的外掛: vscode_deno

如果你是其他編輯器/IDE,可以參考官網推薦的外掛

Deno 將來會取代 Node.js 嗎?

這也是很多前端者關心的話題,網路上兩種聲音都有,我的看法是:會共存,但不會取代。

首先,Node.js 的作者之所以開發 Deno 只是為了兌現他心目中對 JavaScript Runtime 的一個理想實現,並不是為了取代 Node.js;

其次,Node.js 經過十多年的發展,已經很成熟了(雖然在 Ryan 的眼裡不那麼完美),並且已經被廣泛應用。個人認為,將來 Deno 要做的事情,Node.js 都能做,如果沒有特別的因素(比如潛在的安全隱患等),已經使用了 Node.js 的應用,不大會改用 Deno 重構。

所以,以我目前的認知,我認為 Deno 如果能發展起來,應該會與 Node.js 共生,而不會取代 Node.js。

不管怎樣,我很欽佩 Ryan,在 Node.js 獲得如此成功之後,仍然懷揣對作品的理想追求,大膽分享自己在 Node.js 中犯的“錯誤”,開始 Deno 的征程,並且現在 Deno 正在以飛快的速度在迭代。就在昨天,Deno 又釋出了 V1.1.0。

deno-release-v1.1.0.jpg

結語

以上是我對 Deno 的一個初探,解答了什麼是 Deno,它有什麼作用,有哪些特點,與 Node.js 有什麼不同,以及如何使用 Deno(雖然只淺淺地跑了最簡單的程式,但足以讓我感覺到 Deno 與 Node.js 在使用上的不同)。現在,總算對 Deno 的有了一個比較清晰的瞭解。

有興趣交流的小夥伴可以在這裡留言討論:https://github.com/yc111/yc111.github.io/issues/2
Deno 交流QQ群:698469316


參考
Deno Manual:https://deno.land/manual
Deno Doc:https://doc.deno.land/https/github.com/denoland/deno/releases/latest/download/lib.deno.d.ts
Deno中文社群:https://denocn.org/
Deno中文開發者社群:https://deno.js.cn/
Deno中文手冊:https://nugine.github.io/deno-manual-cn/
Futures 和 Tokio 專案的前世今生:https://rustcc.cn/article?id=8af74de6-1e3d-4596-94ca-c3da45509f58


文章首發于于公眾號「前端手札」,喜歡的話可以關注一下哦。

qianduanshouzha-gzh.png


本文作者:ChampYin
轉載請註明出處:https://champyin.com/2020/06/14/Deno-初探/

相關文章