Skip to content

esbuild与vite

元信息

  • 目标:理解构建提速的两条路线——esbuild 换语言(Go 原生并行)、Vite 换策略(开发期不打包、按需编译);能说清 gulp→webpack→esbuild→Vite 四代工具各自回应的痛点
  • 关键概念:esbuild、Vite、原生并行、按需编译、依赖预构建、HMR
  • 关联阶段:cp3
  • 常见误区:以为 Vite 开发快是因为打包更快(开发期根本不打包,靠原生 ESM 按需加载);以为 esbuild 是 Vite 的替代品(esbuild 是引擎,Vite 用它做依赖预构建);以为生产构建也被 Vite 省掉了(生产仍用 Rollup 打包,上百个原生 ESM 请求反而慢)

问题:构建为什么慢?

打包工具 webpack 时代的开发体验痛点:每次启动都要先把整个项目打包完,项目越大,等待越久;改一行代码,热更新也要等模块链重新走一遍。根因在于 JavaScript 单线程——打包器的每一个解析、转换、拼接步骤都挤在一条线程上排队。

出路有两条,本篇两个工具各代表一条:

  • 换语言:esbuild 用 Go 重写打包器,编译为原生机器码,天然并行
  • 换策略:Vite 在开发期干脆不打包,直接利用浏览器的原生 ESM 按需加载

esbuild:用 Go 重写构建

https://esbuild.github.io/ — 用 Go 编写的极快打包/压缩工具。速度优势来自工程选择而非魔法:

  • 编译为原生机器码执行,而非解释执行 JS
  • 解析、打包、压缩、生成 sourcemap 全部并行化,充分利用多核
  • 数据结构为速度量身定制,尽量减少内存分配与遍历次数
  • 从头到尾只访存一遍代码,中间结果不落盘

通常比 webpack 等同类工具快 10~100 倍。代价是功能克制:热更新、代码分割的灵活性等留待上层工具补足。因此 esbuild 的常见身份不是你的直接工具,而是别人工具箱里的引擎——Vite 的依赖预构建用的就是它。

bash
esbuild app.js --bundle --outfile=out.js --minify   # 一条命令完成打包+压缩

Vite:不打包的开发服务器

https://vitejs.cn/(官方 https://vite.dev/)— 由 Vue 作者 Evan You 创建的新一代构建工具。核心洞察:开发期不需要打包,生产期才需要

  • 开发期:启动一个 dev server,浏览器请求哪个模块就实时转换哪个模块(按需编译)。启动几乎是即时的,因为"打包"这一步根本不存在;模块热更新(HMR)只替换改动的那个模块,与项目大小无关
  • 依赖预构建:node_modules 里的第三方包(ESM 形态参差)用 esbuild 一次性预打包,之后作为缓存静候——快而不乱
  • 生产期:用 Rollup 打包,输出高度优化的静态资源(社区正以 Rust 重写的 Rolldown 替换 Rollup,思路不变:生产必须打包,因为上百个原生 ESM 请求反而更慢)
  • 开箱即用的 TypeScript、JSX、CSS 预处理器支持,插件 API 兼容 Rollup 生态
bash
npm create vite@latest my-app   # 选 vanilla/javascript,几秒即得一个工程化项目
cd my-app && npm run dev        # 即时启动 dev server

四代工具一张表

gulpwebpackesbuildVite
年代2013201220202020
语言JSJSGoJS(引擎用 esbuild/Rollup)
定位任务流自动化一切资源皆模块极速打包/压缩引擎开发服务器 + 构建编排
开发期启动全量打包后才可用即时(按需编译)
现状历史地位仍广泛服役作为底层引擎现代项目默认起点

一句话谱系:gulp 解决"重复劳动",webpack 解决"依赖打包",esbuild 解决"打包速度",Vite 重新划分"开发不打包、生产才打包"——每次都是对上一代痛点的直接回答。

扩展阅读