Babel

1 Babel 是什么

Babel 是一个 JS 编译器,能够将 ES6+ 版本的 JS 语法编译为向后兼容的 JS 语法,进而使我们无需等待浏览器支持就可以使用新语法。

2 安装

通过下面命令安装所需包:

1
npm install --save-dev @babel/core @babel/cli @babel/preset-env

2.1 安装包介绍

2.1.1 @babel/core

​ @babel/core 是 Babel 的核心模块,可以将代码解析成 AST,各个插件会在 AST 的基础上进行语法转换。

1
2
3
const babel = require("@babel/core");

babel.transform("code", optionsObject);

2.1.2 @babel/cli

@babel/cli 是 Babel 的命令行工具,可以使我们通过命令行使用使用 Babel。

安装后可以通过下面方式使用 @babel/cli:

1
2
3
npm install --save-dev @babel/core @babel/cli

./node_modules/.bin/babel src --out-dir lib

这个命令将解析 src 目录中的所有 JS 文件,并将每个文件的转换结果输出到 lib 目录。 由于我们没告诉它应该如何转换,因此输出代码将与输入相同(不保留代码样式)。 我们可以通过选项参数来指定所需的转换。

2.1.3 Plugins & Presets

2.1.3.1 Plugins(插件)

Babel 通过具体 Plugins(插件)来进行语法转换,如 @babel/plugin-transform-arrow-functions 可以将箭头函数转换为普通函数。

1
2
3
npm install --save-dev @babel/plugin-transform-arrow-functions

./node_modules/.bin/babel src --out-dir lib --plugins=@babel/plugin-transform-arrow-functions
  • 配置

    1
    2
    3
    {
    "plugins": [ "myPlugin" ]
    }
  • 短名称

    如果插件名称的前缀为 babel-plugin-,则可以使用它的短名称

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    {
    "plugins": [
    "myPlugin",
    "babel-plugin-myPlugin" // 两个插件实际是同一个
    ]
    }

    //这也适用于带有 scope 的插件
    {
    "plugins": [
    "@org/babel-plugin-name",
    "@org/name" // 两个插件实际是同一个
    ]
    }

2.1.3.2 Presets(预设)

@babel/presets-* 是一组插件的集合,安装一个 Presets 可以替代单独安装多个插件。可以通过创建自己的 Presets 来创建任意插件的组合。

@babel/preset-env 是最常用的 Presets,包含了支持 ES6+ 特性的大多插件。如果源码使用了不在 @babel/preset-env 中的语法,编译时会报错,可根据具体错误提示安装对应插件,并将对应插件添加到 babel 配置文件中。

  • 配置

    直接配置 Presets 名称 Babel 会在 nodde_module 目录中查找:

    1
    2
    3
    {
    "presets": ["babel-preset-myPreset"]
    }

    也可以配置 Presets 的绝对/相对路径:

    1
    2
    3
    {
    "presets": ["./myProject/myPreset"]
    }
  • 短名称

    如果 Presets 名称的前缀为 babel-preset-,则还可以使用它的短名称:

    1
    2
    3
    4
    5
    6
    {
    "presets": [
    "myPreset",
    "babel-preset-myPreset" // 这两个相同
    ]
    }

    短名称也适用于带有冠名(scope)的 Presets:

    1
    2
    3
    4
    5
    6
    {
    "presets": [
    "@org/babel-preset-name",
    "@org/name" // 这两个相同
    ]
    }

2.1.3.3 执行顺序

  • 插件比 presets 先运行

  • 插件按照从前往后的顺序执行

  • Presets 按照从后往前的顺序执行

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    //执行顺序: transform-decorators-legacy  transform-class-properties
    {
    "plugins": ["transform-decorators-legacy", "transform-class-properties"]
    }

    //执行顺序:stage-2、react 然后是 es2015。
    {
    "presets": ["es2015", "react", "stage-2"]
    }


2.1.3.4 参数配置

插件和 Presets 都可以接受参数,插件名和参数对象组成一个数组。

下面几种情况都属于不配置参数:

1
2
3
{
"plugins": ["pluginA", ["pluginA"], ["pluginA", {}]]
}

插件配置参数:

1
2
3
4
5
6
7
8
9
10
11
{
"plugins": [
[
"transform-async-to-module-method",
{
"module": "bluebird",
"method": "coroutine"
}
]
]
}

Presets 配置参数:

1
2
3
4
5
6
7
8
9
10
11
{
"presets": [
[
"env",
{
"loose": true,
"modules": false
}
]
]
}

2.1.4 @babel/polyfill

polyfill 是垫片的意思。Babel 将 ES 标准分为 syntax 和 built-in 两种类型,对于可以通过改写覆盖方法实现的就是 built-in,如 Array.prototype.includes、Array.from、Object.assign、Promise 等,而对于如 const、let、import、class 则被分类为 syntax。

对于 built-in 类型会通过 @babel/polyfill 来进行转译,其实现方法即通过 Object.defineProperty 来实现这些标准。

2.1.5 core-js

Babel 在 7.4.0 版本中宣布废弃 @babel/polyfill,使用 core-js 替代。

2.1.5.1 安装

生产环境也需要 core-js,所以使用 –save 安装。

1
npm install core-js --save

2.1.5.2 配置

在 babel 配置文件中通过配置 useBuiltIns 来控制 built-in 类型垫片的注入。可以设置成 entryusagefalse, 默认值为 false

  • entry:在入口注入目标环境所有不支持的 built-in,会增加代码体积。
  • usage:编译时根据源码对 built-in 的使用情况,在对应页面注入相应的实现
  • false:表示不注入垫片

2.1.6 @babel/plugin-transform-runtime

@babel/plugin-transform-runtime 可以将编译后文件中的重复 helper 函数提取出来,并且能够提供沙箱环境,达到了节省代码体积、不会污染全局的效果。

1
2
3
4
5
6
npm install --save-dev @babel/plugin-transform-runtime
npm install --save @babel/runtime

#使用 core-js
npm uninstall --save @babel/runtime
npm install --save @babel/runtime-corejs3

@babel/plugin-transform-runtime 的默认配置不会包含 core-js ,需要通过 corejs 选项来设置,并且需要安装对应 corejs 的版本。

corejs option Install command
false npm install –save @babel/runtime
2 npm install –save @babel/runtime-corejs2
3 npm install –save @babel/runtime-corejs3

3 配置

项目根目录配置 babel.config.json 文件:

targets 属性配置目标环境,babel 会根据目标环境来进行按需转译。

不使用 @babel/plugin-transform-runtime 的配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
{
"presets": [
[
"@babel/env",
{
"targets": {
"edge": "17",
"firefox": "60",
"chrome": "67",
"safari": "11.1"
},
"useBuiltIns": "usage",
"corejs": "3"
}
]
]
}

使用 @babel/plugin-transform-runtime 的配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
{
"presets": [
[
"@babel/env",
{
"targets": {
"edge": "17",
"firefox": "60",
"chrome": "67",
"safari": "11.1"
}
}
]
],
"plugins": [["@babel/plugin-transform-runtime", { "corejs": 3 }]]
}

https://juejin.im/post/6844903602822053895

https://babeljs.io/docs/en/next/babel-preset-env.html

https://www.cnblogs.com/sefaultment/p/11631314.html