深入解析 @wordpress/babel-preset-default:WordPress/Gutenberg 官方 Babel 预设的配置、扩展与 Polyfill 机制
2026/9/16 23:20:59 网站建设 项目流程

深入解析 @wordpress/babel-preset-default:WordPress/Gutenberg 官方 Babel 预设的配置、扩展与 Polyfill 机制

【免费下载链接】gutenbergThe Block Editor project for WordPress and beyond. Plugin is available from the official repository.项目地址: https://gitcode.com/GitHub_Trending/gu/gutenberg

本文围绕 Gutenberg 仓库中的@wordpress/babel-preset-default展开,系统讲解这一官方 Babel 预设的安装、使用、扩展配置与 Polyfill 机制。读者在阅读后将掌握如何在 WordPress 插件、Gutenberg 扩展或任意 npm 项目中使用该预设,理解它内置的 ECMAScript 语言特性与 JSX/TypeScript 支持范围,并学会通过wp:polyfill魔法注释与build/polyfill.js完成浏览器兼容层的接入。

一、预设是什么:为 WordPress 开发定制的默认 Babel 配置

@wordpress/babel-preset-default是 WordPress 官方提供的默认 Babel 预设,属于 Gutenberg monorepo 中的一个独立 npm 包(版本 8.55.0,见 package.json)。它的职责是:当你的代码需要被 WordPress 生态(包括 Gutenberg 编辑器本身、插件、主题)运行时,由它统一决定哪些语言特性可以被转换、如何转换、以及如何注入运行时辅助代码。

它覆盖两类语法来源:

  • ECMAScript 提案:仅支持已进入 TC39 Stage 4("Finished") 中的相关章节)。
  • JSX 语法扩展:通过@babel/plugin-transform-react-jsxruntime: 'automatic'模式转换,无需手动引入React即可使用新的 JSX 转换。

从源码看预设的实际组成

查看预设的入口实现 index.js,可以看到最终输出的配置结构:

return { presets: [ getPresetEnv(), require.resolve( '@babel/preset-typescript' ), ], plugins: [ require.resolve( '@babel/plugin-syntax-import-attributes' ), require.resolve( '@wordpress/warning/babel-plugin' ), [ require.resolve( '@babel/plugin-transform-react-jsx' ), { runtime: 'automatic' } ], maybeGetPluginTransformRuntime(), wpBuildOpts.addPolyfillComments && replacePolyfills, ].filter( Boolean ), };

也就是说,除@babel/preset-env外,该预设还默认开启:

  • TypeScript 支持:内置@babel/preset-typescript,因此.ts/.tsx文件可以直接编译(类型检查仍由 tsc 负责,Babel 只做语法剥离)。
  • Import Attributes:通过@babel/plugin-syntax-import-attributes支持import data from './x.json' with { type: 'json' }这类语法。
  • JSX 自动运行时:采用runtime: 'automatic',编译产物引用react/jsx-runtime,无需在源码中显式import React
  • WordPress 警告插件@wordpress/warning/babel-plugin会在生产构建时移除warning()调用。

二、安装与使用:三条命令接入官方预设

安装

预设本身只负责配置,实际转换仍由@babel/core完成(该预设将其声明为依赖,见 package.json)。在项目根目录执行:

npm install @wordpress/babel-preset-default --save-dev

注意:该包要求长期支持(LTS)状态的 Node.js 版本(engines字段声明为node >=18.12.0npm >=8.19.2,见 package.json),不兼容旧版本 Node。

在 Babel 配置中启用

Babel 支持多种配置方式(.babelrcbabel.config.jspackage.json中的babel字段等),核心做法是把预设名放入presets数组。使用.babelrc的示例:

{ "presets": [ "@wordpress/babel-preset-default" ] }

三、预设内部逻辑:按环境自动选择 targets

从源码可以看到,该预设是一个函数式配置(module.exports = ( api ) => {...}),它会根据api.env()api.caller()动态决定编译目标:

  • 测试环境envNametest):targets固定为{ node: 'current' },且modules保持默认(可被 Node 直接执行),并跳过@babel/plugin-transform-runtime(见 index.js 中isTestEnv分支)。
  • 生产/构建环境modules: false(保留 ES Module 供打包器 tree-shaking),targets优先读取项目根目录的browserslist配置,若无则回退到@wordpress/browserslist-config定义的默认浏览器矩阵:
'> 1%', 'last 1 Android versions', 'last 1 ChromeAndroid versions', 'last 2 Chrome versions', 'last 2 Firefox versions', 'last 2 Safari versions', 'last 2 iOS versions', 'last 2 Edge versions', 'last 2 Opera versions',

这正好对应 WordPress 项目支持的浏览器基线,也是build/polyfill.js选择 polyfill 条目的依据。

  • Gutenberg 官方构建(caller 名为WP_BUILD_MAIN/WP_BUILD_MODULE时):会读取 caller 传入的modulesuseESModulesaddPolyfillComments等选项,实现主入口与 ESM 模块产物的差异化输出。

此外,@babel/preset-env开启了bugfixes: true,让 Babel 只做"最小必要"的语法转换,减少多余输出。

四、扩展配置:在官方预设之上叠加插件

