电竞比分网-中国电竞赛事及体育赛事平台

分享

Deno 運(yùn)行時(shí)入門教程:Node.js 的替代品

 貓熊飛飛 2020-03-07

這幾天假期,我學(xué)習(xí)了一下 Deno[1]。它是 Node.js 的替代品。有了它,將來(lái)可能就不需要 Node.js 了。

這篇文章就是 Deno 的一個(gè)初步介紹,嘗試回答為什么 Node.js 不能滿足需要,以及 Deno 能夠帶給我們什么?

以下內(nèi)容主要基于 Bert Belder[2]和 Ryan Dahl[3]的最新演講。

0、

Deno 運(yùn)行時(shí)入門教程:Node.js 的替代品

進(jìn)入主題之前,先說(shuō)一下 Deno 這個(gè)詞怎么發(fā)音。

兩種發(fā)音,“德諾”和“蒂諾”,我都聽到過(guò)。看起來(lái),“蒂諾”這個(gè)發(fā)音應(yīng)該更合適一些,因?yàn)?Deno 的標(biāo)志是一只恐龍。恐龍(dinosaur)的英文縮寫正是 dino。

1、

Deno 運(yùn)行時(shí)入門教程:Node.js 的替代品

Deno 是 Ryan Dahl 在 2017 年創(chuàng)立的。

Ryan Dahl 也是 Node.js 的創(chuàng)始人,從 2007 年一直到 2012 年,他后來(lái)把 Node.js 移交給了其他開發(fā)者,不再過(guò)問(wèn)了,轉(zhuǎn)而研究人工智能。

他始終不是很喜歡 Python 語(yǔ)言,久而久之,就想搞一個(gè) JavaScript 語(yǔ)言的人工智能開發(fā)框架。等到他再回過(guò)頭撿起 Node.js,發(fā)現(xiàn)這個(gè)項(xiàng)目已經(jīng)背離了他的初衷,有一些無(wú)法忽視的問(wèn)題。

2、

Deno 運(yùn)行時(shí)入門教程:Node.js 的替代品

首先,過(guò)去五六年,JavaScript 語(yǔ)言脫胎換骨,ES6 標(biāo)準(zhǔn)引入了大量新的語(yǔ)法特性。其中,影響最大的語(yǔ)法有兩個(gè):Promise 接口(以及 async 函數(shù))和 ES 模塊。

Node.js 對(duì)這兩個(gè)新語(yǔ)法的支持,都不理想。由于歷史原因,Node.js 必須支持回調(diào)函數(shù)(callback),導(dǎo)致異步接口會(huì)有 Promise 和回調(diào)函數(shù)兩種寫法;同時(shí),Node.js 自己的模塊格式 CommonJS 與 ES 模塊不兼容,導(dǎo)致遲遲無(wú)法完全支持 ES 模塊。

其次,Node.js 的模塊管理工具 npm,邏輯越來(lái)越復(fù)雜;模塊安裝目錄 npm_modules 極其龐雜,難以管理。Node.js 也幾乎沒有安全措施,用戶只要下載了外部模塊,就只好聽任別人的代碼在本地運(yùn)行,進(jìn)行各種讀寫操作。

再次,Node.js 的功能也不完整,導(dǎo)致外部工具層出不窮,讓開發(fā)者疲勞不堪:webpack,babel,typescript、eslint、prettier……

3、

Deno 運(yùn)行時(shí)入門教程:Node.js 的替代品

由于上面這些原因,Ryan Dahl 決定放棄 Node.js,從頭寫一個(gè)替代品,徹底解決這些問(wèn)題。deno 這個(gè)名字就是來(lái)自 Node 的字母重新組合(Node = no de),表示“拆除 Node.js”(de = destroy, no = Node.js)。

跟 Node.js 一樣,Deno 也是一個(gè)服務(wù)器運(yùn)行時(shí),但是支持多種語(yǔ)言,可以直接運(yùn)行 JavaScript、TypeScript 和 WebAssembly 程序。

