前端构建工具 (build tool) 是什么? 为什么要用?

2025年11月2日

💎 加入 E+ 成長計畫 與超過 750+ 位工程師一同在社群成長,並獲得更多深度的軟體前後端學習資源

对现代前端开发来说,构建工具 (build tool) 是相当重要的一个要素。从过去常听到的 Webpack,到后来窜起的 Vite,都是构建工具,但这类工具究竟在做什么?

要迈向资深前端工程师,不能只会写代码,还需要对各类工具有足够掌握,而构建工具就是其中需要掌握的。因此,在这篇文章,我们要来谈什么是构建工具、为什么要用构建工具,以及具体来说构建工具做了什么。

构建工具是什么?与打包工具有什么区别?

在最开始,想先区分比较容易搞混的两个名词,一个是这篇文章会着重的构建工具 (build tool),另一个是大家可能也很常听到的打包工具 (bundler)。

这两个词之所以容易搞混,是因为在社群中颇热门的 Webpack,最早从打包工具起家,后来逐渐进化成构建工具,所以 Webpack 在某些语境会被叫打包工具,在另一些语境被叫构建工具,可能让人感到困惑。

另外,社群中也很热门的 esbuild,名字当中有一个 build,但其本质更贴近打包工具。事实上,esbuild 官网上的副标题就是 An extremely fast bundler for the web(一个为网页而生的极速打包工具)。

所以构建工具与打包工具的区别究竟是什么?

构建工具是完整的工具箱

如果用比喻来说,构建工具就像一个完整的工具箱,里面有各类不同的工具,而其中之一就是打包工具。 以目前社群中最热门的构建工具 Vite 来说,Vite 本身会做很多事情,其中的打包则是透过 esbuild 与 Rollup 来处理(未来会改由 Rolldown 处理)。

具体来说,打包工具在做的,是把多个不同的文件打包成最终要被使用的产物。以目前社群最热门的 React 来说,在一个大型的 React 代码库,可能有上千个组件与近百个页面;但当用户进入某个页面时,并不需要整个代码库的所有代码。打包工具所做的,就是把这些上千个不同的文件整理成少数几个优化后的包,让用户进入页面后,浏览器只需下载那几份优化过的文件。

打包工具会透过 tree shaking 把冗余的代码移除。例如,代码库里可能有些代码明明没被用,但维护者没有删掉;如果没有处理,就会白白占空间。与此同时,打包工具也会做代码分割 (code splitting),让某个页面只加载它会用到的代码,避免让一堆不会用到的代码被浏览器下载。

因此,概略来看,打包就是先厘清众多原始代码之间的关系,然后去除不需要的代码(tree shaking),再把彼此相关的代码放在同一个包(代码分割),最后产出优化后的结果。

但是 构建工具除了打包之外,还会做更多事情。

以上面提到的 Vite 为例,除了做 Rollup 会处理的事项之外,还能透过插件在构建流程中完成其他任务。举例来说,如果希望在构建过程中自动优化项目里的图片,Rollup 本身并不会帮你做;但在 Vite 可以透过 vite-plugin-image-optimizer 插件(链接)来压缩图片,让页面加载更快。

又或者社群中另一款热门的构建工具 Rsbuild,除了会用 Rspack 来打包,还能搭配 Rsdoctor 分析构建产物,进一步协助团队优化性能;这些额外的分析,就是 Rspack 这个打包工具本身没有提供的。

构建工具可以开箱即用

除了提供额外功能外,现代前端构建工具在开发者体验 (DX) 上也带来了额外好处,其中最大的就是开箱即用。

在 Vite 成为最热门的构建工具之前,Webpack 曾经是社群中最热门的选择。前面提到 Webpack 起初以打包为主,不过由于它的 loader 设计,可以挂上各种功能,逐渐让 Webpack 成为一套完整的构建工具。