该预设是一份"有主见"(opinionated)的配置。若想增加或覆盖其行为,只需要在自身 Babel 配置的plugins/presets中追加插件——Babel 保证plugins先于presets执行,因此追加的插件可以覆盖预设内置的同名转换。

例如,某个 Stage 3 提案特性尚未被 WordPress 采纳,但你的项目确实需要,可以显式加入对应插件:

{ "presets": [ "@wordpress/babel-preset-default" ], "plugins": [ "@babel/plugin-transform-class-properties" ] }

需要精确了解默认启用了哪些插件时,可直接阅读预设实现 packages/babel-preset-default/index.js 中的presetsplugins数组。

五、Polyfill 机制:build/polyfill.jswp:polyfill魔法注释

5.1 独立的 Polyfill 文件

该包提供一个配套的build/polyfill.js(压缩版build/polyfill.min.js),用于补齐 WordPress 支持浏览器中缺失的 ECMAScript 特性(参考 WordPress 官方浏览器支持政策;引入于 PR #31279)。

它的定位是:

  • 作为已废弃的@babel/polyfill包的直接替代品(drop-in replacement);
  • 底层基于core-js构建(core-js同时是该包依赖,见 package.json);
  • 通过构建脚本 bin/index.js 生成:先产出build/polyfill.js,再经 terser 压缩为build/polyfill.min.js

使用方式有两种:把 polyfill 内容前置拼接到编译后的代码之前,或作为一个独立的<script>在业务代码之前加载:

<script src="path/to/polyfill.min.js"></script> <script src="path/to/your-bundle.js"></script>

注意:polyfill 只覆盖已进入 Stage 4 的特性。若你使用了尚未定稿的 TC39 提案(非 Stage 4),该 polyfill 不会自动导入对应补丁,你需要自行从core-js等方案按需引入。

5.2 按需注入与wp:polyfill魔法注释

预设内部有一个自定义 Babel 插件 replace-polyfills.js:它遍历代码中所有import 'core-js/...'require( 'core-js/...' )语句,将其删除,并在文件顶部写入一条魔法注释/* wp:polyfill */,标记该文件依赖全局 polyfill:

// 编译前 import 'core-js/stable/array/flat-map'; // 编译后 /* wp:polyfill */

这一机制在 Gutenberg 官方构建(caller 提供addPolyfillComments: true时,配合@babel/preset-envuseBuiltIns: 'usage')下生效,让打包器能据此把文件归属到依赖wp-polyfill的资源清单中,避免重复注入。

5.3 刻意排除的 polyfill 清单

polyfill-exclusions.js 定义了一组被刻意排除的 polyfill:

排除项原因
es.array.push规避非可写数组(non-writable arrays)相关的 Chromium 罕见 bug(见 Chromium issue 42202623)
web.immediateIE 专属特性,WordPress 不使用也不希望为其补丁(见 PR #49234)
/^es(next)?\.set\./Babel/core-js 会对所有new Set()无差别注入全部实例方法 polyfill,造成不必要的体积与性能开销,因此整体关闭(见 PR #67230)
/^es(next)?\.iterator\./与 Set 同理,排除全部 iterator helper polyfill

其中 Set 与 Iterator 需要同时以es.esnext.前缀声明,这是 Babel/core-js 内部依赖关系的特殊性决定的。开发者在面向旧浏览器时需自行确保不使用这些特性。

六、测试与验证:预设行为有据可查

该包使用 Vitest 编写测试(见 test/index.js),覆盖两类场景:

  1. 基础转译:以 fixtures/input.js 为输入(包含 async generator 函数、可选链obj?.foo?.bar等现代语法),在envName: 'production'下转译并与快照对比,验证 Stage 4 特性被正确保留/转换(快照见 index.js.snap)。
  2. 魔法注释注入:以 fixtures/polyfill.js(内部使用Promise.try这类需要 polyfill 的特性)为输入,传入caller: { name: 'WP_BUILD_MAIN', addPolyfillComments: true },断言输出包含/* wp:polyfill */注释。

这为"预设确实启用了哪些特性、polyfill 标记如何产生"提供了可运行、可复现的验证入口。

七、小结与适用场景

@wordpress/babel-preset-default的价值在于把 WordPress 的语法与兼容策略收敛为一套可复用的官方配置:生产构建保持 ESM、测试环境针对当前 Node、JSX 自动运行时开箱即用、TypeScript 语法直接支持,同时通过build/polyfill.jswp:polyfill注释建立了与 Gutenberg 构建流水线一致的 polyfill 分工。

适用场景包括:

  • WordPress 插件/主题使用现代 JavaScript 或 JSX 开发,希望遵循官方编译标准;
  • 在 Gutenberg 生态中开发独立包,需要与官方构建产物保持一致的转译口径;
  • 需要替代已废弃的@babel/polyfill,获得一个基于core-js、面向 WordPress 浏览器基线的即用 polyfill。

若需深度定制,建议以 index.js 为蓝本,结合自身browserslist配置与 Babel 插件优先级,在项目级配置中逐步叠加或覆盖。

【免费下载链接】gutenbergThe Block Editor project for WordPress and beyond. Plugin is available from the official repository.项目地址: https://gitcode.com/GitHub_Trending/gu/gutenberg

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询