01|如果说第三篇讲的是“谁来替应用做总装配”,那第四篇要讲的就是:谁来替未来语法先垫进今天
写到第三篇,其实前端工程化已经走到一个很有意思的位置。
webpack 这类系统开始接管:
- 模块图
- 资源图
- 分块策略
- 构建生命周期
也就是说,前端已经逐步拥有了一个能装配应用的大中枢。
可问题并没有到此结束。
因为应用装配只是其中一层。
更往下一层的问题是:
如果浏览器今天还不会你想写的语法,那这整套工程化装配能力又该服务什么语言现实?
这就是第四篇真正要讲的起点。
Babel 最重要的历史意义,不只是“把新语法转旧语法”。
更不是“兼容老浏览器的一个工具”。
它真正改变的,是另一件更深的事:
它第一次让前端工程化可以大规模地把“未来语言”提前收编进今天的工作流。
02|webpack 解决的是“应用怎么被装配”,但它并没有自动解决“今天到底能写什么语言”
这一步一定要先立住。
因为很多人后来会天然把 webpack 和 Babel 看成同一团东西。
可历史上,它们解决的问题并不一样。
webpack 更像是在回答:
- 整个项目从哪里开始
- 模块和资源怎么接起来
- 最后产物怎么切分和吐出
而 Babel 回答的则是另一类问题:
- 这段代码语法能不能先写
- 当前目标环境能不能跑
- 不同浏览器现实怎么被抹平
- 新标准和旧环境之间谁来做翻译
也就是说,到了这个阶段,前端工程化已经不再只是“怎么构建”。
它开始变成:
怎么决定开发者日常到底可以用哪一种语言现实来写代码。
这件事非常关键。
因为一旦前端团队开始大量写:
let/const- arrow functions
- classes
- modules
- async 相关新语法
那“浏览器现在支持没支持”就会立刻变成一个硬问题。
而如果这问题没有被解决,应用装配得再漂亮,也没有意义。
03|所以 Babel 之所以会变得重要,不是因为大家爱新语法,而是因为标准推进速度和浏览器落地速度,本来就不在一条时间线上
这就是第四篇最关键的历史背景。
很多语言世界里,你会天然觉得:
标准是什么,大家就按那个节奏慢慢用。
可 JavaScript 到了 ES6 前后,现实完全不是这么运作的。
因为那时出现了一个特别强的张力:
- 语言标准在快速演进
- 社区对大型工程语言姿态的需求在快速上升
- 浏览器原生实现却不可能同速全面补齐
这就意味着一件事:
如果前端只能等浏览器全体准备好,现代 JavaScript 的普及速度就会被运行时现实死死卡住。
而工程化时代的前端,恰恰已经等不起了。
因为它这时承受的,不再只是页面小脚本需求。
它面对的是:
- 更复杂的应用
- 更频繁的交付
- 更重的团队协作
- 更强的语言表达欲望
所以 Babel 崛起的真正时机,不是“语法党狂欢”。
而是:
前端终于不想再让浏览器的原生支持节奏,单独决定自己今天到底能写什么。
04|从 6to5 到 Babel,真正变化的也不只是名字,而是它从“ES6 转 ES5”变成了“整套 JavaScript 工具链基础”
这点如果不讲清楚,第四篇就会很容易写轻。
最早的 6to5,名字本身就已经说明了它最初的任务:
把 ES6 编译成 ES5。
这当然已经很重要。
可随着社区需求快速扩大,6to5 很快碰到一个边界:
如果它只是一个版本号过渡工具,那它的历史寿命会太短。
这也是为什么后来在 Not Born to Die 那篇文章里,团队明确把它改名成 Babel。
那篇文章里最关键的一层判断其实非常清楚:
它不想只当一个过渡性转译器。
它想成为:
一套可被其他工具依赖的 JavaScript 转换基础。
到了 Babel 6.0,这个方向就更明确了。
官方自己说得非常直白:
Babel wasn't just going to be a ES6 transpiler. Instead, it needed to become a platform.
这句话分量极大。
因为它意味着 Babel 的野心已经从“替你降级语法”变成了:
替整个 JavaScript 工具世界提供一个通用的语言变换中枢。
这就是为什么后来它不只是服务 ES 语法。
它还会服务:
- JSX
- Flow
- 各类 proposal
- 各种 transform
- minification / codemods / analysis 相关工具生态
所以第四篇一定要立住的一层是:
Babel 真正变强,不是因为它只是“能转 ES6”。
而是因为它后来变成了:
现代 JavaScript 工具链共享的语言变换平台。
05|而它真正改写前端工作流的那一步,就是把“先写未来,再编译回现在”做成了默认现实
这一步其实在 JavaScript 江湖(八) 已经讲过它对现代 JavaScript 的意义。
但在工程化语境里,它还要再往前推进一层。
因为一旦这条工作流成立,前端项目的默认现实就彻底变了。
以前更像是:
- 浏览器会什么
- 你就大体写什么
后来逐渐变成:
- 你先按更现代的写法开发
- 工具链再决定怎么落到当前目标环境
这差别非常大。
因为它意味着,从此以后,开发者每天面对的语言版本,
越来越不是浏览器的原生版本。
而是:
工具链为你构造出来的可用版本。
这会直接改写前端工程化的中心关系。
从这里开始,构建系统已经不只是在处理“文件”。
它开始参与决定:
语言现实本身。
这也就是为什么 Babel 在历史上不能被写成附属工具。
它不是锦上添花。
它是在重写前端“今天能写什么”的答案。
06|所以 Babel 为什么会和 bundler 绑得这么紧?因为应用装配和语言翻译,从这时起已经变成同一条流水线的两端
这也是第四篇最需要讲透的一层。
为什么 Babel 在工程实践里总是和 webpack、后来的各种 bundler / build tool 紧紧绑在一起?
不是因为社区随便把两个热门工具缝到了一起。
而是因为它们天然就在同一条流水线上。
一端要解决的是:
- 应用怎么被解析
- 依赖怎么被装配
- 产物怎么被切分
另一端要解决的是:
- 语法怎么被转换
- 新特性怎么被降级
- 目标环境怎么被照顾
这两件事一旦放到实际项目里,几乎不可能分开。
因为项目不会只问:
“这份应用图怎么输出?”
它还会问:
“这份图里的每个模块,到底该用哪种语言版本被输出?”
这就是为什么 babel-loader 这种集成方式后来会变得这么自然。
官方文档对它的定位也很直接:
Use Babel to transform modern JavaScript and JSX in webpack
注意,这已经不是简单的“两个工具一起用”。
它是在说:
应用图的装配过程,本身就要把语言转换一起吃进去。
从这个时候开始,前端工程化真正成形的默认流水线就出现了:
- 源码先被 Babel 理解和转换
- 再被 bundler 纳入应用图
- 最后以目标环境能接受的形式交付出去
所以 Babel 和 bundler 的绑定,不是偶然搭配。
而是:
现代前端工程链天然会长出来的一种结构。
07|而 preset / plugin 体系真正厉害的,也不只是“灵活”,而是它第一次把“目标环境差异”做成了工程配置问题
如果说前一层解释了它为什么会进入主流水线,
那这一层要讲的,就是它为什么会变得如此工程化。
Babel 真正让前端团队上瘾的地方,并不只是它能转语法。
更是:
它把语言兼容问题,正式变成了一套可以配置、组合、复用的工程问题。
你可以通过:
- preset
- plugin
- targets
- 配置文件
去明确指定:
- 想支持哪些环境
- 想开启哪些变换
- 想接受哪些实验性能力
这一步特别关键。
因为它意味着,从这时起,语言不再只是“浏览器支持列表”的附属物。
它开始变成项目配置的一部分。
也就是说,前端团队第一次可以比较明确地说:
我们这个项目允许写到哪一代语法,允许提前用到哪些能力,要为哪些现实环境付出兼容成本。
这其实已经是一种非常成熟的工程姿态了。
所以 Babel 之所以会显得像基建,
不是因为它无处不在这么简单。
而是因为它把语言兼容这件事,正式纳入了构建配置治理。
08|当然,这一步也带来了非常深的后果:从此以后,前端的“真实语言版本”越来越先存在于工具链里
这也是第四篇不能写漏的一层。
很多人后来把 Babel 记成一个“兼容层”。
可如果只这么记,还是低估了它。
更准确的说法应该是:
它让前端的真实语言版本,越来越先存在于工具链里。
这会带来几个非常深的后果。
第一,开发体验和运行时现实开始明显分层。
第二,标准推进、工具支持、社区实践会同时发生。
第三,工程团队对“浏览器原生支持”这件事的敏感度,在日常编码阶段会被显著降低。
这其实是现代前端非常反直觉的一点。
因为从 Babel 开始,大量开发者每天真正写到的 JavaScript,
并不是“目标浏览器原生支持的 JavaScript”。
而是:
被工具链提前放宽过的 JavaScript。
这也是为什么后来很多人会隐约觉得,现代前端越来越不像“直接对浏览器编程”。
这种感觉不是错觉。
因为从 Babel 起,浏览器现实和开发现实之间,已经正式多了一层强力翻译器。
09|为什么 Babel 真正绑定的,不只是语法未来,而是工程化现实
把前面这些线叠一起看,第四篇最重要的判断可以压成一句:
Babel 之所以会变成现代前端默认基建,不是因为它只是转译器,而是因为它第一次让工程化可以提前定义语言现实。
这句话里面有三层意思。
第一,它解决的不是单一兼容问题,而是标准进度和工程需求之间的系统性时差。
第二,它和 bundler 的绑定,不是偶然组合,而是现代构建链的天然结构。
第三,它真正改写的,不只是输出结果,而是开发者每天写代码时对“语言版本”的基本想象。
所以理解 Babel 的历史地位,最不该只记住“它能把 ES6 变成 ES5”。
更该记住的是:
它第一次让前端团队大规模拥有了这样一种权力:浏览器今天还没完全准备好,但项目今天就可以先按未来语法组织起来。
10|Babel 让“今天能写什么”第一次脱离“浏览器今天支持什么”
前端工程化江湖的第四篇,最值得记住的,不是“Babel 是一个 JavaScript compiler”这种产品定义。
更值得记住的是:
它把“浏览器支持什么”和“开发者今天能写什么”这两件事,第一次在工程实践里明显拆开了。
从 Babel 开始,现代前端越来越习惯一种新的现实:
语言的今天,不必等运行时全部到齐,工具链可以先把未来借给你。
所以第四篇如果只记一句,就记这句:
Babel 为什么会和 bundler 绑成现代前端基建,不是因为它只是在做语法降级,而是因为当前端已经学会替应用做总装配之后,它又进一步学会了:替未来语言先垫进今天。
编者注(事实核对):文中关于 Babel 从 6to5 演化而来的历史,主要依据 The State of Babel 对 2014 年 6to5 起源的回顾,以及 Not Born to Die 中关于改名为 Babel、目标不止于 ES6 transpiler 的说明。关于 Babel 6.0 的平台化转向,主要依据官方 6.0.0 Released 文章,其中明确写到 Babel wasn’t just going to be a ES6 transpiler,而要成为一套 platform,并通过 modularization、plugin API、preset 体系向外开放。关于 Babel 在实际工程链中的位置,主要依据 babel-loader 文档中 “Use Babel to transform modern JavaScript and JSX in webpack” 的表述,以及 Babel 官方 usage/configuration 文档中对 @babel/core、presets、plugins、targets、配置文件的说明。正文将 Babel 概括为“让工程化可以提前定义语言现实”,属于基于其语言转换、工作流重塑与配置治理作用做出的历史总结。
关键人物速览
- Sebastian McKenzie:
6to5/Babel的发起者。理解为什么一个转译器后来会长成整套 JavaScript 工具平台,绕不开他。 - Henry Zhu:
Babel后续长期关键维护者之一。理解它为什么能从项目热度变成真正的社区基建,绕不开这条线。 - Tobias Koppers:
webpack的发起者。理解Babel为什么会在工程实践里和 bundler 紧密绑定,仍然要接回他这条线。
参考与延伸阅读
Not Born to Die
https://babeljs.io/blog/2015/02/15/not-born-to-die6to5 + esnext
https://babeljs.io/blog/2015/01/12/6to5-esnextBabel 6.0.0 Released
https://babeljs.io/blog/2015/10/29/6.0.0The State of Babel
https://babeljs.io/blog/2016/12/07/the-state-of-babelBabel Usage Guide
https://babeljs.io/docs/en/usage/Configure Babel
https://babeljs.io/docs/configuration.htmlbabel-loader
https://webpack.js.org/loaders/babel-loader/
下篇预告:Rollup / Snowpack / Vite 为什么会代表反攻,因为前端很快又会反问:这套越来越重的工程机器,自己是不是也该被重新改造了。