📋 目錄
當 Bun 以「極速」打響名號時,Deno 走的路線完全不同:Deno 的核心賣點是「安全」。Deno 2.0 的沙盒執行環境,讓 JavaScript 程式碼預設情況下無法訪問檔案系統、網路或環境變數——除非你明確授權。這個設計選擇在 2026 年變得越來越重要:Supply Chain 攻擊(供應鏈攻擊)越來越猖狂,Node.js 上一次
npm install可能為你的專案帶來潛在的後門。Deno 的安全模型,是對這個問題的一個認真回答。
為什麼 Deno 的安全模型值得關注
在 Node.js 生態系裡,有一個長期被忽略的問題:當你 npm install 一個 package,該 package 的程式碼有權限訪問你整個系統。
# Node.js:安裝一個 package
npm install some-random-package
# 這個 package 的程式碼現在可以做任何事:
# - 讀取你的 ~/.npmrc 取得 npm token
# - 訪問你的 SSH keys
# - 發送資料到外部伺服器
# - 刪除檔案
這個問題在 2020-2024 年變得越來越嚴重。XZ Utils 事件(2024)、 hundreds of malicious npm packages、Colors.js 和 faker.js 的 maintainer 生氣報復——這些事件的共同點:攻擊者利用了 Node.js 的「全部允許」安全模型。
Deno 的設計起點,就是把「不信任」作為預設值。
Permission Sets:細緻的權限控制
Deno 的安全模型
Deno 預設不允許任何危險操作:
# 如果你的程式碼嘗試訪問網路,Deno 會拒絕並給你一個清晰的錯誤
$ deno run app.ts
⚠️ Deno requests network access to "api.example.com".
Grant? [y/N]
// 如果你沒有給予檔案系統權限,這會失敗
import { readFile } from 'fs';
const data = readFileSync('./config.json', 'utf-8');
// Error: Permission denied: read file './config.json'
Permission Sets 的精細度
Deno 2.0 的 Permission Sets 讓權限控制更精細:
# Deno 2.0 的權限粒度
deno run \
--allow-net=api.example.com \ # 只允許訪問特定網域
--allow-read=/app/data \ # 只允許讀取特定目錄
--allow-env=NODE_ENV \ # 只允許讀取特定環境變數
app.ts
在實際應用中的範例
// 你的 API client 只需要網路權限
// deno run --allow-net=api.example.com app.ts
const response = await fetch('https://api.example.com/data');
// ✅ 可以
// ❌ 但如果你嘗試讀取檔案,就會失敗
import { readFile } from 'fs'; // 沒有 --allow-read
與 Node.js 的對比
| 維度 | Deno | Node.js |
|---|---|---|
| 網路訪問 | 需要明確授權 | 預設全部允許 |
| 檔案系統 | 需要明確授權 | 預設全部允許 |
| 環境變數 | 需要明確授權 | 預設全部允許 |
| 子程序執行 | 需要明確授權 | 預設全部允許 |
Node.js 相容性:Deno 2.0 的實用性
過去的相容性問題
Deno 1.x 的一個主要批評:與 Node.js 的相容性不夠。很多 npm packages 無法在 Deno 裡運行。
Deno 2.0 大幅改善了這個問題:
# Deno 2.0 現在可以直接執行 npm packages
deno run npm:express
deno run npm:prisma
# 直接執行 JSR packages
deno run jsr:@std/bytes
仍然不相容的部分
// ❌ Deno 不支援 Node.js 原生 addons(.node 文件)
const addon = require('./native.node'); // Error
// ❌ 不支援某些 Node.js 內建模組
const { uv } = process.binding('uv'); // Error
Deno 2.0 對 Node.js 模組的支援
// ✅ Deno 2.0 支援這些 Node.js 模組:
import fs from 'node:fs';
import path from 'node:path';
import crypto from 'node:crypto';
import { Buffer } from 'node:buffer';
// ✅ 你只需要明確授權
// deno run --allow-read --allow-net app.ts
Deno 的 All-in-one 工具鏈
Deno 另一個特點:自帶完整的工具鏈,不需要額外安裝:
# Deno 內建:
deno lint # Linter
deno fmt # Formatter
deno test # 測試框架
deno compile # 編譯成單一執行檔
deno install # 安裝 scripts
# 直接執行 TypeScript,不需要 build step
deno run app.ts
deno test # 直接跑測試
deno fmt # 直接格式化
# Deno compile:把你的 app 編譯成單一執行檔
deno compile -o myapp app.ts
# 輸出:myapp(不含 Node.js 環境,單一檔案)
這個「batteries included」的做法,讓 Deno 適合需要簡單部署的場景。
Deno vs Bun vs Node.js
| 維度 | Deno | Bun | Node.js |
|---|---|---|---|
| 安全性 | 沙盒安全模型 | 預設全部允許 | 預設全部允許 |
| 速度 | 快 | 最快 | 成熟穩定 |
| TypeScript | 原生支援 | 需要設定 | 需要額外設定 |
| npm 支援 | ✅ 原生 | ✅ 原生 | — |
| 工具鏈 | 內建 | 需要額外工具 | 社群豐富 |
| 主要賣點 | 安全性 | 效能 | 生態成熟 |
什麼時候選 Deno
- 安全性優先的場景:處理不可信任的程式碼、插件系統
- 需要快速部署:Deno compile 輸出單一執行檔,不需要 Node.js 環境
- 喜歡簡潔的工具鏈:不需要管理一堆 npm packages
- 處理敏感的後端服務:銀行、醫療、政府項目
什麼時候不選 Deno
- 依賴特定的 Node.js 生態:很多企業級工具只有 Node.js 版本
- 團隊已經熟悉 Node.js:學習 Deno 有成本
- 需要最大效能:Bun 在純速度上仍然領先
Deno 2.5 LTS 的支援時間表
# Deno 2.5 LTS 支援至 2026 年 4 月
# 建議的更新策略:
deno update # 檢查更新
deno upgrade # 升級到最新版
結語:安全性正在成為選擇 Runtime 的維度
過去,選擇 JavaScript Runtime 的維度是:效能、生態、相容性。Deno 2.0 引入了一個新的維度:安全性。
在 Supply Chain 攻擊越來越頻繁的時代,這個維度的重要性正在提升。當一個 npm install 可能為你的系統帶來後門,Deno 的「不信任預設」模型提供了一個不一樣的起點。
當然,Deno 的市場份額目前仍然很小,生態系的豐富度不如 Node.js。但對於需要更高安全保障的場景,Deno 2.0 是一個越來越認真的選擇。
延伸閱讀
- Bun vs Node.js vs Deno 2026 完整比較 — 三大 Runtime 的效能與生態比較
本文是「2026 JavaScript Runtime 比較」系列文章之一。