一、配置文件
在前面几小节,我们已经简单使用过Babel的配置文件了。现在我们来深入学习它。
无论是通过命令行工具babel-cli来进行编译,还是webpack这类的构建工具,通常情况下,我们都需要建立一个Babel配置文件来指定编译的规则。
Babel的配置文件是Babel执行时默认会在当前目录寻找的文件,主要有.babelrc,.babelrc.js,babel.config.js和package.json。它们的配置项都是相同,作用也是一样的,只需要选择其中一种。
对于.babelrc,它的配置是这样子
{ "presets": ["es2015", "react"], "plugins": ["transform-decorators-legacy", "transform-class-properties"] }
对于babel.config.js和.babelrc.js,它的配置是一样的,通过module.exports输出配置项
module.exports = { "presets": ["es2015", "react"], "plugins": ["transform-decorators-legacy", "transform-class-properties"] }
对于package.json,就是在package.json中增加一个babel属性和值,它的配置是这样子
{ "name": "demo", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "author": "", "babel": { "presets": ["es2015", "react"], "plugins": ["transform-decorators-legacy", "transform-class-properties"] } }
仔细观察上述几种配置文件,会发现它们的配置项其实都是plugins和presets。
另外,除了把配置写在上述这几种配置文件里,我们也可以写在构建工具的配置里。对于不同的构建工具,Babel也提供了相应的配置项,例如webpack的babel-loader的配置项,其本质和配置文件是一样的,大家学会配置上述的一种,自然也就会其它的了,不再单独讲解。
配置文件总结起来就是配置plugins和presets这两个数组,我们分别称之为插件数组和预设数组。
除了plugins和presets这两个配置项,还有minified、ignore等,但我们平时都用不到,大家还是把精力放在plugins和presets上。
推荐使用后缀名是js配置文件,因为可以使用js做一些逻辑处理,适用性更强。举一个例子
// 这里只是举个例子,实际项目中,我们可以传入环境变量等来做处理 var year = 2020; var presets = []; if (year > 2018) { presets = ["@babel/env"]; } else { presets = "presets": ["es2015", "es2016", "es2017"], } module.exports = { "presets": presets, "plugins": [] }
二、插件与预设
plugin代表插件,preset代表预设,它们分别放在plugins和presets,每个插件或预设都是一个npm包。
本节开头提到了通过Babel配置文件来指定编译的规则,所谓编译的规则,就是在配置文件里列出的编译过程中会用到的Babel插件或预设。这些插件和预设会在编译过程中把我们的ES6代码转换成ES5。
Babel插件的数量非常多,处理ES2015的有
- @babel/plugin-transform-arrow-functions
- @babel/plugin-transform-block-scoped-functions
- @babel/plugin-transform-block-scoping
……
处理ES2018的有
- @babel/plugin-proposal-async-generator-functions
- @babel/plugin-transform-dotall-regex
……
所有的插件都需要先安装npm包到node_modules后才可以使用。
Babel插件实在太多,假如只配置插件数组,那我们前端工程要把ES2015,ES2016,ES2017…下的所有插件都写到配置项里,我们的Babel配置文件会非常臃肿。
preset预设就是帮我们解决这个问题的。预设是一组Babel插件的集合,用大白话说就是插件包,例如babel-preset-es2015就是所有处理es2015的二十多个Babel插件的集合。这样我们就不用写一大堆插件配置项了,只需要用一个预设代替就可以了。另外,预设也可以是插件和其它预设的集合。Babel官方已经对常用的环境做了一些preset包
- @babel/preset-env
- @babel/preset-react
- @babel/preset-typescript
- @babel/preset-stage-0
- @babel/preset-stage-1 …
所有的预设也都需要先安装npm包到node_modules。
三、plugin与preset的短名称
插件可以在配置文件里写短名称,如果插件的npm包名称的前缀为 babel-plugin-,可以省略前缀。例如
module.exports = { "presets": [], "plugins": ["babel-plugin-transform-decorators-legacy"] }
可以写成短名称
module.exports = { "presets": [], "plugins": ["transform-decorators-legacy"] }
如果npm包名称的前缀带有npm作用域@,例如@org/babel-plugin-xxx,短名称可以写成@org/xxx。
目前Babel7的官方npm包里绝大部分插件已经升级为@babel/plugin-前缀的,这种情况的短名称比较特殊了,绝大部分可以像babel-plugin-那样省略@babel/plugin-。但babel官方并没有给出明确的说明,所以还是推荐用全称。
预设的短名称规则与插件的类似,预设npm包名称的前缀为babel-preset-或作用域@xxx/babel-preset-xxx的可以省略掉babel-preset-。
对于Babel7的官方npm包里绝大部分预设已经升级为@babel/preset-前缀的,这种情况的短名称比较特殊了,绝大部分可以像babel-preset-那样省略@babel/preset-。但babel官方并没有给出明确的说明,例如,@babel/preset-env的短名称就是@babel/env,所以还是推荐用全称。
plugins插件数组和presets预设数组是有顺序要求的。如果两个插件或预设都要处理同一个代码片段,那么会根据插件和预设的顺序来执行。规则如下:
- 插件比预设先执行
- 插件执行顺序是插件数组从前向后执行
- 预设执行顺序是预设数组从后向前执行
四、Babel插件和预设的参数
每个插件是插件数组的一成员项,每个预设是预设数组的一成员项,默认情况下,成员项都是用字符串来表示的,例如"@babel/preset-env"。
如果要给插件或预设设置参数,那么成员项就不能写成字符串了,而要改写成一个数组。数组的第一项是插件或预设的名称字符串,第二项是个对象,该对象用来设置第一项代表的插件或预设的参数。例如给@babel/preset-env设置参数:
{ "presets": [ [ "@babel/preset-env", { "useBuiltIns": "entry" } ] ] }
小结:
1.这节课我们主要学习了Babel配置文件的配置规则。但在进行开发的时候,我们到底该选择什么插件或预设呢。这部分内容在接下来的教程里学习。
网上基本上找不到关于babel的教程,这个算比较好的入门教程了,谢谢博主!
webpack中的babel-loader添加了option配置,项目根部又配置了.babelrc文件,这样是不是转译的时候会同时执行两个配置,导致编译后的文件变得更大?如果两个都会执行,webpack中的option配置和.babelrc文件的配置,哪个的优先级高些?
因为没这么做过,不一定准确,你可以试一下。 会合并使用配置,相同的项优先使用babel-loader的。
@babel/plugin-transform-runtime 现在不能直接省略@babel/plugin- ,但可以省 plugin-, presets 同理,亲测
2022已过半,看起来还是很贴心的博客,我好爱。
即将实习,过来恶补
感谢大佬,很多小细节都讲的很清楚!