Nitro 部署到 Deno 运行时:deno_server 预设完整指南
【免费下载链接】nitroNext Generation Server Toolkit. Create web servers with everything you need and deploy them wherever you prefer.项目地址: https://gitcode.com/GitHub_Trending/ni/nitro
本文基于 Nitro 仓库(Next Generation Server Toolkit)的 Deno 运行时部署文档 展开,系统讲解如何将 Nitro 应用构建为可在 Deno 运行时上运行的自定义服务器。读完本文,你将掌握
deno_server预设的构建与启动命令、端口/主机/TLS 等运行环境变量、Node 内置模块兼容策略、WebSocket 与定时任务支持,以及向 Deno Deploy 平台发布应用的两条完整路径。
一、deno_server预设是什么
Nitro 支持通过「预设(Preset)」将同一份应用代码构建成面向不同运行时与平台的产物。文档明确给出面向 Deno 运行时使用的预设名称:
- Preset:
deno_server
该预设位于 src/presets/deno/preset.ts,其别名列表中包含deno(aliases: ["deno"]),因此你可以用deno_server或deno两种写法指定它。
从源码结构看,deno_server预设的核心配置包括:
| 配置项 | 取值 | 说明 |
|---|---|---|
entry | ./deno/runtime/deno-server | 指定 Deno 服务器运行时入口 |
serveStatic | true | 启用静态资源服务 |
exportConditions | ["deno"] | 打包时优先解析带deno导出条件的依赖 |
preview命令 | deno -A ./server/index.mjs | 预览生产构建结果 |
output.format | ESM | 产物为 ES Module 格式 |
二、构建与启动 Deno 生产服务器
文档给出了完整的构建与启动流程:
# 使用 Deno 预设构建 NITRO_PRESET=deno_server npm run build # 启动生产服务器 deno run --allow-net --allow-read --allow-env .output/server/index.mjs2.1 构建阶段发生了什么
执行NITRO_PRESET=deno_server npm run build后,Nitro 会将应用输出到.output目录,其中:
.output/server/index.mjs为最终服务器入口;.output/deno.json会被自动生成(见下文)。
在 Rollup 打包层面,deno_server 预设 会将三类模块声明为外部依赖,不参与打包:
- 以
https://开头的远程模块(Deno 原生支持从 URL 直接导入); - 以
node:开头的 Node 内置模块(Deno 提供原生node:兼容层); - Node 的
builtinModules(无前缀的内置模块名)。
同时开启hoistTransitiveImports: false,避免把间接依赖的导入提升到入口顶部,从而保证生成的 ESM 文件能被 Deno 直接执行。
2.2 自动生成的 deno.json
预设通过compiled钩子在构建完成后自动向.output目录写入一个deno.json配置文件,内容如下:
{ "tasks": { "start": "deno run -A ./server/index.mjs" } }这意味着构建完成后,你可以直接在.output目录下用 Deno 的任务系统启动服务器:
cd .output deno task startdeno-server 测试用例 正是使用deno task start启动被测服务器,并通过NITRO_PORT、NITRO_HOST环境变量将其绑定到随机端口与127.0.0.1上进行验证,说明这一启动方式是官方测试认可的推荐路径。
2.3 关于--allow-*权限参数
文档中的启动命令使用了三个权限标志:
--allow-net:允许网络访问(监听端口、发起 HTTP 请求);--allow-read:允许读取文件系统(静态资源、配置文件);--allow-env:允许读取环境变量(端口、主机、密钥等配置)。
你也可以使用-A(--allow-all)一次性授予全部权限,例如预设内置的预览与start任务都采用了deno run -A的写法。生产环境建议按最小权限原则显式声明所需权限。
三、运行时入口与运行环境变量
从 运行时入口实现 可以看到,Deno 服务器入口通过srvx的serve函数启动,并支持以下环境变量配置:
| 环境变量 | 作用 | 默认值 |
|---|---|---|
NITRO_PORT或PORT | 监听端口 | 3000 |
NITRO_HOST或HOST | 监听主机名 | 不设置(由运行时决定) |
NITRO_SSL_CERT | TLS 证书路径 | 无(不启用 TLS) |
NITRO_SSL_KEY | TLS 私钥路径 | 无(不启用 TLS) |
源码中的解析逻辑为:
const _parsedPort = Number.parseInt(process.env.NITRO_PORT ?? process.env.PORT ?? ""); const port = Number.isNaN(_parsedPort) ? 3000 : _parsedPort; const host = process.env.NITRO_HOST || process.env.HOST; const cert = process.env.NITRO_SSL_CERT; const key = process.env.NITRO_SSL_KEY;使用示例:
NITRO_PORT=8080 NITRO_HOST=0.0.0.0 deno run --allow-net --allow-read --allow-env .output/server/index.mjs当同时设置了NITRO_SSL_CERT与NITRO_SSL_KEY时,服务器会自动以 HTTPS 模式启动(tls: cert && key ? { cert, key } : undefined)。
四、Node 兼容性与 unenv 处理
Nitro 生态中有大量依赖 Node 内置模块的库,而 Deno 提供了原生node:兼容层。为此,Deno 预设的 unenv 配置 做了三件事:
- 外部化内置模块:将
node-compat.ts中列出的全部 Node 内置模块标记为external,交给 Deno 运行时处理; - 别名映射:对
node:fs/fs这类带前缀与不带前缀的写法建立别名,统一指向 Deno 的node:模块; - 全局注入:注入
process、setImmediate、clearImmediate、Buffer等 Node 全局对象,分别来自node:process、node:timers、node:buffer。
其中内置模块清单由 node-compat.ts 自动生成,来源为 Deno 官方平台兼容性数据,覆盖node:fs、node:http、node:crypto、node:stream等常见模块;同时标注了各模块缺失的导出(如node:fs缺少glob、fchmod等),并单独列出少数完全不受支持的模块(如node:_http_client、node:sea)。在选用 Deno 运行时之前,可对照此清单评估依赖的兼容性。
五、WebSocket、定时任务、追踪与优雅关闭
从 deno-server 入口 的代码路径可以看出,Deno 预设不止能跑普通 HTTP 服务,还完整接入了 Nitro 的以下运行时能力:
- WebSocket:通过
crossws/adapters/deno适配器处理Upgrade: websocket请求(仅在应用启用了 WebSocket 路由时激活); - 定时任务:通过
startScheduleRunner启动任务调度器(对应#nitro/runtime/task),支持waitUntil语义; - Tracing:注入
tracingSrvxPlugins插件,将追踪中间件接入请求生命周期(详见 docs/1.docs/50.tracing.md); - 优雅关闭:通过
setupCloseHooks注册关闭钩子; - 未处理错误兜底:
trapUnhandledErrors统一捕获未处理异常。
这意味着路由、中间件、插件、缓存、任务调度等 Nitro 功能在 Deno 运行时下均可正常使用,而不只是「能启动」。
六、部署到 Deno Deploy
文档将 Deno Deploy 的完整部署流程指向 Deno Deploy 平台指南,这里做核心要点提炼。
6.1 预设:deno_deploy
Deno Deploy 使用独立的deno_deploy预设(同样定义在 src/presets/deno/preset.ts),与本地服务器预设的区别在于:
- 入口为
./deno/runtime/deno-deploy,基于Deno.serve编写(见 运行时实现); - 产物入口文件名为
index.ts; - 将
DENO_DEPLOYMENT_ID环境变量注入部署清单(manifest),用于标记部署版本; - 内置部署命令:
deno run -A jsr:@deno/deployctl deploy server/index.ts。
6.2 使用 deployctl 部署
# 使用 deno_deploy 预设构建 NITRO_PRESET=deno_deploy npm run build # 在输出目录中执行部署 cd .output deployctl deploy --project=my-project server/index.ts部署前需要登录 Deno Deploy 获取DENO_DEPLOY_TOKEN访问令牌并设置为环境变量。
6.3 通过 GitHub Actions 持续部署
无需在 CI 中配置密钥,只需在 Deno Deploy 项目设置中选择「GitHub Actions」部署模式,并在仓库.github/workflows目录创建如下工作流:
name: deno-deploy on: push: branches: - main pull_request: branches: - main jobs: deploy: runs-on: ubuntu-latest steps: - uses: actions/checkout@v5 - run: corepack enable - uses: actions/setup-node@v6 with: node-version: 20 cache: pnpm - run: pnpm install - run: pnpm build env: NITRO_PRESET: deno_deploy - name: Deploy to Deno Deploy uses: denoland/deployctl@v1 with: project: my-project entrypoint: server/index.ts root: .output七、运行时自动检测
除了手动指定预设外,Nitro 还会根据运行环境自动选择预设。预设解析逻辑 中维护了{ deno: "deno", bun: "bun" }的运行时映射:当你在 Deno 运行时下启动 Nitro(例如在开发或预览阶段),且未显式指定预设时,Nitro 会通过std-env检测到deno运行时并自动解析到deno别名对应的deno_server预设。
小结
Nitro 对 Deno 的支持分为两个层次:deno_server预设用于在自托管 Deno 环境中运行生产服务器,deno_deploy预设用于发布到 Deno 云平台。两者共享同一套基于srvx的运行时基础,完整支持静态资源、WebSocket、定时任务、追踪与优雅关闭,并通过 unenv 与 Deno 原生node:兼容层平滑处理 Node 依赖。相关源码与测试可直接在仓库中继续深入研读:
- 预设定义:src/presets/deno/preset.ts
- 服务器运行时入口:src/presets/deno/runtime/deno-server.ts
- Deno Deploy 入口:src/presets/deno/runtime/deno-deploy.ts
- Node 兼容配置:src/presets/deno/unenv/preset.ts
- 兼容性测试:test/presets/deno-server.test.ts
- 平台部署文档:docs/2.deploy/20.providers/deno-deploy.md
【免费下载链接】nitroNext Generation Server Toolkit. Create web servers with everything you need and deploy them wherever you prefer.项目地址: https://gitcode.com/GitHub_Trending/ni/nitro
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考