Deno 入门教程 / 第 01 章:Deno 简介
第 01 章:Deno 简介
1.1 Deno 的诞生背景
Ryan Dahl 的反思
2018 年 JSConf EU 上,Node.js 的创始人 Ryan Dahl 做了一场著名的演讲——“10 Things I Regret About Node.js”。他列举了 Node.js 设计中的诸多遗憾:
| 遗憾 | 说明 |
|---|---|
| 没有坚持 Promise | 早期放弃了 Promise,导致后来的回调地狱 |
| 安全性问题 | Node.js 默认拥有完整的系统权限,无安全沙箱 |
| 构建系统(GYP) | node-gyp 构建系统过于复杂 |
| package.json 和 npm | 模块解析过于复杂,中心化的 npm 仓库 |
| node_modules | 嵌套依赖导致目录结构臃肿 |
| require 不带扩展名 | 模块解析逻辑复杂,增加了不确定性 |
| 没有原生 TypeScript 支持 | 需要额外的编译步骤 |
基于这些反思,Ryan Dahl 决定从零开始构建一个新的 JavaScript 运行时——Deno。
Deno 名字的由来
“Deno” 这个名字其实是 “Node” 的字母重新排列(De-No-de → Deno),暗示着它是 Node 的"倒叙"——继承优点,修正错误。
里程碑时间线
| 时间 | 事件 |
|---|---|
| 2018 年 6 月 | Ryan Dahl 发布 Deno 原型(基于 Go 语言) |
| 2018 年下半年 | 重写为 Rust + V8 架构 |
| 2020 年 5 月 | Deno 1.0 正式发布 |
| 2022 年 | Deno 公司获得 $21M 融资 |
| 2023 年 | Fresh 框架成熟,Deno KV 发布 |
| 2024 年 | Deno 2.0 发布,全面兼容 npm |
| 2025 年 | Deno 生态持续壮大,企业采用率提升 |
1.2 设计哲学
Deno 的设计遵循以下核心原则:
🔒 安全优先(Secure by Default)
Node.js: 默认拥有所有权限 → 你需要手动限制
Deno: 默认没有任何权限 → 你需要手动授权
// 这段代码在 Deno 中默认会失败!
const data = await Deno.readTextFile("/etc/passwd");
console.log(data);
// error: Uncaught PermissionDenied: Requires read access to "/etc/passwd"
只有明确授权后才能运行:
deno run --allow-read /etc/passwd script.ts
📦 原生 TypeScript
不需要 tsconfig.json、tsc 编译器或 ts-node,Deno 直接运行 .ts 文件:
// hello.ts
function greet(name: string): string {
return `Hello, ${name}!`;
}
console.log(greet("Deno")); // 直接运行:deno run hello.ts
🌐 Web 标准优先
Deno 优先使用 Web 标准 API(fetch、WebSocket、Request、Response 等),而非自创 API:
// 使用标准 fetch API,而非 Node.js 的 http 模块
const response = await fetch("https://api.github.com/users/denoland");
const data = await response.json();
console.log(data.login);
📁 显式依赖
没有 node_modules,没有 package.json,依赖通过 URL 显式导入:
// 直接从 URL 导入,版本一目了然
import { serve } from "https://deno.land/std@0.224.0/http/server.ts";
🔧 单一可执行文件
Deno 编译为单一的可执行文件,无需安装依赖:
deno compile --allow-net server.ts
# 输出一个独立的可执行文件,可直接分发
1.3 Deno vs Node.js 全面对比
这是每个初学者最关心的问题。让我们做一次详尽的对比:
核心特性对比
| 特性 | Deno | Node.js |
|---|---|---|
| 创建者 | Ryan Dahl | Ryan Dahl |
| 首次发布 | 2020 年 | 2009 年 |
| 语言实现 | Rust + V8 | C++ + V8 |
| TypeScript | ✅ 原生支持 | ⚠️ 需要额外配置(Node 22+ 开始实验性支持) |
| 包管理 | URL / JSR / npm | npm / yarn / pnpm |
| 权限系统 | ✅ 内置沙箱 | ❌ 无 |
| Web API | ✅ 标准支持 | ⚠️ 部分支持 |
| node_modules | ❌ 不需要(Deno 2.0 可兼容) | ✅ 必须 |
| package.json | 可选 | 必须 |
| 标准库 | ✅ 官方维护 | ❌ 依赖第三方 |
| 单文件编译 | ✅ deno compile | ⚠️ 需要 pkg 等工具 |
| 内置工具 | test、bench、lint、fmt | 无 |
| 学习曲线 | 中等 | 低(生态更成熟) |
性能对比
| 场景 | Deno | Node.js | 说明 |
|---|---|---|---|
| HTTP 服务器吞吐量 | 高 | 高 | 两者差距不大,Deno 在高并发下略优 |
| 冷启动时间 | 较快 | 较快 | Deno 2.0 优化显著 |
| TypeScript 执行 | 快(缓存) | 较慢(需编译) | Deno 有编译缓存机制 |
| 内存占用 | 中等 | 中等 | 取决于具体场景 |
| 子进程创建 | 快 | 快 | 两者使用相似的 V8 引擎 |
生态系统对比
| 维度 | Deno | Node.js |
|---|---|---|
| 包数量 | 较少(JSR + npm 兼容) | 海量(200 万+ npm 包) |
| 企业采用 | 逐渐增长 | 广泛 |
| 社区规模 | 活跃但较小 | 庞大 |
| 框架 | Fresh、Oak、Hono | Express、Nest、Next.js |
| ORM | Drizzle、Prisma(兼容) | 丰富 |
| 学习资源 | 日益增多 | 极其丰富 |
1.4 Deno 的技术架构
┌─────────────────────────────────────────┐
│ 你的 TypeScript/JS 代码 │
├─────────────────────────────────────────┤
│ Deno 标准库 (deno/std) │
├─────────────────────────────────────────┤
│ Deno Runtime API (全局 Deno 对象) │
├──────────────────┬──────────────────────┤
│ Web APIs │ V8 引擎 │
│ (fetch, URL, │ (JavaScript 执行) │
│ WebSocket) │ │
├──────────────────┴──────────────────────┤
│ Rust 核心 │
│ (Tokio 异步运行时 / 权限系统 / 文件I/O) │
├─────────────────────────────────────────┤
│ 操作系统 │
└─────────────────────────────────────────┘
关键组件说明:
- V8 引擎:Google 的 JavaScript 引擎,与 Chrome 和 Node.js 相同
- Rust 核心:提供异步 I/O、权限检查、网络等底层能力
- Tokio:Rust 的异步运行时,提供高性能异步 I/O
- Web APIs:遵循 WHATWG/W3C 标准实现
1.5 适用场景
✅ 非常适合使用 Deno 的场景
| 场景 | 原因 |
|---|---|
| 新项目 | 无历史包袱,可直接享受现代化特性 |
| TypeScript 优先的项目 | 原生支持,零配置 |
| 边缘计算/Serverless | 快速启动、单文件编译、Deno Deploy |
| 安全敏感的应用 | 沙箱权限模型 |
| 脚本和自动化工具 | 直接运行,无需构建步骤 |
| Fresh 全栈应用 | 官方框架,SSR + 岛屿架构 |
| API 服务器 | 原生 HTTP 服务器、Web 标准 API |
| CLI 工具 | 单文件编译分发 |
⚠️ 慎重考虑的场景
| 场景 | 原因 |
|---|---|
| 依赖大量 Node.js 专属包 | 虽然 Deno 2.0 兼容 npm,但部分原生模块仍有问题 |
| Electron 桌面应用 | 生态尚未成熟 |
| 已有大型 Node.js 项目迁移 | 迁移成本可能较高 |
| 需要特定 Node.js 原生模块 | 如 node-canvas、sharp 等需要额外适配 |
🏢 业务场景示例
场景 1:SaaS 平台的 API 服务
→ Deno + Hono/Fresh + Drizzle + PostgreSQL
→ 安全权限模型 + TypeScript 原生 + 部署到 Deno Deploy
场景 2:内部自动化脚本
→ 直接运行 .ts 文件,无需构建步骤
→ 使用 --allow-read/write 精细控制权限
场景 3:边缘计算函数
→ Deno Deploy 全球分发
→ 冷启动快,单文件编译
场景 4:实时 WebSocket 应用
→ Deno 原生 WebSocket API
→ 高并发、低延迟
1.6 Deno 的发展现状
Deno 2.0 的重要改进
2024 年发布的 Deno 2.0 标志着一个重要的里程碑:
| 改进 | 说明 |
|---|---|
| npm 兼容性 | 大幅提升,可直接使用绝大多数 npm 包 |
| package.json 支持 | 可选使用,与现有生态无缝对接 |
| Node.js API 兼容 | node:fs、node:path 等内置支持 |
| 性能提升 | 启动速度、运行性能全面优化 |
| 稳定性 | API 稳定性承诺 |
JSR(JavaScript Registry)
Deno 团队推出了 JSR —— 一个现代化的 JavaScript/TypeScript 包注册中心:
// 从 JSR 导入包
import { encodeBase64 } from "@std/encoding/base64";
// 不同于 npm,JSR 原生支持 TypeScript
JSR 的特点:
- 原生 TypeScript 支持(无需预编译)
- 自动生成类型文档
- 支持多运行时(Deno、Node.js、Bun、浏览器)
- 基于 ESM(ES Modules)
1.7 本章小结
| 要点 | 说明 |
|---|---|
| Deno 是什么 | 现代 JavaScript/TypeScript 运行时 |
| 谁创建的 | Node.js 之父 Ryan Dahl |
| 核心优势 | 安全、原生 TS、Web 标准、单文件编译 |
| 与 Node.js 的关系 | 不是替代,而是补充和演进 |
| 适合场景 | 新项目、TS 项目、安全敏感、边缘计算 |
📖 扩展阅读
下一章:第 02 章:安装与环境配置 → 学习如何安装 Deno、管理版本以及配置开发环境。