你以为 Deno 只是 Node.js 的竞品?今天它用 esbuild 把这件事彻底变了

做过前端工程化的都知道:运行时声称自己能解决构建问题,一般就是在说大话。2022 年 Deno 删掉了 deno bundle,当时给的理由是「JavaScript 打包太复杂了,我们觉得自己做不好」。这个决定在当时被很多人吐槽——一个 JavaScript 运行时,不解决打包问题,那和浏览器有什么区别?

四年过去了。2026 年 7 月 Deno 2.4 发布,deno bundle 回来了。这次 Deno 没有声称自己造了个新引擎,而是在官方博客里直说:「JavaScript bundling is an incredibly complex problem, and we did not believe we could build deno bundle properly. Now that deno bundle uses esbuild under the hood, it is here to stay.」——我们以前觉得自己做不好,现在委托给 esbuild 了,所以这个功能留得住。

这句话放到任何工程团队里都需要勇气。承认自己的边界,比假装全能要难得多。

实际用起来什么样

回到技术层面。deno bundle 现在的工作方式很直接:底层跑 esbuild,给你套一层统一入口。

# 打包一个 TS/JS 文件
deno bundle main.ts --output bundle.js

# 打包 React 页面,target browser
deno bundle --platform=browser app.jsx -o bundle.js

# 开启 minify + sourcemap
deno bundle --minify --sourcemap app.ts -o app.bundle.js

输出的产物支持 tree shaking、代码分割、ESM 格式,npm 和 JSR 依赖都能解析。和直接用 esbuild 的区别是:你不需要单独装 esbuild,也不需要写配置文件,运行时自带。

--unstable-raw-imports:把非 JS 文件拽进模块图

另一个有意思的更新是 --unstable-raw-imports。这个 flag 让你直接在 JS/TS 里 import 图片、文本、字节文件:

import message from "./hello.txt" with { type: "text" };
import bytes from "./icon.png" with { type: "bytes" };

console.log("Message:", message);
Deno.serve((_req) => {
  return new Response(bytes, {
    headers: { "Content-Type": "image/png" },
  });
});

以前要读这类文件,得在运行时调用 Deno.readFileSync(),还得自己处理文件路径解析和产物部署问题。现在这些文件直接进了模块图,配合 deno bundle 打包成一个自包含产物。deno compile 也能把资源文件直接嵌进二进制里。

这个功能目前是 --unstable 状态,但已经可以在生产环境里做渐进增强。

Deno 在工具链上的务实姿态

Deno 2.4 的真正信息量不在某个新 API,而在这个技术决策本身:

  • 不重复造轮子:把打包这件事委托给 esbuild,而不是自己从零实现一个兼容层
  • 边界清晰:「我们做不好 bundling,所以我们不用假装做得好」——这是工程上的成熟
  • 工具链整合:不再把运行时和打包工具割裂,而是让用户在一个 CLI 里完成从开发到产物的全流程

这个思路其实和当年 Deno 决定内置 TypeScript 支持的逻辑一致:有些东西不用你操心,运行时帮你处理。但这里 Deno 往前走了一步——它承认某些事自己不擅长,并且主动引入了更合适的外部工具。

对于已经在用 Deno 的团队来说,deno bundle 的回归让完整的构建链路第一次在 Deno 生态里真正闭环:写代码 deno run 调试,deno bundle 打包产物,deno compile 编译成单一可执行文件,三步不需要切换工具链。

怎么上手

# 升级到 2.4
deno upgrade

# 基本打包
deno bundle main.ts --output bundle.js

# 打包 React 应用
deno bundle --platform=browser app.jsx -o app.js

# 带资源文件的打包(需开启 raw-imports)
deno bundle --unstable-raw-imports main.ts -o bundle.js

Deno 2.4 还顺手稳定了内置 OpenTelemetry 支持、增加了 deno update 简化依赖管理、--preload 让你在主脚本运行前先执行初始化代码。如果你在找一个能同时覆盖开发、测试、打包、编译的零配置工具链,Deno 现在给出的答案比四年前完整得多。

评论区

0 条评论

登录后可评论。

阿柯·前端架构 13 阅读