各式各样的babel工具,babel-plugin/babel-preset/babel-runtime/babel-polyfill.....

babel配置读取

1、可以通过babe-cli命令行转义高级语法,命令行配置,指定文件
2、加入script命令,指定babel配置文件
3、通过babel-loader配置,借助webpack,打包时自动读取cwd()根目录的.babelrc或babel.config.js

@babel/preset-env

babel7的preset工具@babel/preset-env

// .babelrc
{
    "presets": [
        "@babel/preset-env",
        options
    ]
}

配置过后,babel-loader会读取该文件,并根据预设转换需要转换的高级语法,但是它并不提供高级语法如Array.prototype.includes、Array.prototype.flat的垫片。

@babel/polyfill

core-js@3的出现,替代了@babel/polyfill,配合@babel/preset-env的useBuiltlns选项,可以得到更小的代码体积

{
  "presets": [
    [
      "@babel/preset-env",
      {
        "useBuiltIns": "usage",
        "corejs": 3 // 如果不指定,会默认使用core-js2.x
      }
    ]
  ]
}

@babel/plugin-transfrom-runtime

上面的配置可以达到转义的功能,但是看一下输出的代码

"use strict";

require("core-js/modules/es.array.from");

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

var Parent = function Parent() {
  _classCallCheck(this, Parent);
};

Array.from([])

上面编译的代码有两个问题
1、helper重复注入
2、全局环境污染

重复注入

babel-runtime会在每个文件,使用到class Xxx {} 的地方提供一个helper,如果class很多,会使得单文件体积变大。然后就到了@babel/plugin-transfrom-runtime出场的时候了

{
  "presets": [
    [
      "@babel/preset-env",
      {
        "useBuiltIns": "usage",
        "corejs": 3
      }
    ]
  ],
  "plugins": [
    "@babel/plugin-transform-runtime"
  ]
}

然后_classCallCheck就会作为一个模块被生成,而不是每次都注入一个_classCallCheck函数了。

全局环境污染

可以看到require("core-js/modules/es.array.from");直接把Array的from函数给顶掉了,如果babel团队更新不及时,而js引擎换了对from的解析规则,那么真实的Array.from方法就被替换了,所以为了避免这种情况发生,需要安装@babel/runtime-corejs3

{
  "presets": [
    "@babel/preset-env",
    {
        "useBuiltIns": "usage",
        "corejs": 3
    }
  ],
  "plugins": [
    [
      "@babel/transform-runtime",
      {
        "corejs": 3
      }
    ]
  ]
}

输出的代码会实现一个_from方法,然后将代码中所有的Array.from替换为Array._from,避免了在兼容高级语法的机型上,语法被污染的情况。上面也是babel7语法转换最佳配置,最后需要安装的插件有

npm i @babel/preset-env corejs@3 @babel/transfrom-runtime @babel/runtime-corejs3 -D

总结

@babel/polyfill 和 @babel/runtime

两个都可以提供es2015的环境,为Array.prototype.reduce之类的方法提供垫片,区别在于
@babel/polyfill 是通过在Array.prototype上添加了一个自己的reduce方法,会覆盖原方法
而@babel/runtime是通过引入一个_reduce方法,然后将项目中的reduce方法替换成_reduce,减少了全局污染

@babel/plugin-transfrom-runtime 和 @babel/runtime

npm install --save-dev @babel/plugin-transform-runtime
npm install --save @babel/runtime

plugin-transform-runtime可以和polyfill或者runtime配合,它是用来分析文件需要的垫片,自动从polyfill或者runtime中获取并加入的
@babel/runtime 用来在生产环境中提供垫片
撒花✿✿ヽ(°▽°)ノ✿