22.04-Deno部署

要点

  • Deno 是 Node.js 的「安全版替代」,原生 TypeScript、权限控制、标准库
  • Hono 对 Deno 有完整支持
  • Deno Deploy 是官方的边缘部署平台,类似 Cloudflare Workers
  • Deno 的生态比 Node.js/Bun 小,但在特定场景有独特优势

内容

1. Deno 是什么

Deno 是 Node.js 的创造者 Ryan Dahl 做的「重新设计版」,解决了他认为 Node.js 的几个问题:

特性Node.jsDeno
引擎V8V8
TypeScript需要编译原生支持
安全无权限控制有权限控制
URL 导入不支持支持(import from "https://..."
标准库需要 npm内置 @std/
包管理npm/pnpmdeno install
锁文件package-lock.jsondeno.lock

2. Hono 在 Deno 上跑

// src/index.ts
import { Hono } from 'jsr:@hono/hono'
 
const app = new Hono()
 
app.get('/', (c) => c.text('Hello Hono on Deno!'))
app.get('/api/users', (c) => c.json({ users: [] }))
 
Deno.serve({ port: 3000 }, app.fetch)

运行:

// terminal
deno run --allow-net src/index.ts

Deno 的权限控制需要你显式授权:--allow-net 允许网络访问。如果不加,代码无法发起 HTTP 请求。

3. Deno 的权限系统

Deno 默认禁止所有权限,需要显式开启:

// terminal
# 只允许网络访问
deno run --allow-net src/index.ts
 
# 允许网络和文件读取
deno run --allow-net --allow-read src/index.ts
 
# 允许所有权限(不推荐,但开发时方便)
deno run -A src/index.ts
 
# 限制网络访问到特定域名
deno run --allow-net=api.example.com src/index.ts

权限列表:

权限标志说明
网络--allow-netHTTP 请求、WebSocket
文件读取--allow-read读文件
文件写入--allow-write写文件
环境变量--allow-env读取 env
运行子进程--allow-run执行命令
所有-A全部允许

这个设计比 Node.js 安全——恶意包无法在没有授权的情况下访问你的文件或网络。

4. Deno Deploy

Deno Deploy 是 Deno 官方的边缘部署平台,类似 Cloudflare Workers:

// terminal
# 安装 deployctl
deno install -Arf jsr:@deno/deployctl
 
# 部署
deployctl deploy --project=my-api src/index.ts

Deno Deploy 的特点:

  1. 全球边缘网络:类似 Workers,代码部署到全球节点
  2. 原生 TypeScript:直接部署 .ts 文件,不需要编译
  3. Git 集成:push 到 GitHub 自动部署
  4. KV 和 Postgres:内置 KV 存储和 Postgres 数据库

4.1 Deploy 的限制

维度免费额度付费版
请求数100 万次/月按量计费
内存128 MB可调整
CPU 时间10 ms/请求可调整
运行时长5 分钟可调整
区域全球边缘全球边缘

5. Deno 的包管理

Deno 的包管理和 Node.js 完全不同:

// 从 URL 导入
import { Hono } from 'jsr:@hono/hono'
 
// 从 npm 导入(Deno 兼容 npm)
import express from 'npm:express'
 
// 从 deno.land/x 导入
import { serve } from 'https://deno.land/std/http/server.ts'

deno.json 是 Deno 的配置文件(类似 package.json):

{
  "tasks": {
    "dev": "deno run --watch --allow-net src/index.ts",
    "start": "deno run --allow-net src/index.ts"
  },
  "imports": {
    "@hono/hono": "jsr:@hono/hono@^4.0.0",
    "@std/path": "jsr:@std/path@^1.0.0"
  }
}

imports 字段定义导入映射,代码里可以用短名字:

// 用 imports 映射的短名字
import { Hono } from '@hono/hono'

6. 传统服务器部署

如果不用 Deno Deploy,也可以在传统服务器上跑 Deno:

// terminal
# 安装 Deno
curl -fsSL https://deno.land/install.sh | sh
 
# 运行
deno run --allow-net src/index.ts
 
# 编译成可执行文件
deno compile --allow-net --output my-api src/index.ts
 
# 运行编译后的文件
./my-api

deno compile 会把代码和 Deno 运行时打包成一个独立可执行文件,部署时不需要安装 Deno。

7. Docker 部署

# Dockerfile
FROM denoland/deno:1.45
 
WORKDIR /app
COPY deno.json deno.lock ./
RUN deno install
 
COPY . .
 
EXPOSE 3000
CMD ["deno", "run", "--allow-net", "src/index.ts"]

8. 和 Node.js/Bun 的对比

维度Node.jsBunDeno
生态最大(npm)兼容 npm较小(jsr + npm 兼容)
TypeScript需要编译原生支持原生支持
安全无权限控制无权限控制有权限控制
边缘平台无官方无官方Deno Deploy
包管理npm/pnpmbundeno install
标准库@std/

Deno 的独特优势:

  1. 权限系统:更安全,适合运行不受信任的代码
  2. Deno Deploy:官方的边缘平台,和 Workers 竞争
  3. 原生 TypeScript:不需要配置 tsconfig
  4. 标准库:统一的官方标准库

Deno 的劣势:

  1. 生态较小:虽然兼容 npm,但部分包有兼容性问题
  2. 社区较小:遇到问题时解决方案比 Node.js 少
  3. API 不稳定:还在快速迭代

9. 适用场景

Deno 适合:

  1. 新项目且团队认同 Deno 理念
  2. 需要权限控制的场景
  3. 想用 Deno Deploy 作为边缘平台
  4. 脚本和工具开发

不太适合:

  1. 依赖大量 Node.js 原生模块的项目
  2. 需要极致生态兼容性的项目
  3. 团队已经熟悉 Node.js 的项目

10. 小结

Deno 部署的核心:

  1. Hono 支持 Deno,用 jsr:@hono/hono 导入
  2. Deno Deploy 是官方边缘平台,类似 Workers
  3. 权限系统是 Deno 的独特优势
  4. 原生 TypeScript,不需要编译配置
  5. 包管理用 deno.json,和 npm 生态兼容但有差异

Deno 是一个有趣的选择,但生态和社区规模不如 Node.js。选择 Deno 需要评估团队对它的接受度和项目的兼容性需求。