core-js 模块直接在浏览器加载产生大量请求怎么解决:打包成单 bundle 上线
【免费下载链接】core-jsStandard Library项目地址: https://gitcode.com/GitHub_Trending/co/core-js
如果你的前端页面没有走本地打包器,而是通过<script>或模块加载器按文件逐个加载core-js,官方文档在 Usage 中已经明确指出了后果:core-js极度模块化,内部由大量极小的模块文件组成,"在浏览器中使用时应该把core-js打包,而不是为每个文件使用一个 loader,否则你会有几百个请求"(原文:for usage in browsers bundle upcore-jsinstead of a usage loader for each file, otherwise, you will have hundreds of requests)。
本文给出文档中支持的两条主路径:直接使用现成的单文件包core-js-bundle,或用core-js-builder按目标浏览器生成一个自有的单文件 bundle。两条路径的产物都是"浏览器只需要请求一个core-js文件",并给出文档中提供的验证方式。
为什么会产生几百个请求
Usage 文档 的 WARNING 部分解释了原因:core-js的每个入口(如core-js/actual/set/intersection、core-js/es/array/find-last)背后是一批互相依赖的小模块文件。按文件加载意味着每个模块都会发起独立请求。因此"打包"不是可选优化,而是浏览器场景下的默认要求。
同一节警告还给了两条与上线直接相关的约束,先记下来,后文会用到:
modules路径是内部 API,不注入全部依赖,且在 minor 或 patch 版本中可能变动,只建议在自定义构建时使用;- 如果用扩展原生对象的全局版
core-js,建议把所有core-js模块放在应用入口的最上方加载,否则可能产生冲突(文档举例:Google Maps 自带Symbol.iterator,会与Array.from、URLSearchParams等core-js模块冲突)。
方案一:直接使用现成的 core-js-bundle(最短路径)
Usage 文档 的安装部分列出了三个版本,其中 "bundled global version" 就是为浏览器单文件加载准备的:
npm install --save core-js-bundle@3.50.0core-js-bundle 包说明 对它的定位是一句话:"It's a bundled global version"——即把全局版core-js预先打包成的单文件版本,功能与import 'core-js/actual'等入口一致,浏览器只需加载这一个文件,不再出现逐模块请求。
这个方案适合"浏览器里直接上、不想自己跑构建"的场景;它的代价是拿到的是完整功能集,无法按目标浏览器裁剪(要裁剪见方案二)。
方案二:用 core-js-builder 按目标环境生成单 bundle
Usage 文档的 Custom build 一节 指出:要排除部分core-js功能、或针对目标引擎生成 polyfill 时,使用core-js-builder包。core-js-builder 的 README 给出了完整 API:
import builder from 'core-js-builder'; const bundle = await builder({ // entry / module / namespace / 它们的数组,默认是全部 `core-js` 模块 modules: ['core-js/actual', /^esnext\.reflect\./], // 黑名单:要排除的 entry / module / namespace,默认为空 exclude: [/^es\.math\./, 'es.number.constructor'], // 可选的 browserslist 或 core-js-compat 格式查询 targets: '> 0.5%, not dead, ie 9-11', // 显示 bundle 摘要,默认关闭 summary: { console: { size: true, modules: false }, comment: { size: false, modules: true }, }, // 输出格式,默认 'bundle';'cjs'/'esm' 则不打包,只输出模块导入列表 format: 'bundle', // 可选的目标文件名;不提供则不会创建文件 filename: './dist/core-js.bundle.js', });各选项与上线动作的对应关系(均以 README 原文为准):
modules决定 bundle 包含哪些功能,可以是 entry(如core-js/actual)、单个模块或正则,默认是全部core-js模块;targets传browserslist查询,builder 基于core-js-compat的数据只为目标引擎保留必需的模块;format保持默认'bundle',产物是一个自包含的单文件(README 明确:cjs/esm格式下"结果不会被打包,会包含对所需模块的 import",不能用于直接给浏览器加载);filename指向产物路径,文档示例中的PATH_TO_MY_COREJS_BUNDLE是占位符,替换成你自己的输出路径即可;不提供filename时不创建文件(此时只会把内容返回为bundle变量);- 使用 TypeScript 时 README 提醒要把
esModuleInterop设为true。
modules、exclude、targets三个参数都使用core-js-compat的格式,细节可在 core-js-compat 包 中查。
可选分支:由转译器随应用一起打包
如果你的工程本来就经过构建管线,文档推荐的优化路径是让转译器只保留目标环境需要的core-js模块,然后由 webpack/rollup 等 bundler 把core-js和你的业务代码打进同一个产物文件:
@babel/preset-env的useBuiltIns选项。用useBuiltIns: 'entry'时,import 'core-js/stable'会被替换为只针对目标的模块导入(Usage 文档 给出的文档示例:以chrome 71为目标时,import 'core-js/stable'被替换为core-js/modules/es.array.unscopables.flat等 4 个模块导入);useBuiltIns: 'usage'则按每个文件用到的特性自动注入模块导入,此时不要手动添加core-jsimport。文档同时建议把corejs选项写成小版本号(如corejs: '3.50')而不是corejs: 3,因为后者不会注入 minor 版本新增的模块;swc提供同样的entry/usage两种模式,Usage 文档 给出的.swcrc示例为:
{ "env": { "targets": "> 0.25%, not dead", "mode": "entry", "coreJs": "3.50" } }这条分支的前提是你已有 bundler;文档同时注明 swc 的usage模式目前不如babel完善。
验证打包结果
- 产物层面:
core-js-builder的summary选项就是文档给出的核对手段——summary.console: { size: true, modules: true }会在构建时在控制台输出 bundle 大小和实际包含的模块清单,summary.comment会把同样的信息写进产物文件的注释里。开启summary后检查清单里是否只剩目标targets需要的模块,即可确认裁剪生效。 - 请求层面:按 Usage 文档 的标准,改造前浏览器对
core-js是"每文件一个 loader、几百个请求";改用core-js-bundle单文件或 builder 产物后,core-js在浏览器网络请求中应只体现为一个文件。 - 运行时层面:页面打开后确认你需要的特性可用即可(例如
core-js-bundle文档示例中的Array.from、flat等调用行为符合预期)。
上线时的限制与注意点
- 全局版
core-js会扩展原生对象,第三方库自带的同名 polyfill(文档提到Promisepolyfill 重复加载、Symbol.iterator冲突等案例)可能与它冲突;core-js模块统一放在入口最顶部加载,能按文档建议的"发现并手动补入冲突 entry"方式处理冲突。 - 不要把
core-js/modules/...这种内部路径写进浏览器直接加载的代码,它是内部 API,可能随版本变动。 core-js-builder的targets依赖core-js-compat数据,构建出的 bundle 只覆盖你声明的目标引擎;目标范围变了需要重新构建,而不只是改页面引用。- 想进一步控制 polyfill 行为的,Usage 文档 的 "Configurable level of aggressiveness" 一节提供了
core-js/configurator(useNative/usePolyfill/useFeatureDetection),并明确说明它对部分特性不生效、改动了默认行为时连core-js内部实现也可能受影响。
更多包级别说明见 core-js-bundle 包说明 和根目录 README。
【免费下载链接】core-jsStandard Library项目地址: https://gitcode.com/GitHub_Trending/co/core-js
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考