在項目迭代過程當中,由於有兼容 IE 的需求,根據文檔使用babel-polyfill
和babel-runtime
兩個插件解決問題。可是對於兩者之間的恩怨情仇,卻不甚瞭解,便打算細細探究一番。node
若是咱們沒有配置一些規則,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 會給其作兼容。 可是這樣作也有一個缺點,就是會污染全局變量,並且項目打包之後體積會增大不少,由於把整個依賴包也搭了進去。因此並不推薦在一些方法類庫中去使用。web
1. `npm install --save babel-polyfill`
2. 在應用的入口引用,以確保它可以最早加載:
`import "babel-polyfill";` 或者
`require("babel-polyfill");`
複製代碼
爲了避免污染全局對象和內置的對象原型,可是又想體驗使用新鮮語法的快感。就能夠配合使用babel-runtime
和babel-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
隨着歷史進程的發展,新一代的 babel-prenset-env 很強大,瞭解一下😜函數
自由轉載-非商用-非衍生-保持署名(創意共享3.0許可證)