引言
2020 年 5 月 13 日,可能是前端開發史上又一個里程碑式的一天,因爲一個名爲 Deno 1.0 版本正式發佈了。
那麼問題來了,Deno 是什麼?爲什麼說是里程碑?它和 Node 有什麼關係?和我又有什麼關係?
帶着疑問,跟着我一起來初窺 Deno 1.0 的神祕面紗吧。
背景
Deno 是 Ryan Dahl 在 2017 年開始的一個項目。從那時候開始,就有不少人開始關注這個項目了,爲什麼?這要從 Ryan Dahl 這個人說起。
Ryan Dahl ,2009 年創造了現在火遍全球技術圈的 Node.js ,被譽爲 Node 之父。但是遺憾的是,他後來把 Node 移交給了其他開發者,轉而研究人工智能,不再過問了。直到後來他再回過頭撿起 Node 的時候,才發現這個項目已經背離了他的初衷,有一些無法忽視的問題。
於是就有了這樣一件事,在 2018年一次公開的演講中,Ryan Dahl 發表了一次讓人意外的演講,演講的主題是 “Design Mistakes in Node”,翻譯爲中文則是“Node 的設計失誤”,基本上把 Node 全部否定了,包括安全性、構建系統、package.json、node_modules、index.js 等等,並表示 Node 存在的種種不足導致有許多嚴重 bug 問題且不可迴避。
由於上面這些原因,Ryan Dahl 決定放棄 Node,從頭寫一個替代品,徹底解決這些問題,那便是 Deno。
《Design Mistakes in Node》PPT:https://tinyclouds.org/jsconf2018.pdf
什麼是Deno
Deno 目前有兩種發音,"德諾"和"蒂諾"。之前看了阮一峯老師一篇關於 Deno 的文章之後,傾向於"蒂諾"這個發音。
Deno 的標誌是一隻恐龍,恐龍(dinosaur)的英文縮寫正是 dino。 ——摘自《Deno 運行時入門教程:Node.js 的替代品》
Deno 這個名字取得就很有趣了,細心的朋友可能會發現,Deno這個名字就是來自 Node 的字母重新組合(Node = no + de),它的意思是"消滅 Node.js"(de = destroy, no = Node.js)。另外一種解釋是顛倒 Node 字母的寓意就是說要顛覆 Node ,這兩種意思其實也差不多。
實現
Node 的開發語言是 C++,而 Deno 卻不一樣。Deno 的開發一開始使用的是 Go 語言,後來換成了 Rust。
或許你會有疑問,爲啥不是 C++、Go,爲什麼是 Rust ?
主要原因是 Rust 提供了很多現成的模塊,對 Deno 項目來說,可以節約很多開發時間。如果使用 C++,就意味着一切東西都需要從頭開始構建,這樣的話就太浪費時間了。
優勢
- Deno 基於最新的 JavaScript 語言;
- Deno 具有覆蓋面廣泛的標準庫;
- Deno 以 TypeScript 爲核心,配以更多獨特的方式從而帶來了巨大的優勢,其中包括一流的 TypeScript 支持(Deno 自動編譯 TypeScript 而無需你單獨編譯);
- Deno 大力擁抱 ES 模塊標準;
- Deno 沒有包管理器;
- Deno 具有一流的
await
語法支持; - Deno 內置測試工具;
- Deno 旨在儘可能地與瀏覽器兼容,例如通過提供內置對象
fetch
和全局window
對象
劣勢
有一種“家庭背景”叫做生態,就憑這一點,目前的 Deno 完全是望塵莫及。很多優秀的東西沒有流行起來,不是說它不夠優秀,而是缺乏相關的生態。就像華爲想搞自己的鴻蒙系統,即使真的能比安卓優秀,但是安卓巨大的生態就足夠領先很多年。生態這東西不是一兩年就能搞起來的,需要長年累月的維護、開發以及拓展。
Ryan Dahl 也說了,Deno 現在不打算對 Node 做兼容處理,也就是說很多東西在 Node 能用但是在 Deno 上用不了。所以對於 Deno 來說,還有很長的路要走。
Deno VS Node
Deno | Node | |
---|---|---|
版本 | v1.0.2 | v14.3.0 |
github star | 61.1k | 70.5k |
API 引用方式 | 全局對象 | 模塊導入 |
模塊系統 | ES Module 瀏覽器實現 | CommonJS & 新版 node 實驗性 ES Module |
安全 | 默認安全 | 無安全限制 |
Typescript | 原生支持 | 第三方,如通過 ts-node 支持 |
包管理 | 原生支持 | npm + node_modules |
異步操作 | Promise | 回調 |
包分發 | 去中心化 import url | 中心化 npmjs.com |
入口 | import url 直接引入 | package.json 配置 |
打包、測試、格式化 | 原生支持 | 第三方如 eslint、gulp、webpack、babel 等 |
API 引用方式
Node 內置 API 通過模塊導入的方式引用,例如:
const fs = require("fs");
fs.readFileSync("./node.txt");
而 Deno 則是一個全局對象 Deno
的屬性和方法:
Deno.readFileSync("./deno.txt");
模塊系統
Node 採用的是 CommonJS 規範,而 Deno 則是採用的 ES Module 的瀏覽器實現。
對於 Deno 來說:
// 支持
import * as fs from "https://deno.land/std/fs/mod.ts";
import { deepCopy } from "./deepCopy.js";
import foo from "/foo.ts";
// 不支持
import foo from "foo.ts";
import bar from "./bar"; // 必須指定擴展名
安全
Deno 默認安全,通過權限控制提供了一個安全的沙箱環境,程序只能訪問由用戶設置爲可執行標誌的文件。外部代碼沒有文件系統、網絡、環境的訪問權限,除非顯式開啓。而 Node 程序可以直接訪問用戶足以訪問的任何內容。
支持 Typescript
Deno 支持開箱即用的 TypeScript 的環境,不需要任何配置文件就能在 Deno 中輕易地使用 TypeScript 。
包管理
Node 有一個官方的軟件包管理器,稱爲 NPM。Deno 沒有,而是允許你從 URL 導入任何 ES 模塊。這使得 Deno 非常靈活,我們可以直接創建軟件包而無需在 NPM 這樣的存儲庫中發佈它們。 Deno 下載模塊以後,依然會有一個總的目錄,在本地緩存模塊,因此可以離線使用。
// index.js
import { white, bgRed } from "https://deno.land/std/fmt/colors.ts";
console.log(bgRed(white("hello world!")));
> deno run index.js
Download https://deno.land/std/fmt/colors.ts
Compile https://deno.land/std/fmt/colors.ts
hello world!
異步操作
Node 用回調的方式處理異步操作,而 Deno 則採用 Promise。
包分發
對於 www.npmjs.com 我們肯定都不陌生,它是推動 Node 蓬勃發展的重要支點。而 Deno 並沒有一個像 npmjs.com 的倉庫,通過 import url 的方式將互聯網任何一處的代碼都可以引用。
入口
我們知道 npm 包必須有 package.json
文件,裏面不僅需要指明 main
或 module
或 browser
等字段來標明入口文件,還需要指明 name
、license
、description
等字段來說明這個包。在 Deno 中,其模塊不需要任何配置文件,直接是 import url 的形式。
打包、測試、格式化
使用過 Node 的一定有這樣的體會,我們需要經常引入一些其他工具或者插件,例如用 eslint 做代碼格式校檢、用 webpack 打包和構建項目、用 babel 做轉化等等。而 Deno 通過內置了一些類似的工具,不需要我們再額外去引入,給我們的開發帶來了不少的方便。
Deno 有一個內置的測試器,可以用來測試 JavaScript 或 TypeScript 代碼。
Deno.test("hello world", () => {
const x = 1 + 2;
if (x !== 3) {
throw Error("x should be equal to 3");
}
});
Deno 有着內置的格式化工具,能夠格式化 TypeScript 和 JavaScript 代碼。
// 格式化當前目錄和子目錄下的所有 JS/TS 文件
deno fmt
// 格式化特定的文件
deno fmt myfile1.ts myfile2.ts
// 檢查當前目錄和子目錄下的所有 JS/TS 文件是否都已被格式化
deno fmt --check
Deno 內置了調試器,使用 Chrome Devtools 或其他支持該協議的客戶端(比如 VSCode)能夠調試 Deno 程序。除此之外,還有打包器、腳本安裝器、依賴查看器等等。
小結
在 Ryan Dahl 的計劃中,他並不會去預想 Deno 在短時間內能夠發展成一個多大規模的平臺。當然咯,把時間調回2009年,JavaScript 還是人人都能取笑的一個有些怪異的小語言,誰也沒想到如今 JavaScript 成爲了使用最廣泛的開發語言之一。
雖然 Deno 是以 Destroy-Node 爲己任而開發的,但就目前來講,Deno 取代 Node 是不可能的,Node 的佔有率太高了,生態也足夠完善,而 Deno 目前僅僅處於發展的最初期。不過我相信,憑藉着它與生俱來的設計優勢,以及目前的關注度,隨着其相關生態的建設,將來的 Deno 會比 Node 更具優勢。
如果你對 Deno 未來的發展也感興趣的話,那就去給它個 star 吧。
最後附上 Deno 傳送門:https://github.com/denoland/deno