2018:Deno 構想——Ryan Dahl 對 Node 的反思#
事件#
2018年,Ryan Dahl 在 JSConf EU 發表著名演講 「我對 Node.js 感到後悔的10件事」,並宣布新專案 Deno。2020年5月發佈 Deno 1.0(見 2020-Deno-1-0問世)。
為何重要#
Dahl 指出 Node.js 的十大設計缺陷,Deno 逐一修正: 1. 模組系統:放棄 CommonJS 的 require,採用標準 ESM(import) 與 URL 匯入,不需要 node_modules。 2. TypeScript 一等公民:內建 TS 支援,不需建置設定。 3. 安全性:預設沙箱,檔案/網路/環境變數存取需明確授權(--allow-read 等)——Node 完全沒有權限模型。 4. Promise 而非回呼:Node 早期 API 以回呼為主(error-first callback),導致回呼地獄;Deno 全部使用 Promise 與 async/await。 5. 單一可執行檔、頂層 await、標準 API 對齊瀏覽器(如 fetch 內建)。
理論與實用原因#
- 理論原因:以瀏覽器為「正確先例」——JavaScript 的正規模組與安全模型應以 Web 標準為準,伺服器端不應自成體系。
- 實用原因:Node 的
node_modules目錄暴脹、package.json相依地獄、安全漏洞頻傳(npm 供應鏈攻擊),都需要根本性重設計。
彌補了什麼缺陷#
彌補了 Node.js「回呼式 API、無權限模型、非標準模組系統、TS 支援需外部工具」的歷史包袱。Deno 也證明了一件事:一個語言的運行時可以有多個競爭實作,隨後 Bun(2023)加入戰局,Node 本身也被迫向 ESM、fetch、權限模型靠攏。
相關條目#
程式範例#
1. Node 的設計缺陷 vs Deno 的修正#
// Node(2009):error-first callback——回呼地獄的根源
fs.readFile("config.json", (err, data) => {
if (err) return cb(err);
doSomething(data, cb);
});
// Deno(2018):全 Promise + async/await,不需回呼
const data = await Deno.readTextFile("config.json");
doSomething(data);
2. 安全模型:預設沙箱,Node 完全沒有權限概念#
# Node:程式碼隨便讀檔、上網、改環境變數——全開放
node script.js
# Deno:預設什麼都不能做,明確授權
deno run script.js # 💥 PermissionDenied
deno run --allow-read --allow-net script.js # ✅ 明確授權
// script.js
const data = await Deno.readTextFile("./config.json"); // 需 --allow-read
const res = await fetch("https://api.example.com"); // 需 --allow-net
3. URL 匯入:不需要 node_modules 與中央 registry#
// Node:npm + node_modules 目錄
const express = require("express");
// Deno:直接從 URL 匯入,模組快取在本機
import { serve } from "https://deno.land/std@0.200.0/http/server.ts";
serve(() => new Response("Hello"));
4. TypeScript 開箱即用#
deno run server.ts # 直接執行 .ts——Node 需要 tsc 編譯或 ts-node