它內(nèi)置了 V8 引擎,用來(lái)解釋 JavaScript。同時(shí),也內(nèi)置了 tsc 引擎,解釋 TypeScript。它使用 Rust 語(yǔ)言開發(fā),由于 Rust 原生支持 WebAssembly,所以它也能直接運(yùn)行 WebAssembly。它的異步操作不使用 libuv 這個(gè)庫(kù),而是使用 Rust 語(yǔ)言的 Tokio[4]庫(kù),來(lái)實(shí)現(xiàn)事件循環(huán)(event loop)。

4、

Deno 運(yùn)行時(shí)入門教程:Node.js 的替代品

你可能會(huì)問(wèn),為什么使用 Rust,而不是 C (Node.js 的開發(fā)語(yǔ)言)?

主要原因是 Rust 提供了很多現(xiàn)成的模塊,對(duì) Deno 項(xiàng)目來(lái)說(shuō),可以節(jié)約很多開發(fā)時(shí)間。

5、

Deno 運(yùn)行時(shí)入門教程:Node.js 的替代品

Deno 本身也是 Rust 的一個(gè)模塊。如果你想在 Rust 里面使用 V8 引擎,就可以加載 Deno。它等于是一個(gè) V8 的包裝層,提供一些底層 API,讓你跟 V8 引擎互動(dòng)。

6、

Deno 運(yùn)行時(shí)入門教程:Node.js 的替代品

Deno 只有一個(gè)可執(zhí)行文件,所有操作都通過(guò)這個(gè)文件完成。它支持跨平臺(tái)(Mac、Linux、Windows)。

7、

Deno 運(yùn)行時(shí)入門教程:Node.js 的替代品

Deno 具有安全控制,默認(rèn)情況下腳本不具有讀寫權(quán)限。如果腳本未授權(quán),就讀寫文件系統(tǒng)或網(wǎng)絡(luò),會(huì)報(bào)錯(cuò)。

必須使用參數(shù),顯式打開權(quán)限才可以。

  • --allow-read:打開讀權(quán)限,可以指定可讀的目錄,比如--allow-read=/temp
  • --allow-write:打開寫權(quán)限。
  • --allow-net=google.com:允許網(wǎng)絡(luò)通信,可以指定可請(qǐng)求的域,比如--allow-net=google.com
  • --allow-env:允許讀取環(huán)境變量。

8、

Deno 運(yùn)行時(shí)入門教程:Node.js 的替代品

Deno 支持 Web API,盡量跟瀏覽器保持一致。

它提供 window 這個(gè)全局對(duì)象,同時(shí)支持 fetch、webCrypto、worker 等 Web 標(biāo)準(zhǔn),也支持 onload、onunload、addEventListener 等事件操作函數(shù)。

此外,Deno 所有的異步操作,一律返回 Promise。

9、

Deno 運(yùn)行時(shí)入門教程:Node.js 的替代品

Deno 只支持 ES 模塊,跟瀏覽器的模塊加載規(guī)則一致。沒有 npm,沒有 npm_modules 目錄,沒有require命令(即不支持 CommonJS 模塊),也不需要package.json文件。

所有模塊通過(guò) URL 加載,比如import { bar } from 'https:///bar.ts'(絕對(duì) URL)或import { bar } from './foo/bar.ts'(相對(duì) URL)。因此,Deno 不需要一個(gè)中心化的模塊儲(chǔ)存系統(tǒng),可以從任何地方加載模塊。

但是,Deno 下載模塊以后,依然會(huì)有一個(gè)總的目錄,在本地緩存模塊,因此可以離線使用。

10、

Deno 運(yùn)行時(shí)入門教程:Node.js 的替代品

由于 Deno 只支持從 URL 加載模塊,導(dǎo)致 Node.js 的模塊加載寫法都會(huì)失效。

import React from 'react';
import { Box, Grid } from '@material-ui/core';
import { initializeApp } from 'firebase/app';

上面的寫法在 Deno 里面都是非法的。

