babel-polyfill VS babel-runtime

背景

在項目迭代過程當中,由於有兼容 IE 的需求,根據文檔使用babel-polyfillbabel-runtime兩個插件解決問題。可是對於兩者之間的恩怨情仇,卻不甚瞭解,便打算細細探究一番。node

關於 Babel

若是咱們沒有配置一些規則,Babel 默認只轉換新的 JavaScript 句法(syntax),而不轉換新的 API,好比 Iterator、Generator、Set、Maps、Proxy、Reflect、Symbol、Promise 等全局對象,以及一些定義在全局對象上的方法(好比 Object.assign )都不會轉碼。 因此,當這樣的代碼出現時:webpack

const key = 'babel'
const obj = {
    [key]: 'foo',
}
複製代碼

Babel 默認會編譯成下面的代碼git

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的幫助函數,可是這個幫助函數僅僅在當前模塊中生效,所以其餘模塊中若是用到了一樣的語法,編譯後就會出現大量的重複代碼。github

babel-polyfill

原理是當運行環境中並無實現的一些方法,babel-polyfill 會給其作兼容。 可是這樣作也有一個缺點,就是會污染全局變量,並且項目打包之後體積會增大不少,由於把整個依賴包也搭了進去。因此並不推薦在一些方法類庫中去使用。web

用法

1. `npm install --save babel-polyfill`
2. 在應用的入口引用,以確保它可以最早加載:
`import "babel-polyfill";` 或者
`require("babel-polyfill");`
複製代碼

babel-runtime

爲了避免污染全局對象和內置的對象原型,可是又想體驗使用新鮮語法的快感。就能夠配合使用babel-runtimebabel-plugin-transform-runtime。 好比當前運行環境不支持promise,能夠經過引入babel-runtime/core-js/promise來獲取promise, 或者經過babel-plugin-transform-runtime自動重寫你的promise。也許有人會奇怪,爲何會有兩個runtime插件,實際上是有歷史緣由的:剛開始開始只有babel-runtime插件,可是用起來很不方便,在代碼中直接引入helper 函數,意味着不能共享,形成最終打包出來的文件裏有不少重複的helper代碼。因此,Babel又開發了babel-plugin-transform-runtime,這個模塊會將咱們的代碼重寫,如將Promise重寫成_Promise(只是打比方),而後引入_Promise helper函數。這樣就避免了重複打包代碼和手動引入模塊的痛苦。npm

用法

1. `npm install --save-dev babel-plugin-transform-runtime`
2. `npm install --save babel-runtime`
3. 寫入 `.babelrc`
複製代碼
{
  "plugins": ["transform-runtime"]
}
複製代碼

啓用插件babel-plugin-transform-runtime後,Babel就會使用babel-runtime下的工具函數,轉譯代碼以下:json

'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');
複製代碼

不足

babel-runtime 不能轉碼實例方法,好比這樣的代碼:promise

'!!!'.repeat(3);
'hello'.includes('h');
複製代碼

這隻能經過 babel-polyfill 來轉碼,由於 babel-polyfill 是直接在原型鏈上增長方法。babel

And more

隨着歷史進程的發展,新一代的 babel-prenset-env 很強大,瞭解一下😜函數

參考連接

自由轉載-非商用-非衍生-保持署名(創意共享3.0許可證

相關文章
相關標籤/搜索