写这篇文章的起因来自一次偶然。某天要搭个工程做些试验,由于工程小,没打算用脚手架,就手动 npm install
装了些必要的类库,当然其中包括 babel
。同时在安装的过程中,顺手将必要的配置文件从以前到工程拷贝到根目录。
接下来的情节,你大概也猜到了,敲代码猛如虎、跑编译快如龙、控制台报错一脸懵。
经过排查发现,由于安装类库的时候没带上版本号,导致 babel
安装了最新的版本 —— Babel 7。最新的 Babel 7 相较于前一个版本,是有不兼容的更新的。想着也许以后脚手架都会上 Babel 7,就趁机学一学吧。
背景交代完毕,下面进入学习时间了。
使用 Babel 之前,需要通过下面的指令安装四大核心库:
npm install --save-dev @babel/core @babel/cli @babel/preset-env
npm install --save @babel/polyfill
然后在工程根目录创建一个配置文件 babel.config.json
:
{
"presets": [
[
"@babel/env",
{
"targets": {
"edge": "17",
"firefox": "60",
"chrome": "67",
"safari": "11.1",
},
"useBuiltIns": "usage",
}
]
],
"plugins": ["plugin-transform-arrow-functions"]
}
配置项中,一个 plugin
代表一种代码转换的功能,例如 plugin-transform-arrow-functions
就提供“将箭头函数转换成普通函数”的功能;presets
中的每一个 preset
代表一种预设,而一个预设是由多个 plugin
构成。
理解 preset
和 plugin
的运行顺序还是有必要的。掌握下面三点即可:
plugins
比 presets
先运行plugins
里面的 plugin
是顺序执行presets
里面的 preset
是逆序执行Babel 7 对 Polyfill 也进行了优化。第一个优化是在使用上,现在你只要在 env
这个 preset
里面设置 "useBuiltIns": "usage"
,Babel 就会根据你设置的 targets
,扫描所有需要转换的代码,自动找出需要 polyfill 的地方,在开头处注入类似下面的代码:
require('core-js/modules/xxxx') // xxx 代表需要的 polyfill
这样我们不必在全局引入整个类库,带来了两个好处:
第二个优化,是将提案(proposal)级别的 polyfill 从 @babel/polyfill
中移除了。如果你想使用这些 polyfill,需要从 core-js
中单独引入(具体引入方法)。
顺带说一下,上面说的两个优化点都提到了 core-js
, 它是包括在 @babel/polyfill
这个类库里的,不用单独安装。
下面我们说下导致我开头“惨案”发生的罪魁祸首 —— 不兼容更新,具体更新的内容可以点这个链接。我这里提两个比较主要的:
这两个 Preset Deprecations 导致以下的 presets
都失效了:
babel-preset-es201x
babel-preset-latest
babel-preset-stage-x
之前包含在这些预设里面的功能,你现在需要手动添加到配置文件到 plugins
中,又或者自己创建一个 preset
。
Babel 团队这样做的一个目的是让你清楚的知道自己需要哪些功能(查看 Plugin 列表)。
还有些修改是关于重命名的,例如不在年度发行版本里的功能需要加上 -proposal
:
@babel/plugin-transform-function-bind
→ @babel/plugin-proposal-function-bind
(Stage 0)@babel/plugin-transform-class-properties
→ @babel/plugin-proposal-class-properties
(Stage 3)又或者将插件里面的“年份”删掉:
@babel/plugin-transform-es2015-classes
→ @babel/plugin-transform-classes
好了,东西就写这些,毕竟不是新手入门指导。最后再感慨下,现在的 JSer(包括我自己)都被脚手架“惯”坏了,好多细节都不去主动了解(除了这里说的 Babel,还有像 Webpack),这样一旦碰到这类比较大的更新,往往会措手不及。
拓展阅读