但 Webpack 之所以后来逐渐式微,而 Vite 能够崛起,关键除了 Vite 的性能更好之外,还有开箱即用的开发者体验。过去 Webpack 最让人诟病的,就是配置的上手门槛高;相对而言,Vite 将难配置的部分处理掉,让新手也能快速上手。

除了 Vite 之外,上面提到的 Rsbuild 之所以会被开发,是因为 Rspack 团队想确保 Rspack 这个打包工具的底层稳定性。但这意味着团队无法随着不同前端框架的演进去做大量修改,在这种前提下想让开发者开箱即用会有难度。

因此,Rspack 团队额外开发了 Rsbuild 这套构建工具,底层使用 Rspack,但在 Rsbuild 这一层处理了与各框架的对接,让不同框架的开发者无需烦恼配置问题,就能轻松开箱即用。

以上概略性介绍了构建工具与打包工具的不同。本文后半段会聚焦讨论构建工具;在这一系列的下一篇文章,则会更详细地谈打包工具。

前端代码一定要构建吗?

在基本了解构建工具在做什么之后,大家可能会产生一个问题,那就是“前端代码一定要构建吗?”

显然这个问题的答案是“不一定要”。举例来说,下面这个 HTML 文件中间带有一个 <script>,完全可以直接在浏览器运行。

<html>
  <head>
    <title>ExplainThis</title>
  </head>
  <body>
    <div id="root" />
    <script type="text/javascript">
      document.getElementById("root").innerText = "ExplainThis nicely!";
    </script>
  </body>
</html>

事实上,社群里仍有人主张不要使用构建工具,最有名的大概就是 Ruby on Rails 的作者 DHH。

https://x.com/dhh/status/1791909885120233946

在 DHH 的观点中,因为现代浏览器足够强大,即使不用构建工具,纯 HTML、CSS 搭配少量 JavaScript 也能开发出足够好的网页应用。与此同时,因为不需要构建工具,直接用最“香草”(vanilla) 的方式开发,部署时也免去了那些繁琐步骤,让流程变得简单轻松。

为什么现代前端仍然倾向构建?

如果不用构建也能在浏览器运行前端代码,且有 DHH 这样的主张,那为什么现代前端依旧朝构建的方向迈进,各类工具(例如 Webpack、Vite、Rspack)百花齐放?

最主要的原因是要兼顾开发者体验 (DX)。

什么意思呢?观察现在多数前端团队的开发方式,几乎不会仅使用香草的 HTML、CSS 与 JavaScript(DHH 的团队是非常特殊的例外)。

比如说,现代前端项目大多会选用框架(如 React/Next、Vue/Nuxt、Svelte/SvelteKit)。为了在开发阶段就先发现类型相关的问题,许多团队会使用 TypeScript。此外,为了在开发时不用手动刷新页面,多数团队会依赖热模块更新 (HMR):改完某段代码后立即看到结果。

但问题是,浏览器认识香草的 HTML、CSS 与 JavaScript,却无法直接执行 React 或 Vue 的代码,也不能直接运行 TypeScript。同时,即便退一步只写 JavaScript,许多旧版浏览器也不支持最新的 ECMAScript 语法。这意味着,如果想用更现代的语法来提升开发体验,代码在旧浏览器上就会出问题。

而前端构建工具,就是为了解决这些问题。通过构建流程,开发者写的 React/Vue、TypeScript、最新 ECMAScript 语法可以被转换成所有浏览器都能支援的代码。因此我们会说,构建工具之所以必要,是因为现代前端开发既要兼顾开发者体验,又要让产物能在浏览器顺利运行,构建工具正是连接两者的桥梁。

进一步来说,前面提到的 tree shaking、代码分割等方式,能让传到浏览器端的数据更少,不仅让传输速度更快,也让浏览器需要解析的代码更少,整体性能自然提升。

综上所述,无论从开发者体验或性能角度来看,构建工具都为现代前端项目带来了非常大的帮助,这也是为什么现代前端会持续朝构建工具的方向靠拢。

🧵 如果你想收到最即時的內容更新,可以在 FacebookInstagram 上追蹤我們