babel7按需加载polyfill示例详解

Kathy ·
更新时间:2024-09-20
· 770 次阅读

目录

babel7

useBuiltIns:usage

效果

babel是怎么知道我们需要哪些polyfill的?

useBuiltIns:entry

最佳实践

babel-runtime

babel7

babel7发布了。

在升级到 Babel 7 时需要注意几个重大变化:

移除对 Node.js 6 之前版本的支持;

使用带有作用域的 @babel 命名空间,以防止与官方 Babel 包混淆;

移除年度预设,替换为 @babel/preset-env;

使用选择性 TC39 个别提案替换阶段提案;

TC39 提议插件现在是 -proposal,而不是 -transform;

为某些面向用户的包(例如 babel-loader、@babel/cli 等)在 @babel/core 中引入peerDependency。

官方提供了一个工具babel-upgrade,对于老项目,只需要执行:npx babel-upgrade --write --install

具体看 https://github.com/babel/babel-upgrade

useBuiltIns:usage

babel的polyfill总是比较大,会影响一些性能,而且也会有一些没用的polyfill,怎么减少polyfill的大小呢?

babel7提供了useBuiltIns的按需加载:usage。

配置中设置useBuiltIns:usage,babel就会自动把所需的polyfill加载进来,不需要手动import polyfill文件。

配置如:

{ "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.

效果

看下useBuiltIns:usage的效果。"debug"选项开到true,可以看到打包的文件。

我用es6摘抄了一些语法,用来测试编译:

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。

babel是怎么知道我们需要哪些polyfill的?

根据我们填的"targets",babel会去查用到的api,当前的target环境支持什么不支持什么,不支持的才加polyfill。

可以看到我们编译后的文件已经加了polyfill。

文件大小和性能都有很多提高。

useBuiltIns:entry

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,那么冗余的代码将会很大。

babel-runtime

最佳方案就是在用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。

以上就是babel7按需加载polyfill示例详解的详细内容,更多关于babel7按需加载polyfill的资料请关注软件开发网其它相关文章!



babel

需要 登录 后方可回复, 如果你还没有账号请 注册新账号
相关文章