Babel 7.4.0 编译配置

730 阅读2分钟

​ Babel 是一个 JS 编译器(输入源码 source code =》 输出编译后的代码 output code)。编译过程分为三个阶段:解析(parsing)、转换(transforming)和打印输出(printing)。

​ 如果没有任何插件,执行 ./node_modules/.bin/babel src --out-dir lib,结果类似于 cont babel = code => code,即代码解析后再输出同样的代码。如果想实现转换(transforming)的功能,我们就需要添加插件。

​ 除了一个个添加插件,我们可以使用预设(a preset)——一系列插件的组合。

代码分析

class A {}	// syntax transforms
class B {}	// syntax transforms

const p = new Promise((resolve, reject) => {}); // polyfills-supports global variables => core-js@2
Array.from('foo'); // polyfills-supprots static properties =>core-js@2

[1, 2, 3].includes(1); // polyfills-supports instance properties => core-js@3

function* foo() { }; // after syntax transforms,polyfills-supports genetators/async/await functions => regenerator-runtime/runtime

Step1. Syntax transforms

解决这个问题的方法是使用preset——@babel/preset-env。主要功能是根据配置的目标环境(包括浏览器环境和node环境)自动将输入的源码转化为兼容目标环境的代码。

###安装

npm install --save-dev @babel/preset-env

使用

// package.json
{
  "browserslist": "> 0.25%, not dead"
}

// .babelrc配置文件
{
  "presets": ["@babel/preset-env"]
}

Step2. Polyfills

安装

npm install --save core-js@3

npm install --save regenerator-runtime

###使用

// .babelrc配置文件
{
  "presets": [[
    "@babel/preset-env", {
      "useBuiltIns": "usage",	//entry:全部polyfills引入;usage:使用到pollyfills引入
      "corejs": 3
    }]],
}

Note: useBuiltIns 的默认配置是 false,即不引入pollyfills。useBuiltIns 配置是 entry 时,需要 import "core-js";import "regenerator-runtime/runtime";在入口文件。useBuiltIns 配置 usage 时,会自动检测代码中用到的功能自动引入模块,当模块未安装,则会报错。

Step3. Problems

问题1:我在项目中定义了跟规范不一致的Promise函数,同时引入了一个库 core-js,这个库可能覆盖自定义的Promise函数,导致出错。优化后我们希望达到的效果,不污染全局和内置对象原型:

// corejs: false
"use strict";

var a = new Promise();
[1, 2, 3].includes(1);

// corejs: 2
"use strict";

var _interopRequireDefault = require("@babel/runtime-corejs2/helpers/interopRequireDefault");

var _promise = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/promise"));

var a = new _promise["default"]();
[1, 2, 3].includes(1);

// corejs: 3
"use strict";

var _interopRequireDefault = require("@babel/runtime-corejs3/helpers/interopRequireDefault");

var _includes = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/instance/includes"));

var _promise = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/promise"));

var _context;

var a = new _promise["default"]();
(0, _includes["default"])(_context = [1, 2, 3]).call(_context, 1);

问题2:多文件时编译生成多次相同的工具函数,例如

// 优化前
class Circle {}

function _classCallCheck(instance, Constructor) {
  //...
}

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

// 优化后
var _classCallCheck = require("@babel/runtime/helpers/classCallCheck");

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

如下为解决问题的方法:

安装

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

npm install --save @babel/runtime or npm insall --save @babel/runtime-corejs2 or npm insall --save @babel/runtime-corejs3

Note: 根据个人需要选择材料。@babel/runtime is a library that contain's Babel modular runtime helpers and a version of regenerator-runtime. @babel/runtime-corejs2 is a library that contain's Babel modular runtime helpers and a version of regenerator-runtime as well as core-js@2. @babel/runtime-corejs3 is a library that contain's Babel modular runtime helpers and a version of regenerator-runtime as well as core-js@3.

使用

//.babelrc配置文件
{
  "presets": [[
    "@babel/preset-env", {
      "useBuiltIns": "usage",
      "corejs": 3
    }]],
  "plugins": [["@babel/plugin-transform-runtime", {"corejs": 3}]]
}