@babel/plugin-transform-runtime
1、自动引入辅助函数
首先创建一个原始文件
typescript
export class D {
d = 0;
constructor() {
this.d = 111;
}
}
使用 @babel/preset-env 转换
javascript
/** ---------------- babel.config.js --------------- */
module.exports = {
presets: ['@babel/preset-env']
};
/** -------------------- 转换后的文件 ----------------------- */
function _classCallCheck(instance, Constructor) {
/** xxx */
}
function _defineProperties(target, props) {
/** xxx */
}
function _createClass(Constructor, protoProps, staticProps) {
/** xxx */
}
var D = /*#__PURE__*/ _createClass(function D() {
_classCallCheck(this, D);
this.d = 0;
this.d = 111;
});
export { D };
我们可以看到 @babel/preset-env
在处理语法转换时会注入很多辅助函数(_classCallCheck、_createClass
等),如果项目文件很多,会导致体积十分庞大
为了解决这个问题,@babel/runtime
出现了,它将这些辅助函数整合到了一起。我们可以通过包引用
javascript
var _classCallCheck = require('@babel/runtime/helpers/classCallCheck');
var _defineProperties = require('@babel/runtime/helpers/defineProperty');
/** xxx */
这样解决了代码复用的问题,但是每次手动引入过于麻烦,于是 @babel/plugin-transform-runtime
登场,我们可以用它来自动导入
javascript
module.exports = {
presets: ['@babel/preset-env'],
plugins: ['@babel/plugin-transform-runtime']
};
/** -------------------- 转换后的文件 ----------------------- */
var _interopRequireDefault = require('@babel/runtime/helpers/interopRequireDefault');
Object.defineProperty(exports, '__esModule', {
value: true
});
exports.D = void 0;
var _createClass2 = _interopRequireDefault(
require('@babel/runtime/helpers/createClass')
);
var _classCallCheck2 = _interopRequireDefault(
require('@babel/runtime/helpers/classCallCheck')
);
var _defineProperty2 = _interopRequireDefault(
require('@babel/runtime/helpers/defineProperty')
);
var D = /*#__PURE__*/ (0, _createClass2.default)(function D() {
(0, _classCallCheck2.default)(this, D);
(0, _defineProperty2.default)(this, 'd', 0);
this.d = 111;
});
exports.D = D;
2、为类库打包增加 Polyfill
在开发类库的时候,也会用到一些新语法,需要有对应的 Polyfill,但是如果项目中不存在该怎么办呢?我们又不能在组件层注入全局 Polyfill (不想组件影响项目) 因此 @babel/plugin-transform-runtime
提供了局部 Polyfill 的方法。
创建源文件
javascript
export const a = new Promise((resolve, reject) => {
resolve(true);
});
export async function asyncFn() {
await a;
}
按照默认配置进行代码转换
javascript
/** ---------------- babel.config.js --------------- */
module.exports = {
presets: ['@babel/preset-env'],
plugins: ['@babel/plugin-transform-runtime']
};
/** -------------------- 转换后的文件 ----------------------- */
var _interopRequireDefault = require('@babel/runtime/helpers/interopRequireDefault');
Object.defineProperty(exports, '__esModule', {
value: true
});
exports.a = void 0;
exports.asyncFn = asyncFn;
var _regenerator = _interopRequireDefault(
require('@babel/runtime/regenerator')
);
var _asyncToGenerator2 = _interopRequireDefault(
require('@babel/runtime/helpers/asyncToGenerator')
);
var a = new Promise(function (resolve, reject) {
resolve(true);
});
exports.a = a;
function asyncFn() {
/** xxx */
}
根据转换后的代码可以发现,Promise 仍然用的全局的,也就是项目中必须注入 Polyfill,否则类库会出错。
我们修改下配置,通过设置 core-js 来转换
javascript
/** ---------------- babel.config.js --------------- */
module.exports = {
presets: ['@babel/preset-env'],
plugins: [['@babel/plugin-transform-runtime', { corejs: 3 }]]
};
/** -------------------- 输出结果 ----------------------- */
var _Object$defineProperty = require('@babel/runtime-corejs3/core-js-stable/object/define-property');
var _interopRequireDefault = require('@babel/runtime-corejs3/helpers/interopRequireDefault');
_Object$defineProperty(exports, '__esModule', {
value: true
});
exports.a = void 0;
exports.asyncFn = asyncFn;
var _regenerator = _interopRequireDefault(
require('@babel/runtime-corejs3/regenerator')
);
var _asyncToGenerator2 = _interopRequireDefault(
require('@babel/runtime-corejs3/helpers/asyncToGenerator')
);
var _promise = _interopRequireDefault(
require('@babel/runtime-corejs3/core-js-stable/promise')
);
var a = new _promise.default(function (resolve, reject) {
resolve(true);
});
exports.a = a;
function asyncFn() {
/** xxx */
}
可以看到,现在转换后的 Promise 是一个从 @babel/runtime-corejs3/core-js-stable/promise 导入的局部变量
总结
- 删除内联的辅助函数,并自动从
@babel/runtime/helpers
中引入。 - 当代码里使用了新的 API、新的实例方法, 自动从引入
@babel/runtime-corejs3
引入 Polyfill,以此来替代从全局引入 Polyfill。
TIP
@babel/plugin-transform-runtime 引入的 polyfill 不会对全局造成污染,所以很适合作为类库的打包。