# 重点

# @babel/core

核心模块,转换代码

const babel = require("@babel/core");

const code = `
    const a = () => {
        console.log(111)
    }
    a()
`;
const result = babel.transform(code, {});
console.log(result.code)
1
2
3
4
5
6
7
8
9
10

# @babel/cli

一个允许你从终端使用babel的工具。(-d 为 --output-dir 的简写,输出路径),实际执行的是npx babel src... ,下面这个例子也可以写为 ./node-modules/.bin/babel src...

"scripts": {
    "build": "babel src -d dist"
}
1
2
3

# plugins

transform-member-expression-literals为例

  • Cli方式
"scripts": {
    "test1": "babel --plugins transform-member-expression-literals src -d dist"
}
1
2
3
  • Node方式
require("@babel/core").transform("", {
    plugins: ["transform-member-expression-literals"]
});
1
2
3
  • 配置文件方式(.babelrc)
{
    "presets": [...],
    "plugins": ["transform-member-expression-literals"]
}
1
2
3
4

# presets

# 官方presets

  • @babel/preset-env
  • @babel/preset-flow
  • @babel/preset-react
  • @babel/preset-typescript

# 创建preset

  • 自定义preset文件(js文件,通过相对路径引入)
module.exports = () => ({
    // 可以包含其他的presets以及带有选项的插件
    presets: [
        require("@babel/preset-env"),
    ],
    plugins: [
        [require("@babel/plugin-proposal-class-properties"), { loose: true }],
        require("@babel/plugin-proposal-object-rest-spread"),
    ],
});
1
2
3
4
5
6
7
8
9
10
  • npm包

如果presetnpm上,你可以传入预设名称,babel将检查它是否已安装在node_modules中。

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

# preset顺序

preset的顺序是相反的(从最后一个到第一个)。

{
    "presets": [
        "a",
        "b",
        "c"
    ]
}
1
2
3
4
5
6
7

将会按照以下顺序运行:c, b, 然后 a。

这主要是为了确保向后兼容性,因为大多数用户在“stage-0”之前列出了“es2015”。

# preset-env

{
    "presets": [
        "@babel/preset-env"
    ]
}
1
2
3
4
5

语法转换只是将高版本的语法转换成低版本的,但是新的内置函数、实例方法(includes)无法转换。这时,就需要使用polyfill上场了,顾名思义,polyfill的中文意思是垫片,所谓垫片就是垫平不同浏览器或者不同环境下的差异,让新的内置函数、实例方法等在低版本浏览器中也可以使用。

# @babel/polyfill

# 介绍

@babel/polyfill模块包括core-js和一个自定义的regenerator runtime模块,可以模拟完整的 ES2015+ 环境

这意味着可以使用诸如PromiseWeakMap之类的新的内置组件、Array.fromObject.assign之类的静态方法、Array.prototype.includes之类的实例方法以及生成器函数(前提是使用了 @babel/plugin-transform-regenerator插件)。为了添加这些功能,polyfill将添加到全局范围和类似String这样的内置原型中(会对全局环境造成污染)。

npm install --save @babel/polyfill
1

需要将完整的polyfill在代码前加载,引入后打包出来的体积较大,接下来出场的是preset-env + useBuiltIns

# preset-env + useBuiltIns

Babel 会检查所有代码,以便查找在目标环境中缺失的功能,然后仅仅把需要的 polyfill 包含进来。

core-js@2分支中已经不会再添加新特性,新特性都会添加到core-js@3。例如你使用了Array.prototype.flat(),如果你使用的是core-js@2,那么其不包含此新特性。为了可以使用更多的新特性,建议使用core-js@3。安装corejs3:yarn add @babel/runtime-corejs3

{
    "presets": [
        [
            "@babel/env",
            {
                "useBuiltIns": "usage",
                "corejs": 3
            }
        ]
    ]
}
1
2
3
4
5
6
7
8
9
10
11

Babel会使用很小的辅助函数来实现类似_createClass等公共方法。默认情况下,它将被添加(inject)到需要它的每个文件中。

使用@babel/plugin-transform-runtime插件,所有帮助程序都将引用模块@babel/runtime,这样就可以避免编译后的代码中出现重复的帮助程序,有效减少包体积。

# @babel/plugin-transform-runtime

# 作用

@babel/plugin-transform-runtime 是一个可以重用 Babel 注入的帮助程序,以节省代码大小的插件。

yarn add -D @babel/plugin-transform-runtime
1

@babel/runtime作为生产依赖项(因为它是用于“运行时”的)

yarn add @babel/runtime
1

此转换器的另一个用途是为代码创建沙箱环境。如果您使用@babel/polyfill以及它提供的内置内容(如 PromiseSetMap) ,将会污染全球范围。虽然这对于一个应用程序或命令行工具来说可能是可以的,但是如果你的代码是一个你打算发布给其他人使用的库,或者如果你不能准确地控制你的代码运行的环境,这就成了一个问题。

转换器将把这些内置的代码别名为core-js,这样您就可以无缝地使用它们,而无需进行多次填充。

# 用法

{
    "presets": [
        [
            "@babel/preset-env"
        ]
    ],
    "plugins": [
        ["@babel/plugin-transform-runtime", {
            "corejs": 3
        }]
    ]
}
1
2
3
4
5
6
7
8
9
10
11
12

如果上面 @babel/plugin-transform-runtime配置的core-js2,其中不包含实例的polyfill需要单独引入。如果我们配置的corejs3版本,那么不管是实例方法还是全局方法,都不会再污染全局环境。