build_babel - zen0822/interview GitHub Wiki
Plugins
箭头函数已经被转成常规函数了。Babel 的转换的核心其实就是 plugin,按照配置文件里 plugins 配置的顺序执行。类似函数式编程中的 compose,假设我们有如下配置
module.exports = {
plugins: [
'plugina',
'pluginb',
'pluginc',
],
};
转换的逻辑相当于执行了
pluginc(pluginb(plugina(source)));
@babel/plugin-transform-runtime
假设有 2 个文件都使用了 Class
src/a.js
class A {}
src/b.js
class B {}
Babel 配置
module.exports = {
presets: [
[
'@babel/preset-env',
{
useBuiltIns: 'usage',
corejs: 3,
},
],
],
};
目标环境 ie10 转换后的代码 lib/a.js
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
var A = function A() {
_classCallCheck(this, A);
};
lib/b.js
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
var B = function B() {
_classCallCheck(this, B);
};
很明显转换后的两个文件中 _classCallCheck 的定义是重复的,会导致打包的体积变大。这种样板代码可以通过 @babel/plugin-transform-runtime 解决。安装依赖
npm i @babel/plugin-transform-runtime @babel/runtime --save-dev
修改配置
module.exports = {
presets: [
[
'@babel/preset-env',
{
useBuiltIns: 'usage',
corejs: 3,
},
],
],
plugins: [
'@babel/plugin-transform-runtime',
],
};
转换后的代码
lib/a.js
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
var A = function A() {
(0, _classCallCheck2["default"])(this, A);
};
lib/b.js
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
var B = function B() {
(0, _classCallCheck2["default"])(this, B);
};
样板代码被转换成了 require 的方式,保证了引入的唯一。
Presets
Presets 就是 plugin 的默认集合。官方提供的 presets 中最重要的就是 env,默认已经包含了官方列举的 plugin 中的 ES3、ES5、ES2015~ES2021、Modules 等 plugin 集合。