前言 Deno 已經正式發佈了! 我說這句話時候,是不是很多前端 和 NodeJS 工(碼)程(農)師已經按不住自己的40米大刀了。心中的不僅感慨前端是真的會造輪子,有了 node 還不夠嗎,還沒學會 node 又搞了個 deno,node 和 deno 啥區別?! 的確,deno 和 node 形 ...
前言
Deno 已經正式發佈了!
我說這句話時候,是不是很多前端 和 NodeJS 工(碼)程(農)師已經按不住自己的40米大刀了。心中的不僅感慨前端是真的會造輪子,有了 node 還不夠嗎,還沒學會 node 又搞了個 deno,node 和 deno 啥區別?!
的確,deno 和 node 形態很相似,要解決的問題似乎也相同,那他們到底有啥區別,這一切究竟是道德的淪喪還是 ry 的扭曲,讓我們走進本篇文章,一探究竟。
一定要看到最後哦,最後有驚喜哦!
Deno VS Node
Node | Deno | |
---|---|---|
API 引用方式 | 模塊導入 | 全局對象 |
模塊系統 | CommonJS & 新版 node 實驗性 ES Module | ES Module 瀏覽器實現 |
安全 | 無安全限制 | 預設安全 |
Typescript | 第三方,如通過 ts-node 支持 | 原生支持 |
包管理 | npm + node_modules | 原生支持 |
非同步操作 | 回調 | Promise |
包分發 | 中心化 npmjs.com | 去中心化 import url |
入口 | package.json 配置 | import url 直接引入 |
打包、測試、格式化 | 第三方如 eslint、gulp、webpack、babel 等 | 原生支持 |
1.內置 API 引用方式不同
node 模塊導入
node 內置 API 通過模塊導入的方式引用,例如:
const fs = require("fs"); fs.readFileSync("./data.txt"); 複製代碼
deno 全局對象
而 deno 則是一個全局對象 Deno
的屬性和方法:
Deno.readFileSync("./data.txt"); 複製代碼
具體 deno 有哪些方法,我們可以通過 repl
看一下:
deno # 或 deno repl
複製代碼
進入repl
後,輸入Deno
回車,我們可以看到:
{
Buffer: [Function: Buffer],
readAll: [AsyncFunction: readAll],
readAllSync: [Function: readAllSync],
writeAll: [AsyncFunction: writeAll],
writeAllSync: [Function: writeAllSync],
# .....
}
複製代碼
這種處理的方式好處是簡單、方便,壞處是沒有分類,想查找忘記的 API 比較困難。總體來說見仁見智。
2.模塊系統
我們再來看一下模塊系統,這也是 deno 和 node 差別最大的地方,同樣也是 deno 和 node 不相容的地方。
node CommonJS 規範
我們都知道 node 採用的是 CommonJS 規範,而 deno 則是採用的 ES Module 的瀏覽器實現,那麼我們首先來認識一下:
ES Module 的瀏覽器實現
具體關於 ES Module 想必大家都早已熟知,但其瀏覽器實現可能大家還不是很熟悉,所以我們先看一下其瀏覽器實現:
<body> <!-- 註意這裡一定要加上 type="module" --> <script type="module"> // 從 URL 導入 import Vue from "https://unpkg.com/[email protected]/dist/vue.esm.browser.js"; // 從相對路徑導入 import * as utils from "./utils.js"; // 從絕對路徑導入 import "/index.js"; // 不支持 import foo from "foo.js"; import bar from "bar/index.js"; import zoo from "./index"; // 沒有 .js 尾碼 </script> </body> 複製代碼
deno 的模塊規範
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"; // 必須指定擴展名 複製代碼
我們發現其和我們平常在 webpack 或者 ts 使用 es module 最大的不同:
-
可以通過 import url 直接引用線上資源;
-
資源不可省略擴展名和文件名。
關於第 1 點,爭議非常大,有人很看好,覺得極大的擴展了 deno 庫的範圍;有人則不太看好,覺得國內網速的原因,並不實用。大家的看法如何,歡迎在評論區發表