Babel編譯轉(zhuǎn)碼的范圍
Babel默認(rèn)只轉(zhuǎn)換新的JavaScript語法沪铭,而不轉(zhuǎn)換新的API。 例如赔退,Iterator硕旗、Generator创译、Set软族、Maps互订、Proxy屹耐、Reflect瓢剿、Symbol桥氏、Promise 等全局對(duì)象字支,以及一些定義在全局對(duì)象上的方法(比如 Object.assign)都不會(huì)轉(zhuǎn)譯揖庄。 如果想使用這些新的對(duì)象和方法蹄梢,則需要為當(dāng)前環(huán)境提供一個(gè)polyfill
babel-polyfill
目前最常用的配合Babel一起使用的polyfill是babel-polyfill禁炒,它會(huì)”加載整個(gè)polyfill庫”幕袱,針對(duì)編譯的代碼中新的API進(jìn)行處理凹蜂,并且在代碼中插入一些幫助函數(shù)玛痊。
比如說:代碼中包含
const key = 'babel'
const obj = {
[key]: 'polyfill',
}
使用babel-polyfill配合轉(zhuǎn)碼后,代碼會(huì)變成這樣
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: 'polyfill' }));
babel-runtime
babel-polyfill解決了Babel不轉(zhuǎn)換新API的問題,但是直接在代碼中插入幫助函數(shù)蒿涎,會(huì)導(dǎo)致污染了全局環(huán)境劳秋,并且不同的代碼文件中包含重復(fù)的代碼玻淑,導(dǎo)致編譯后的代碼體積變大。 (比如:上述的幫助函數(shù)_defineProperty有可能在很多的代碼模塊文件中都會(huì)被插入)
Babel為了解決這個(gè)問題箫锤,提供了單獨(dú)的包babel-runtime用以提供編譯模塊的工具函數(shù)谚攒, 啟用插件babel-plugin-transform-runtime后五鲫,Babel就會(huì)使用babel-runtime下的工具函數(shù)位喂,上述的代碼就會(huì)變成這樣
var _defineProperty2 = __webpack_require__("./node_modules/babel-runtime/helpers/defineProperty.js");
var _defineProperty3 = _interopRequireDefault(_defineProperty2);
var _assign = __webpack_require__("./node_modules/babel-runtime/core-js/object/assign.js");
var _assign2 = _interopRequireDefault(_assign);
function _interopRequireDefault(obj) {
return obj && obj.__esModule ? obj : { default: obj };
}
var key = 'babel';
var obj = (0, _defineProperty3.default)(
{}, key, (0, _assign2.default)({}, { key: 'polyfill' })
);
可以看到上述轉(zhuǎn)換后的代碼中_defineProperty幫助函數(shù)是通過babel-runtime下的模塊引用的痛倚, 同時(shí)Object.assign也變成了模塊引用, 這樣可以避免自行引入polyfill時(shí)導(dǎo)致的污染全局命名空間的問題抒蚜。
配置
使用babel-polyfill需要額外安裝babel-polyfill依賴包嗡髓, 然后在webpack配置文件中的入口或者公共模塊中加入’babel-polyfill’即可浊伙,代碼如下:
entry: {
common: [
`babel-polyfill`,
`whatwg-fetch`,
`react`,
`react-dom`,
`redux`,
`react-redux`,
`js-cookie`,
],
},
使用babel-runtime需要額外安裝babel-runtime和babel-plugin-transform-runtime依賴包, 然后在.babelrc配置文件中啟用transform-runtime, 代碼如下:
{
"presets": [
"es2015",
"react",
"stage-0"
],
"plugins": [
"transform-runtime"
]
}
比較
babel-polyfill與babel-runtime相比雖然有各種缺點(diǎn)哑子,但在某些情況下仍然不能被babel-runtime替代, 例如烦却,代碼:[1, 2, 3].includes(3),Object.assign({}, {key: 'value'})摩渺,Array摇幻,Object以及其他”實(shí)例”下es6的方法绰姻,babel-runtime是無法支持的, 因?yàn)閎abel-runtime只支持到static的方法帜矾。
結(jié)論
babel-runtime適合在組件珍剑,類庫項(xiàng)目中使用,而babel-polyfill適合在業(yè)務(wù)項(xiàng)目中使用。
參考:https://stackoverflow.com/questions/31781756/is-there-any-practical-difference-between-using-babel-runtime-and-the-babel-poly
vue-cli腳手架中使用
babel-polyfill
在main.js中引用babel-polyfill
import 'babel-polyfill'
bable-runtime
在.babelrc文件中使用
{
"presets": [
["env", {
"modules": false,
"targets": {
"browsers": ["> 1%", "last 2 versions", "not ie <= 8"]
}
}],
"stage-2"
],
"plugins": ["transform-vue-jsx", "transform-runtime"],
"env": {
"test": {
"presets": ["env", "stage-2"],
"plugins": ["transform-vue-jsx", "transform-es2015-modules-commonjs", "dynamic-import-node"]
}
}
}