babel7发布了。
在升级到 Babel 7 时须要注意几个重大变化:javascript
官方提供了一个工具babel-upgrade,对于老项目,只须要执行:
npx babel-upgrade --write --install
具体看https://github.com/babel/babel-upgradejava
babel的polyfill老是比较大,会影响一些性能,并且也会有一些没用的polyfill,怎么减小polyfill的大小呢?
babel7提供了useBuiltIns的按需加载:usage。
配置中设置useBuiltIns:usage,babel就会自动把所需的polyfill加载进来,不须要手动import polyfill文件。
配置如:react
{ "presets": [ "@babel/preset-react", ["@babel/env", { "targets": { "browsers": ["> 1%", "last 2 versions", "not ie <= 8"] }, "useBuiltIns": "usage", "debug": true }] ], "plugins": ["@babel/transform-runtime"] }
babel提供的@babel/env全面替换es2015,stage插件。(若是用到stage的某些插件须要自行引入。我的感受stage用起来太不方便了)。
以前的babel-preset-env/babel-preset-react全都更名为@babel/xxx,若是在babel7你还按以前的写法,会报错:
Error: Plugin/Preset files are not allowed to export objects, only functions.
git
看下useBuiltIns:usage的效果。"debug"选项开到true,能够看到打包的文件。es6
我用es6摘抄了一些语法,用来测试编译:github
const a = Object.assign({}, { a: 1 }); console.log(a); function timeout(ms) { return new Promise((resolve) => { setTimeout(resolve, ms); }); } async function asyncPrint(value, ms) { await timeout(ms); console.log(value); } let s = Symbol(); typeof s; class ColorPoint { constructor(x, y, color) { this.color = color; } toString() { return this.color + ' ' + super.toString(); // 调用父类的toString() } } asyncPrint('hello world', 50); function* helloWorldGenerator() { yield 'hello'; yield 'world'; return 'ending'; } var hw = helloWorldGenerator(); console.log(hw.next());
babel编译以后,能够看到加载的polyfill只加载了 es6.object.assign,es6.promise, es6.symbol,es7.symbol.async-iterator , regenerator-runtime。json
根据咱们填的"targets",babel会去查用到的api,当前的target环境支持什么不支持什么,不支持的才加polyfill。api
能够看到咱们编译后的文件已经加了polyfill。promise
文件大小和性能都有不少提升。浏览器
useBuiltIns:entry就没有那么智能了,他会根据target环境加载polyfill,他须要手动import polyfill,不能屡次引入。
@babel/preset-env会将把@babel/polyfill根据实际需求打散,只留下必须的。作的只是打散。仅引入有浏览器不支持的polyfill。这样也会提升一些性能,减小编译后的polyfill文件大小。
main.js须要引入polyfill。import '@babel/polyfill';
。
能够看到效果。我只截了部分polyfill依赖。
编译后的文件引入了一堆polyfill。
只用polyfill不是最完美的方案。
polyfill会额外引入一些函数,好比:
由于polyfill没有babel-runtime的helper函数,在编译async
函数的时候,会引入以上的代码asyncGeneratorStep
,_asyncToGenerator
。
若是你每一个文件都用到了async,那么冗余的代码将会很大。
最佳方案就是在用polyfill的同时,再用babel-runtime。
babel-runtime会把asyncGeneratorStep
,_asyncToGenerator
等函数require进来。从而减少冗余。
这得益于babel-runtime的helper函数。
因此最佳的配置是polyfill+babel-runtime。
若是用了react能够加@babel/preset-react。
{ "presets": [ "@babel/preset-react", ["@babel/env", { "targets": { "browsers": ["last 2 versions", "ie 11"] }, "useBuiltIns": "usage" }] ], "plugins": ["@babel/transform-runtime"] }
能够看到,_asyncToGenerator2已被require。