今天很多人一提到前端工程化,第一反应往往都差不多:

  • 配置很重
  • 工具很多
  • 构建链很长
  • dev server、热更新、lint、测试、打包、部署全都绕不开

于是很容易得出一种结论:

前端天生就是复杂的。

可如果你把时间线拉长一点,就会发现这件事其实非常怪。

因为最早的前端根本不长这样。

它最开始可以简单到:

  • 几个 <script> 标签
  • 一点 CSS
  • 几段页面交互

那为什么后来会一步步长成今天这种样子?

为什么写个前端项目,到最后会自然带出一整套:

  • bundler
  • transpiler
  • dev server
  • HMR
  • 代码分割
  • 静态资源处理
  • 类型检查
  • 发布产物策略

这套 《前端工程化江湖》,想讲的就是这些事。

它不是工具选型指南。

也不是“十分钟看懂 webpack / Vite / Babel 区别”的速食说明书。

它更像一部压力史。

一种特别典型的前端压力史:

平台原生能力不够、应用规模一路变大、交付要求越来越高,于是社区只能不断把原本不属于浏览器开发者日常的那部分复杂度,一层层接到自己身上。

你可以先把这套系列记成五幕:

  1. 最早的前端几乎没有“构建”概念,更多只是脚本拼接与静态资源摆放。
  2. 当项目开始变大,GruntGulp 这类 task runner 先把重复劳动流水线化。
  3. 当模块制度、依赖图和大型应用一起爆炸,webpack 这类 bundler 开始变成真正的总协调系统。
  4. 当语言演化速度快过运行时落地速度,Babel 又把“先写未来、再编译回现在”变成前端默认工作流。
  5. 当 bundle-based 开发体验本身开始变重,RollupSnowpackVite 这类新路线又开始反攻。

这五幕一连起来,你就会发现,这套系列真正想讲的,不是“哪些工具后来流行了”。

而是另一件更大的事:

前端工程化的历史,不是一群开发者无聊发明复杂工具的历史,而是网页应用化之后,浏览器原生能力、模块现实、性能要求和团队交付压力一起把前端逼成了一整套工程机器的历史。


这套系列讲什么

我想讲的,不只是“GruntwebpackBabelVite 各自做什么”。

更想讲的是底下那几场反复重演的冲突:

  • 为什么最早的前端几乎不需要工程化,而后来却越来越离不开它
  • 为什么 task runner 先火,但最后又不够
  • 为什么 bundler 会从“打包工具”长成几乎统治整个前端构建现实的中枢
  • 为什么 Babel 会和 bundler 紧紧绑在一起,变成现代前端的默认基础设施
  • 为什么 Vite 这类新路线会被很多人看成“对重型前端工程机器的一次反攻”

换句话说,这是一套关于 浏览器原生能力边界、前端交付复杂度、工具链权力演化,以及现代开发体验如何被工程化建出来 的系列文章。


这套系列真正要追的,不是工具名,是压力传导

如果你退一步看,会发现前端工程化这些年的很多变化,表面上像工具换代,底下其实一直在重复几类更硬的问题。

01|平台原生能力够不够

前端工程化最底下的一层矛盾其实非常朴素:

浏览器原生能力,够不够支撑大型应用的开发和交付。

最早的时候,这个问题不尖锐。

因为前端代码不大,页面也没那么像应用。

可一旦事情变重,问题就会迅速冒出来:

  • 模块要不要原生支持
  • 新语法能不能马上跑
  • 静态资源怎么管理
  • 代码拆分和按需加载怎么办

如果原生能力不够,社区就只能补。

一补,就会长出工具。

所以这套系列里一个最重要的问题就是:

前端工程化,到底有多少是“开发者想要更爽”,又有多少是“平台实在没给够”。

02|重复劳动能不能先被流水线化

很多早期工程工具一开始其实不浪漫。

它们最先解决的常常不是“架构理想”。

而是很俗的问题:

  • 文件要不要拼接
  • Sass 要不要编译
  • 图片要不要处理
  • 代码要不要压缩
  • 发布前一串命令能不能别手工敲

所以 GruntGulp 这类工具之所以会先火,

本质上不是因为它们代表未来哲学。

而是因为它们先把前端日常里的重复劳动做成了流水线。

这里面一个很重要的问题就是:

前端工程化一开始,先解决的到底是不是“软件工程高级问题”,还是“别再手工做脏活累活”。

03|构建工具到底是在服务代码,还是在重新定义应用

等到 bundler 时代,这个问题就会更尖锐。

因为 webpack 这类工具后来已经不只是“帮你处理代码”。

它们开始参与定义:

  • 什么算模块
  • 什么算资源
  • 什么进初始包
  • 什么按需加载
  • 什么构成一份最终可交付应用

到这一步,工具链就不只是辅助。

它开始反过来塑造开发者怎么理解项目。

所以这套系列会反复追问:

前端工程化工具,到底是在服务应用,还是越来越像应用本身的解释器。

04|写代码的现实版本,到底是浏览器版本,还是工具链版本

Babel 之后,这件事又进一步变了。

因为从那以后,很多前端开发者真正日常写的 JavaScript,其实已经不是“浏览器今天原生能跑的 JavaScript”。

而是:

工具链先帮你翻译过的未来 JavaScript。

这会带来非常大的后果。

因为它意味着开发体验的现实,越来越不直接等于运行时现实。

中间隔着:

  • 编译
  • 目标环境配置
  • polyfill
  • preset / plugin

所以这套系列里还有一个很重要的问题:

