最近尝试把厂里项目的依赖从 babel@6 升级到 babel@7,发现打包之后体积大了很多。于是打开 webpack-bundle-analyzer
,果然大部分代码都是 corejs 引入的,项目本身的逻辑只占少部分。
从报告来看,虽然目标浏览器的版本均高于 Promise 的启动版本(比如 Chrome 32),但 es.promise
仍然会被打包进来。于是以 es.promise
为突破口开始分析,找到答案:因为 JavaScript 引擎 V8 直至 v6.6 版本时,在 Promise 实现方面都存在严重 bug,所以 babel@7 保守地选择 Chrome 66/67 作为临界点。
想来其它体积多半也是这么加上来的,就不再一个一个排查了。
这就很难处理。不升级吧,新特性兼容不了;升级吧,包体积变大,公司上层又未必同意。
下一步试试 esbuild 吧,或者回头手动打包一套 polyfill。目前设想的方案是:
- 用 babel 之类的工具提取出所有特性
- 根据 caniuse 生成必须的特性列表
- 像上面说的 Promise,因为 bug 所以必须兼容,我们就不考虑了,可以反过来加一条 eslint 规则规避
- 最终生成新的 polyfill 打包进来
参考连接:
- New Babel release creates too many `require()` and polyfills · Issue #9736 · babel/babel (github.com)
- 想知道按照 corejs 标准,哪些特性需要哪些浏览器支持,可以查阅:core-js/data.mjs at master · zloirock/core-js (github.com)
- 如果想知道 Android、node.js、chrome 之间的版本对应关系,可以查阅:core-js/mapping.mjs at master · zloirock/core-js (github.com)
欢迎吐槽,共同进步