5月27日 20:14

如何使用 deno compile 编译可执行文件?

什么是 deno compile?

deno compile 是 Deno 内置的编译工具,能把 TypeScript/JavaScript 代码连同运行时一起打包成独立可执行文件。目标机器不需要安装 Deno,直接运行即可。它的底层原理是把代码和依赖绑定为 eszip 格式,再注入到精简版 Deno 运行时(denort)二进制中——所以它并不是真正编译成机器码,而是"打包+嵌入"。

基本编译命令

bash
deno compile --allow-net --allow-read app.ts

编译时必须指定权限标志,运行时无法再修改。输出文件默认与源文件同名,可用 --output 自定义:

bash
deno compile --allow-net --output=myapp app.ts

交叉编译与目标平台

一条命令即可编译到其他平台:

bash
deno 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 显式声明:

bash
deno compile --include=./plugins/plugin.ts app.ts

Web Worker 的代码同理,也需 --include 手动加入。

权限编译时锁定。 --allow-net 等标志在编译时写死,运行时无法突破,也无法降级。这意味着如果将来需要新权限,必须重新编译。

deno compile 与 Node.js 打包工具对比

维度deno compilepkg (Node)nexe (Node)
配置复杂度零配置,一条命令需要 package.json 和配置需要配置和构建脚本
跨平台编译原生支持 --target有限支持有限支持
产物体积50-100 MB40-80 MB40-70 MB
维护状态Deno 官方维护社区维护,更新慢社区维护,更新慢

deno compile 的核心优势不在体积,而在于零配置和官方长期维护。

面试追问方向

  • deno compile 的产物为什么体积大?能否压缩?——因为嵌入了 V8 和 denort,upx 可压缩但有兼容风险。
  • 动态导入的模块为什么不会被打包?如何解决?——编译器只做静态分析,运行时才能确定路径的 import 会被跳过,用 --include 显式包含。
  • 编译时锁定的权限是否意味着安全性更强?——是,但也丧失了灵活性,需根据场景取舍。
标签:Deno