ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

core-js-builder 实战指南:按目标环境定制 core-js 按需构建 Polyfill 包

core-js-builder 实战指南:按目标环境定制 core-js 按需构建 Polyfill 包 core-js-builder 实战指南按目标环境定制 core-js 按需构建 Polyfill 包【免费下载链接】core-jsStandard Library项目地址: https://gitcode.com/GitHub_Trending/co/core-js本篇指南围绕 core-js-builder 展开讲解如何通过编程式 API 从core-js中按需挑选模块、排除不需要的特性并结合core-js-compat的兼容性数据与 browserslist 查询为指定引擎版本构建定制化的 polyfill 产物。读完本文你将掌握modules、exclude、targets、summary、format、filename等全部选项的用法与底层执行原理能够为项目生成体积最小、恰好满足目标环境需求的 polyfill 脚本。一、为什么需要 core-js-buildercore-js作为标准库的 polyfill 集合包含了 ES 标准提案、Web 标准等多达数百个独立模块本仓库 packages/core-js/modules 下即有数百个.js模块文件。直接全量引入会带来不必要的体积开销而有些场景下我们只希望为特定的目标引擎例如老版本 IE、特定版本的 iOS Safari补齐缺失的 API。core-js-builder正是为这类场景设计的构建入口它接收与core-js-compat同格式的modules、exclude、targets选项详见 core-js-compat 说明通过 webpack 将选中的模块打包成一个自包含的脚本文件或者生成一组import/require语句。其能力可概括为条件包含只打包你需要的core-js特性模块条件排除黑名单机制剔除不需要的特性例如体积敏感的es.math.*按目标构建传入 browserslist 查询或环境版本对象自动只打包目标环境缺失的 polyfill。二、快速上手最小示例core-js-builder提供的是异步 API返回 Promise 字符串。在浏览器/现代构建流程中可以直接import注意包类型为 CommonJS见 package.json 中的type: commonjs。import builder from core-js-builder; const bundle await builder({ // 入口 / 模块 / 命名空间 / 上述的数组默认情况下为全部 core-js 模块 modules: [core-js/actual, /^esnext\.reflect\./], // 条目 / 模块 / 命名空间的黑名单默认情况下为空列表 exclude: [/^es\.math\./, es.number.constructor], // 可选的 browserslist 或 core-js-compat 格式查询 targets: 0.5%, not dead, ie 9-11, // 显示打包摘要默认关闭 summary: { // 在控制台输出可指定需要的部分或设为 true 全部开启 console: { size: true, modules: false }, // 在目标文件头部注释中输出用法同 summary.console comment: { size: false, modules: true }, }, // 输出格式默认为 bundle可为 cjs 或 esm // 此时结果不会被打包而是包含所需模块的导入语句 format: bundle, // 可选的目标文件名缺省时不会创建文件 filename: PATH_TO_MY_COREJS_BUNDLE, });在 TypeScript 中使用时需要将esModuleInterop设置为true。返回值与文件产出当filename省略时函数不写任何文件仅返回打包后的脚本字符串方便你在内存中继续加工如注入到自定义 loader当提供filename时会自动创建文件所在的目录底层调用mkdirp并写入结果同时返回值仍包含完整脚本。三、选项详解与源码级原理1.modules控制打包哪些模块modules支持三种筛选形式且可混用为数组对应 compat.js 的getModules逻辑入口点字符串如core-js/actual会展开为该入口覆盖的全部模块由core-js-compat/entries映射模块名前缀字符串如esnext.reflect.匹配所有以该前缀开头的模块名正则表达式如/^es\.math\./对完整模块名做test匹配。默认值为null此时等价于打包core-js-compat中的全部模块allModules。注意若某个过滤器匹配不到任何模块会抛出TypeError: Specified invalid module name or pattern: ...避免拼写错误被静默吞掉。2.exclude黑名单剔除exclude与modules使用同样的筛选语法字符串前缀、入口、正则、数组。在 compat.js 中先归一化 exclude 集合再从候选模块列表中过滤掉命中的项。典型用法是剔除体积大或业务不需要的模块exclude: [/^es\.math\./, es.number.constructor]顺带一提core-js-builder的 index.js 中还保留了一个已过时计划在core-js4移除的blacklist参数作为exclude的别名新代码请直接使用exclude。3.targets按目标环境裁剪targets可以是 browserslist 查询字符串也可以是描述各引擎最低支持版本的对象。构建时会先通过core-js-compat的checkModule逐模块比对兼容性数据若目标引擎版本低于模块所需版本则该模块被判为必需而进入打包列表若没有提供targets则默认全部模块都需要见 compat.js。对象形式的完整字段可参考 core-js-compat README例如targets: { android: 4.0, // Android WebView 版本 bun: 0.1.2, // Bun 版本 chrome: 38, // Chrome 版本 chrome-android: 18, // Android Chrome 版本 deno: 1.12, // Deno 版本 edge: 13, // Edge 版本 electron: 5.0, // Electron 版本 firefox: 15, // Firefox 版本 firefox-android: 4, // Android Firefox 版本 hermes: 0.11, // Hermes 版本 ie: 8, // Internet Explorer 版本 ios: 13.0, // iOS Safari 版本 node: current, // Node.js 版本current 表示当前运行的版本 opera: 12, // Opera 版本 opera-android: 7, // Android Opera 版本 phantom: 1.9, // PhantomJS 版本 quest: 5.0, // Meta Quest 浏览器版本 react-native: 0.70, // React Native 版本默认 Hermes 引擎 rhino: 1.7.13, // Rhino 引擎版本 safari: 14.0, // Safari 版本 samsung: 14.0, // Samsung Internet 版本 esmodules: true | intersect, // true 时忽略 browsers 目标intersect 时取 browsers 目标与 browserslist 目标的交集并取较大版本 browsers: 0.25%, // Browserslist 查询或目标浏览器对象 }在 targets-parser.js 中可以看到底层处理细节browsers字段会交给browserslist()解析为引擎版本列表esmodules: true会引入支持 ES Modules 的最低版本集合数据来自externalnode: current会被替换为process.versions.node。同时browserslist 别名如ios_saf、and_chr、ie_mob会被统一映射到内部引擎名非法引擎名会被过滤同一引擎的多个版本取最小值。4.format三种输出形态format决定产物的组织形式可选值为bundle默认、cjs、esm非法值会直接抛出TypeError(Incorrect output type)bundle通过 webpack 将所需模块打包为单个 IIFE 脚本自包含、可直接用script引入。打包时index.js会以mode: none、hashFunction: md5配置 webpack入口为core-js/modules/name解析路径产物生成在临时目录并读回后删除临时文件同时对__webpack_require__做压缩处理cjs不打包输出一串require(core-js/modules/name);语句适合在 Node.js / CommonJS 环境中直接 import 使用esm不打包输出一串import core-js/modules/name.js;语句适合接入现代打包器进一步 tree-shaking。后两种格式只是模块引用列表体积极小且不包含执行逻辑——真正的 polyfill 代码仍由core-js本体提供。5.summary打包摘要报告summary分为console与comment两个通道每个通道可设为布尔值或{ size, modules }对象设为truesize与modules全部开启设为对象仅开启指定项默认关闭{}。console 通道会在控制台输出彩色摘要size打印产物体积KBmodules逐行列出每个模块名若提供了targets还会附带该模块对应的引擎版本 JSON见 index.js。comment 通道则把信息写进输出文件头部的注释块size追加size: x.xxKB w/o commentsmodules追加逐行模块清单。方便日后排查这个 bundle 里到底装了哪些 polyfill。6.filename写出产物文件可选。提供时自动mkdirp创建父目录并写入最终脚本含 banner 注释缺省时仅返回字符串。banner 由 config.js 生成包含core-js版本号、版权声明、许可证与源码链接例如/** * core-js 3.50.0 * © 2013–2025 Denis Pushkarev (zloirock.ru), 2025–2026 CoreJS Company (core-js.io). All rights reserved. * license: ... * source: https://github.com/zloirock/core-js */四、完整的实战组合示例以下示例展示如何为需要支持现代浏览器 ES Modules、同时兼容 IE 9-11的场景构建一个定制 bundle并输出体积与模块清单报告import builder from core-js-builder; import { writeFileSync } from node:fs; const code await builder({ modules: [core-js/actual, /^web\./, esnext.observable], exclude: [/^es\.math\./, /^es\.reflect\./, es.array.flat], targets: { browsers: 0.5%, not dead, ie: 9, }, format: bundle, summary: { console: { size: true, modules: true }, comment: { size: true, modules: false }, }, filename: ./dist/my-corejs-bundle.js, }); // 返回值同样可用例如再手动追加一段自定义代码 writeFileSync(./dist/my-corejs-bundle.custom.js, code \n// custom tail\n);运行后控制台会输出类似bundling ./dist/my-corejs-bundle.js, size: 87.42KB bundling ./dist/my-corejs-bundle.js, modules: es.array.push for {ie:9} es.string.trim for {ie:9} ...若某个模块在目标环境下并不缺失它不会出现在列表中若所有目标环境都不缺任何模块例如只针对最新 Nodesummary.console.modules会打印nothing此时产物可能只包含 banner。五、构建流程的内部原理一次builder()调用的完整执行链路如下对应 index.js 与 compat.js参数校验与归一化校验format合法性将summary两个通道统一为{ size, modules }布尔对象模块筛选调用core-js-compat的compat({ targets, modules, exclude })内部依次完成 exclude 归一化、模块列表交集计算、proposal 稳定化过滤filterOutStabilizedProposals、按 targets 逐模块判定必需性最终返回{ list, targets }按 format 生成代码bundlewebpack 以选中模块为多入口打包 → 读取临时产物 → 包裹为!function (undefined) { use strict; ... }();IIFEcjs/esm分别生成require(...)/import ...语句序列附加 banner 与摘要将 banner 置于最前按summary.comment追加注释按summary.console打印报告可选写文件filename存在时创建目录并写入最后返回完整脚本字符串。这一流程在 tests/builder/builder.mjs 中有直接验证测试用modules: core-js/actual、exclude: [/group-by/, esnext.typed-array.to-spliced]、targets: { node: 16 }、format: esm构建并断言结果中包含es.error.cause、es.array.push、esnext.array.group、web.structured-clone等模块的 import 语句同时不包含es.weak-set、esnext.weak-set.from、被排除的esnext.array.group-by等。这个测试清晰地演示了入口展开 黑名单排除 按目标裁剪三者协同的预期行为。六、使用注意事项TypeScript启用esModuleInterop才能直接import builder from core-js-builder包自带类型声明 index.d.ts其中完整定义了Format、SummaryEntry、Summary等类型Node.js 版本包声明engines.node 8.9.0代码中刻意避开了fs.promises与mkdir的recursive选项以兼容旧版 Node源码中留有TODO: replace ... after dropping NodeJS 10 support注释运行时依赖构建过程依赖core-js、core-js-compat两者均锁定为同版本3.50.0、webpack4.47.0 5与mkdirp这些是打包期依赖产物本身是自包含脚本无需运行时携带正则过滤的命名空间约定es.、esnext.、web.、stage.等前缀分别对应标准已定稿特性、提案特性、Web 标准与 Stage 提案模块可据此写出精确的包含/排除模式可对照 packages/core-js/modules 与 packages/core-js/proposals 下的实际模块命名确认targets缺省意味着打包全部所选模块此时体积最大务必在发布到生产环境前明确指定目标环境。七、与其他包的分工core-js-builder处于本仓库工具链的构建出口位置core-js提供全部 polyfill 模块实现core-js-compat提供某个模块在某个引擎版本下是否需要的兼容性数据与查询 API而core-js-builder将两者组合按需产出最终脚本。若你只需要查询某环境下需要哪些模块而不需要打包可直接使用core-js-compat的compat({ targets, modules, version, inverse })获得模块清单与逐模块目标版本映射完整 API 见 core-js-compat 说明这也正是builder内部第 2 步所调用的能力。【免费下载链接】core-jsStandard Library项目地址: https://gitcode.com/GitHub_Trending/co/core-js创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表