最新消息:看到那些跳动的图片、文字了吗?点击点击 O(∩_∩)O~~

babel-runtime 与 babel-polyfill

若思若想 onlyling 2863浏览

开发背景

最近终于在项目里面用上了 React,在打包的时候发现,有同事把 babel-polyfill 加上了,当时已经在 webpack 中配置了 babel-runtime,觉得应该不会需要这个东西。查找了一些资料,发觉这两个并不一样。

Babel 默认不转码的API非常多,详细清单可以查看 babel-plugin-transform-runtime 模块的 definitions.js 文件。

关于 Babel

如果我们没有配置一些规则,Babel 默认只转换新的 JavaScript 句法(syntax),而不转换新的 API,比如 Iterator、Generator、Set、Maps、Proxy、Reflect、Symbol、Promise 等全局对象,以及一些定义在全局对象上的方法(比如 Object.assign )都不会转码。

所以,当这样的代码出现时:

const key = 'babel'
const obj = {
    [key]: 'foo',
}

Babel 默认会编译成下面的代码

function _defineProperty(obj, key, value) {
    if (key in obj) {
        Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true });
    } else {
        obj[key] = value;
    }
    return obj;
}

var key = 'babel';
var obj = _defineProperty({}, key, Object.assign({}, { key: 'foo' }));

我们可以看到代码中多了一个名为_defineProperty的帮助函数,但是这个帮助函数仅仅在当前模块中生效,因此其他模块中如果用到了同样的语法,编译后就会出现大量的重复代码。

babel-polyfill

polyfill 应该不陌生,在使用一些比较新的 API 的时候,总会看到 xxx-polyfill 的库。其他就是针对低版本、没有该 API 浏览器、环境的一种兼容。

原理是当运行环境中并没有实现的一些方法,babel-polyfill 会给其做兼容。 但是这样做也有一个缺点,就是会污染全局变量,而且项目打包以后体积会增大很多,因为把整个依赖包也搭了进去。所以并不推荐在一些方法类库中去使用。

如果想使用这些新的对象和方法,必须使用 babel-polyfill,为当前环境提供一个垫片。

babel-runtime

为了不污染全局对象和内置的对象原型,但是又想体验使用新鲜语法的快感。就可以配合使用 babel-runtime 和 babel-plugin-transform-runtime。

比如当前运行环境不支持 Promise,可以通过引入 babel-runtime/core-js/promise 来获取 Promise,或者通过 babel-plugin-transform-runtime自 动重写你的 Promise。

启用插件 babel-plugin-transform-runtime 后,Babel就会使用 babel-runtime 下的工具函数,转译代码如下:

'use strict';

var _defineProperty2 = require('babel-runtime/helpers/defineProperty');

var _defineProperty3 = _interopRequireDefault(_defineProperty2);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var key = 'babel';
var obj = (0, _defineProperty3.default)({}, key, 'foo');

翻译自官网:runtime transformer plugin 做3件事:

  • 当使用 generators/async 功能时,自动添加 babel-runtime/regenerator
  • 自动添加 babel-runtime/core-js 并且映射ES6静态方法和内置方法
  • 移除内联的 Babel 帮助代码并使用 babel-runtime/helpers 模块来替代简单来说,基本上你可以使用内置函数如 Promise,Set,Symbol 等;也可以无缝地使用需要 polyfill 的所有 Babel 特性,而不会污染全局,对于库来说很实用。一定要把 babel-runtime 作为依赖引入!

转载请注明:OnlyLing - Web 前端开发者 » babel-runtime 与 babel-polyfill