现代前端写的代码,到底是在直接面向浏览器写,还是在面向工具链构造出的“理想运行时”写。

05|工程化为什么总会一边解决问题,一边把自己变成新问题

这是前端工程化最典型、也最 JavaScript 的地方。

每一轮工具链升级,几乎都真的解决了旧问题。

但同时,它也往往会制造出新的重:

  • 配置负担
  • 学习成本
  • 生态分裂
  • 版本兼容地狱
  • 构建速度瓶颈

所以工程化史不是一条单向进步线。

它更像一种压力转移:

旧问题被工具解决后,复杂度并没有消失,而是被重新组织、重新命名、重新堆到另一层。

这也是为什么后面会有一轮又一轮“反工程化”或“轻量化反攻”。


为什么这条线特别值得单独拆出来

因为它几乎解释了今天前端开发者日常体感里的那种“重”。

你感觉项目重,往往并不是因为某个框架单独很重。

而是因为背后连着一整套工程压力:

  • 本地开发要快
  • 热更新要稳
  • 产物要小
  • 新语法要能用
  • 旧浏览器要兼容
  • 资源要统一处理
  • 构建要可重复
  • 团队协作要可预测

这些要求单看都合理。

可它们叠起来,就会自然把前端推向一整套复杂工具链。

所以前端工程化这条线真正值得写的,不是“哪个工具更流行”。

而是:

为什么在 Web 平台长期不肯一次性给足原生能力的前提下,前端社区只能不断自己搭脚手架、修道路、铺管线,最后把一门本来看起来很轻的页面开发,变成了高度工程化的交付体系。


这套系列准备怎么写

目前我更倾向于按五篇主线来写:

  1. 前端最早并不是工程化出来的,它只是慢慢被规模逼出构建需求
    先讲无构建时代、脚本拼接时代,以及为什么“前端不需要工程”这件事后来越来越站不住。

  2. Grunt / Gulp 为什么先火:前端第一次把脏活累活做成流水线
    讲 task runner 时代到底解决了什么,以及为什么后来又不够。

  3. webpack 为什么会一度成王:因为它不只是打包器,而是应用装配系统
    讲 dependency graph、chunk、loader、plugin 为什么让它变成总协调器。

  4. Babel 为什么和 bundler 绑成现代前端基建:因为前端开始默认“先写未来,再编译回现在”
    讲 Babel 不是补充品,而是现代开发体验的中枢之一。

  5. Rollup / Snowpack / Vite 为什么会代表反攻:前端终于开始反问,工程化自己是不是也太重了
    讲新一代工具为什么要反 bundle-based 开发时的重量,同时又没有真的离开工程化。

也就是说,这套系列想讲的,不只是“工具换代”。

更想讲:

为什么前端工程化最后没有变成一套稳定不动的工业标准,而是每当旧工具把复杂度吸得太重时,就会有新一代工具出来重新分配这份复杂度。


先记住这句

如果你现在只想先记住一句话,那就记这句:

前端不是天然复杂,而是在网页应用化之后,被模块化、兼容性、性能和交付效率这些现实压力,一步步逼成了一整套工程机器。

而且这套机器最特别的地方还在于:

它不是一次性搭好的。

它是一轮工具解决一轮问题,

然后再在新的瓶颈上逼出下一轮工具。

这就是前端工程化最典型的历史节奏。

不是突然工业化。

而是:

旧压力刚被驯服,新压力立刻又把工具链往更深一层推。


先记住:前端不是爱造工具,而是被现实逼着发明流水线

所以这套 《前端工程化江湖》 真正想讲的,不是“前端为什么这么爱折腾工具”。

更想讲的是:

为什么一个本来只是负责页面表现和交互的开发领域,最后会被逼到不得不自己发明编译器、打包器、开发服务器、热更新机制和一整套交付流水线。

如果把 JavaScript 江湖 写的是语言如何一路被推成平台语言,

模块化江湖 写的是大家如何为“代码怎么组织”狠狠干起来,

前端工程化江湖 要写的,就是:

当语言和模块制度都不再够用之后,前端社区如何把“写页面”这件事,硬生生扩建成一整座工程基础设施的过程。


关键人物速览

  • Ben AlmanGrunt 的发起者。理解前端为什么会先从“自动化重复劳动”开始工程化,绕不开他。
  • Eric SchoffstallGulp 的早期发起者之一。理解前端流水线为什么会从“配置驱动”转向“代码驱动”,他这条线很典型。
  • Tobias Kopperswebpack 的发起者。理解 bundler 为什么会从工具长成前端应用装配系统,绕不开他。
  • Sebastian McKenzieBabel 的发起者。理解为什么现代前端会把“先写未来,再编译回现在”当成默认现实,绕不开他。
  • Evan YouVite 的发起者。理解新一代前端工具为什么会开始系统性反击重型 dev bundling,这条线离不开他。

参考与延伸阅读

  1. Grunt: The JavaScript Task Runner
    https://gruntjs.com/

  2. gulp.js
    https://gulpjs.com/

  3. Why webpack
    https://webpack.js.org/concepts/why-webpack/

  4. webpack: Under The Hood
    https://webpack.js.org/concepts/under-the-hood/

  5. Babel 6.0.0 Released
    https://babeljs.io/blog/2015/10/29/6.0.0

  6. The State of Babel
    https://babeljs.io/blog/2016/12/07/the-state-of-babel

  7. Frequently Asked Questions | Rollup
    https://rollupjs.org/faqs/

  8. How Snowpack Works
    https://www.snowpack.dev/concepts/how-snowpack-works

  9. Why Vite
    https://vite.dev/guide/why