做一个Babel7升级配置的备忘文档,很多内容都是官网的搬运和理解扩展
概览
Babel7使用 "scoped" packages 方式,加上了 @babel 标识便于区分官方 package 以及 非官方 package
npm install --save-dev @babel/core @babel/cli @babel/preset-env
npm install --save @babel/polyfill
迁移原项目插件时需要先官网查看,有一些还未移到@babel域下
配置
.babelrc
File-relative configuration
- 与文件实际物理位置相关
- 从编译文件向上查找文件系统获取.babelrc文件,找到package.json为止
- 如果目录不在
babelrcRoots
配置中(默认配置为. 即根目录),.babelrc文件将被忽略
进一步解析:
- .babelrc文件不能跨多个package生效(即有package.json的目录),一般使用webpack配置js文件loader,我们会忽略node_modules目录,因为项目根目录的.babelrc文件通常不会对该目录下各个package生效,且如果node_modules目录下的package有自己的.babelrc文件,这个sub配置会生效,并可能因为插件依赖不完全而报错
- 同理 .babelrc 文件也不能对 symlinked packages 生效
如这个官网例子:(.babelrc文件无法对mod1和mod2的文件生效)
.babelrc
packages/
mod1/
package.json
src/index.js
mod2/
package.json
src/index.js
json格式文件,不支持计算、注释
格式
{
"presets": [...],
"plugins": [...]
}
.babelrc.js
js文件,配置同.babelrc
可访问Node API
格式
const presets = [ ... ];
const plugins = [ ... ];
if (process.env["ENV"] === "prod") {
plugins.push(...);
}
module.exports = { presets, plugins };
babel.config.js
Project-wide configuration
Babel7.x新特性,项目全局配置
默认使用当前工作目录下的babel.config.js文件,可配置configFile
覆盖默认文件路径
- 对当前工作目录下 node_modules 或 symlinked packages 均可生效
- 当前工作目录下如果配置了.babelrc,其中配置将会覆盖或合并babel.config.js中的配置
- 但是要注意,如果在工作目录下某个sub package中运行babel,将无法找到根目录的babel.config.js文件 (可以配置 "rootMode" 选项为
"upward"
,让Babel自动向上寻找)
格式
module.exports = function () {
const presets = [ ... ];
const plugins = [ ... ];
return {
presets,
plugins
};
}
Monorepo-structured repositories
对于一个项目中存在多个package包的情况,Babel7提供了一种更方便进行babel配置管理、合并、特殊配置的方案
- 根目录使用 babel.config.js 进行全局配置
- Subpackage使用 .babelrc, 默认情况下 subpackage 目录下的 .babelrc文件不会生效
package.json
babel.config.js
packages/
mod/
package.json
.babelrc
index.js
当Babel编译packages/mod/index.js文件时,和它同一级目录的.babelrc文件不会被识别
如果需要该.babelrc文件被识别加载,需要在根目录下的 babel.config.js
文件中使用配置项 "babelrcRoots"
babelrcRoots: [
".",
"packages/*",
],
polyfill
依然还是两种方案
@babel/polyfill
全局polyfill
会污染全局和原生对象
@babel/plugin-transform-runtime(devDependency) 与 @babel/runtime(dependency)
plugin-transform-runtime 插件将所有编译时需要的helper方法统一从@babel/runtime中引入 ,不会污染全局和原生对象