5月27日 20:14
如何使用 deno compile 编译可执行文件?
什么是 deno compile?
deno compile 是 Deno 内置的编译工具,能把 TypeScript/JavaScript 代码连同运行时一起打包成独立可执行文件。目标机器不需要安装 Deno,直接运行即可。它的底层原理是把代码和依赖绑定为 eszip 格式,再注入到精简版 Deno 运行时(denort)二进制中——所以它并不是真正编译成机器码,而是"打包+嵌入"。
基本编译命令
bashdeno compile --allow-net --allow-read app.ts
编译时必须指定权限标志,运行时无法再修改。输出文件默认与源文件同名,可用 --output 自定义:
bashdeno compile --allow-net --output=myapp app.ts
交叉编译与目标平台
一条命令即可编译到其他平台:
bashdeno compile --target=x86_64-unknown-linux-gnu --output=myapp-linux app.ts deno compile --target=aarch64-apple-darwin --output=myapp-mac app.ts deno compile --target=x86_64-pc-windows-msvc --output=myapp.exe app.ts
这在 CI/CD 中做批量发布时很实用,不用准备多台构建机器。
三个注意事项
文件体积大。 编译产物通常 50-100 MB,因为包含了完整 V8 引擎和 Deno 运行时。对体积敏感的场景可用 upx 压缩,但稳定性需自行验证。
动态导入不会自动打包。 静态分析能识别的动态 import 会被包含,但运行时拼装的路径不会。需要用 --include 显式声明:
bashdeno compile --include=./plugins/plugin.ts app.ts
Web Worker 的代码同理,也需 --include 手动加入。
权限编译时锁定。 --allow-net 等标志在编译时写死,运行时无法突破,也无法降级。这意味着如果将来需要新权限,必须重新编译。
deno compile 与 Node.js 打包工具对比
| 维度 | deno compile | pkg (Node) | nexe (Node) |
|---|---|---|---|
| 配置复杂度 | 零配置,一条命令 | 需要 package.json 和配置 | 需要配置和构建脚本 |
| 跨平台编译 | 原生支持 --target | 有限支持 | 有限支持 |
| 产物体积 | 50-100 MB | 40-80 MB | 40-70 MB |
| 维护状态 | Deno 官方维护 | 社区维护,更新慢 | 社区维护,更新慢 |
deno compile 的核心优势不在体积,而在于零配置和官方长期维护。
面试追问方向
- deno compile 的产物为什么体积大?能否压缩?——因为嵌入了 V8 和 denort,upx 可压缩但有兼容风险。
- 动态导入的模块为什么不会被打包?如何解决?——编译器只做静态分析,运行时才能确定路径的 import 会被跳过,用
--include显式包含。 - 编译时锁定的权限是否意味着安全性更强?——是,但也丧失了灵活性,需根据场景取舍。