babel7.4配置总结

本文适用版本

1
2
3
4
5
6
7
8
9
10
11
"@babel/core": "^7.4.4",
"@babel/plugin-transform-runtime": "^7.4.4",
"@babel/preset-env": "^7.4.5",
"@babel/runtime": "^7.4.5",
"@babel/runtime-corejs2": "^7.4.5",
"@babel/runtime-corejs3": "^7.4.5",
"babel-loader": "^8.0.6",
"core-js": "^3.1.4",
"regenerator-runtime": "^0.13.2",
"webpack": "^4.17.1",
"webpack-cli": "^3.1.0"

什么是 babel

babelJavaScriptes2015/2016/2017/2046 的新语法转化为 es5,让低端运行环境(如浏览器和 node)能够认识并执行。

运行方式

babel 总共分为三个阶段:解析,转换,生成。

babel 本身不具有任何转化功能,它把转化的功能都分解到一个个 plugin 里面。因此当我们不配置任何插件时,经过 babel 的代码和输入是相同的。

Plugin

  1. 语法插件(@babel/parser):使得 babel 能够解析更多的语法。
  2. 转译插件:源码转换并输出。

Preset

preset 即一组官方推荐的预设插件的集合。目前推荐使用 @babel/preset-env

Plugin 和 Preset 执行顺序

  • Plugin 会运行在 Preset 之前。
  • Plugin 会从前到后顺序执行。
  • Preset 的顺序则 刚好相反(从后向前)。

browserslist

browserslist 是在不同的前端工具之间共用目标浏览器和 node 版本的配置工具,中文参阅。浏览器特性支持可查询caniuse

eg:package.json

1
2
3
4
5
6
"browserslist": [
"last 1 version",
"> 1%",
"maintained node versions",
"not dead"
]

各 babel 包介绍

@babel/core

babel 的编译核心包,内置 helpers 插件模块,是语法转换的主要辅助工具,所谓 babel 版本多少就是指这个包的版本多少。

babel-loader

webpack 中使用 babel 加载文件。

@babel/preset-env

  1. 文档查阅
  2. @babel/preset-env 是一个智能预设,集合了一系列常用插件,会根据 browserslist 设置的目标浏览器,自动将代码中的新特性转换成目标浏览器支持的代码。
  3. 默认的 @babel/preset-env 是无法转换新的 API,比如 Iterator、Generator、Set、Maps、Proxy、Reflect、Symbol、Promise 等全局对象,以及一些定义在全局对象上的方法(比如 Object.assign)都不会转码。需要根据需要添加 core-js 包和 regenerator-runtime 包支持。
1
npm i core-js egenerator-runtime

babel.config.js配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
module.exports = {
presets: [
[
'@babel/env',
{
targets: {
browsers: ['> 1%', 'last 2 versions', 'not dead'],
},
modules: false, //取值可以是 amd, umd, systemjs, commonjs 和 false,为false时可以用于webpack做tree shaking。
useBuiltIns: 'usage', // usage-按需引入 entry-入口引入(代码里需手动引入core-js) false-不引入
corejs: 3, // 2-corejs@2 3-corejs@3
},
],
],
};

core-js

  1. 文档查阅
  2. JavaScript 标准库的 polyfill,目前提供 core-jscore-js-purecore-js-bundle 3 个版本。
  3. 可直接项目里引用各种 polyfill
1
2
3
4
// polyfill all `core-js` features:
import 'core-js';
// polyfill only stable `core-js` features - ES and web standards:
import 'core-js/stable';

regenerator-runtime

  1. regenerator-runtime 模块来自 facebookregenerator 模块。
  2. 生成器函数、asyncawait 函数经 babel 编译后,regenerator-runtime 模块用于提供功能实现。
  3. 源码查阅

@babel/polyfill

babel 7.4 版本已废弃,因为他仅仅依赖了 core-jsregenerator-runtime,安装这两个就可以了。

@babel/runtime/@babel/runtime-corejs2/@babel/runtime-corejs3

  1. @babel/runtime 提供 helpers 函数,并会去安装 regenerator-runtime 包,只做语法转换(helpersregenerator), 没有新 api 的实现。
  2. @babel/runtime-corejs2 包含 @babel/runtime 的全部并额外安装 core-js@2
  3. @babel/runtime-corejs3 包含 @babel/runtime 的全部并额外安装 core-js-pure@3
  4. 相比之下 @babel/runtime-corejs3 支持更多,包括实例,api 等。
  5. 三者均需要与 @babel/plugin-transform-runtime 搭配使用(但 @babel/plugin-transform-runtime 不一定要和他们用)。
1
2
3
4
5
6
7
8
9
10
11
module.exports = {
presets: ['@babel/env'],
plugins: [
[
'@babel/plugin-transform-runtime',
{
corejs: 3, //为false就安装 npm i @babel/runtime,为2就安装@babel/runtime-corejs2,为3就安装@babel/runtime-corejs3
},
],
],
};

@babel/plugin-transform-runtime

  1. Babel 编译过程中产生的 helper 方法进行重新利用(聚合),以达到减少打包体积的目的.
  2. 避免全局补丁污染,对打包过的 bundler 提供”沙箱”式的补丁。
  3. 文档查阅

两种最优方案

使用 corejs+useBuiltIns

npm 安装:

1
2
npm i @babel/core @babel/preset-env @babel/plugin-transform-runtime -D
npm i core-js regenerator-runtime

babel.config.js 配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
module.exports = {
presets: [
[
'@babel/env',
{
targets: {
browsers: ['> 1%', 'last 2 versions', 'not dead'],
},
useBuiltIns: 'usage',
corejs: 3,
},
],
],
plugins: [['@babel/plugin-transform-runtime']],
};
  1. 该方案支持所有,包括转译语法,API 及实例方法的 polyfill
  2. 该方案会污染全局。

使用 runtime-corejs3

npm 安装:

1
2
npm i @babel/core @babel/preset-env @babel/plugin-transform-runtime -D
npm i @babel/runtime-corejs3

babel.config.js 配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
module.exports = {
presets: [
[
'@babel/env',
{
targets: {
browsers: ['> 1%', 'last 2 versions', 'not dead']
}
]
],
plugins: [
[
'@babel/plugin-transform-runtime',
{
corejs: 3
}
]
]
};
  1. 该方案支持所有,包括转译语法,API 及实例方法的 polyfill
  2. 该方案不会污染全局。

总结

  1. Babel 版本号< 7.4.0
    • 开发类库:@babel/runtime
    • 内部项目:@babel/polyfill
  2. Babel 版本号>= 7.4.0
    • @babel/runtime-corejs3
  3. 这文档都是坑爹的,网上的各种经验也都是之前的某个版本的总结,babel 包变化很快,最好的还是去看源码,和多测试不同包的效果,自己摸索体验。
---- 本文结束,感谢您的阅读 ----