Deno 的所有模塊都要通過(guò)入口腳本加載,不能通過(guò)模塊名加載,所以必須帶有腳本后綴名。

11、

Deno 運(yùn)行時(shí)入門教程:Node.js 的替代品

Deno 原生支持 TypeScript 語(yǔ)言,可以直接運(yùn)行,不必顯式轉(zhuǎn)碼。

它的內(nèi)部會(huì)根據(jù)文件后綴名判斷,如果是.ts后綴名,就先調(diào)用 TS 編譯器,將其編譯成 JavaScript;如果是.js后綴名,就直接傳入 V8 引擎運(yùn)行。

12、

Deno 運(yùn)行時(shí)入門教程:Node.js 的替代品

Deno 內(nèi)置了開發(fā)者需要的各種功能,不再需要外部工具。打包、格式清理、測(cè)試、安裝、文檔生成、linting、腳本編譯成可執(zhí)行文件等,都有專門命令。

執(zhí)行deno -hdeno help,就可以顯示 Deno 支持的子命令。

  • deno bundle:將腳本和依賴打包
  • deno eval:執(zhí)行代碼
  • deno fetch:將依賴抓取到本地
  • deno fmt:代碼的格式美化
  • deno help:等同于-h參數(shù)
  • deno info:顯示本地的依賴緩存
  • deno install:將腳本安裝為可執(zhí)行文件
  • deno repl:進(jìn)入 REPL 環(huán)境
  • deno run:運(yùn)行腳本
  • deno test:運(yùn)行測(cè)試

13、

Deno 運(yùn)行時(shí)入門教程:Node.js 的替代品

Deno 的安裝可以參考官網(wǎng)首頁(yè)[5],但是你可以直接去 GitHub 倉(cāng)庫(kù)的發(fā)布頁(yè)[6],下載編譯好的可執(zhí)行文件(上圖)。

下載 Deno 以后,查看一下版本。

$ deno --version
deno 0.31.0
v8 8.1.108
typescript 3.7.2

命令行直接運(yùn)行deno,就會(huì)進(jìn)入 REPL 環(huán)境。

$ deno
> console.log(1,2,3)
1 2 3
undefined
>

14、

Deno 運(yùn)行時(shí)入門教程:Node.js 的替代品

下面,運(yùn)行一個(gè) TypeScript 的遠(yuǎn)程腳本,這是官網(wǎng)給出的例子[7]。

$ deno run \
https://nd/std/examples/curl.ts \
https://

上面例子中,Deno 執(zhí)行遠(yuǎn)程腳本curl.ts,用這個(gè)腳本去抓取網(wǎng)址。但是,運(yùn)行后報(bào)錯(cuò),表示沒有網(wǎng)絡(luò)通信的權(quán)限。

我們給予 Deno 網(wǎng)絡(luò)通信的權(quán)限,就可以順利執(zhí)行。

$ deno run --allow-net \
https://nd/std/examples/curl.ts \
https://

15、

Deno 運(yùn)行時(shí)入門教程:Node.js 的替代品

現(xiàn)在,Deno 最新版本是 0.31。根據(jù)規(guī)劃,1.0 應(yīng)該會(huì)在今年上半年發(fā)布。

Deno 還處在密集開發(fā)中,功能不穩(wěn)定,不建議用于生產(chǎn)環(huán)境。但是,它已經(jīng)是一個(gè)可用的工具,大家可以多試用,熟悉它的用法。我相信,設(shè)計(jì)上的諸多優(yōu)點(diǎn),將會(huì)使它比 Node.js 更具優(yōu)勢(shì)。

參考資料

[1]

Deno: https://nd/

[2]

Bert Belder: https://www./watch?v=puXyo1jGQys

[3]

Ryan Dahl: https://www./watch?v=1gIiZfSbEAE

[4]

Tokio: https://github.com/tokio-rs/tokio

[5]

官網(wǎng)首頁(yè): https://nd/

[6]

發(fā)布頁(yè): https://github.com/denoland/deno/releases

[7]

例子: https://nd/std/examples/curl.ts

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多