前端工程化-webpack篇之babel-polyfill與babel-runtime(三)

關於 Babel

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

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

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

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

babel-polyfill

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

用法

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函數。這樣就避免了重複打包代碼和手動引入模塊的痛苦。函數

用法

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下的工具函數,轉譯代碼以下:工具

'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 不能轉碼實例方法,好比這樣的代碼:ui

'!!!'.repeat(3);  
'hello'.includes('h');

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

相關文章
相關標籤/搜索