编译为单文件可执行程序
用 deno compile 分发单文件应用,掌握交叉编译、资源嵌入与选型边界
deno compile 把入口模块图与精简运行时 denort 打成一个自包含可执行文件,目标机器不需要安装 Deno。
基本用法
deno compile --output=server main.ts
./server
产物是一个与平台绑定的二进制文件。运行时参数必须在编译时声明,包括权限:
deno compile --allow-net --allow-env=PORT --output=server main.ts
交叉编译
--target 可从任意主机平台交叉编译。当前支持五个目标三元组:
| 目标 | 平台 |
|---|---|
x86_64-pc-windows-msvc | Windows x86_64 |
x86_64-apple-darwin | macOS x86_64 |
aarch64-apple-darwin | macOS ARM64 |
x86_64-unknown-linux-gnu | Linux x86_64 |
aarch64-unknown-linux-gnu | Linux ARM64 |
deno compile --target=aarch64-unknown-linux-gnu --output=server-linux-arm64 main.ts
对应目标的 denort 会下载到 DENO_DIR 缓存。交叉产物必须在目标平台真实启动一次,不要只验证“编译通过”。
嵌入资源
自 Deno 2.1 起,--include 可把文件或目录嵌进二进制,并通过 import.meta 相对路径读取:
deno compile --include=./data --include=worker.ts main.ts
const csv = await Deno.readTextFile(import.meta.dirname + "/data/names.csv");
--include可多次传入;只支持本地文件,远程模块无法嵌入。- 被嵌入的
.js/.ts会作为模块图根参与解析;预构建的前端产物用--include-as-is原样嵌入,避免被再次转译。 deno.json的compile块可声明include/exclude数组,与 CLI 标志合并。- 默认嵌入整个已解析的
node_modules;实验性的--exclude-unused-npm只嵌入可达的 npm 包。
与 Docker / Deploy 的边界
| 场景 | 优先方案 |
|---|---|
| 分发 CLI 工具、单文件后台程序 | deno compile |
| 服务需要系统库、CA、shell 或多个进程协作 | Docker 与容器 |
| HTTP 服务需要托管 TLS、多区域部署与自动扩缩 | Deno Deploy |
deno compile 解决“分发形态”,不解决进程管理、滚动升级或证书。服务长期运行仍需要 systemd、容器编排或托管平台。
已知局限
- 动态导入只有字符串字面量会被静态纳入;计算出的 specifier 需要
--include显式带上。 - Worker 代码默认不进产物,用
--include或静态import "./worker.ts"引入。 - 原生插件(FFI、
.node加载项)依赖自解压模式,首次运行更慢且占用额外磁盘;按目标平台逐一验证。 - 二进制与 Deno 版本绑定,运行时升级需要重新编译分发。
官方参考:deno compile。