wp-calypso 的 Babel 插件 babel-plugin-preserve-i18n:在压缩产物中保住 WordPress 翻译调用
前端CMS【免费下载链接】wp-calypsoThe JavaScript and API powered WordPress.com项目地址https://gitcode.com/gh_mirrors/wp/wp-calypso点击查看免费下载本篇文章围绕 wp-calypso 仓库中的 Babel 插件 automattic/babel-plugin-preserve-i18n 展开介绍它如何在构建与压缩阶段保留__( Hello )这类 WordPress i18n 函数调用语法使 WP i18n 提取工具在产物包括被 Terser 压缩后的 bundle中仍能识别并抽取翻译字符串。读完本文你将掌握该插件的设计动机、AST 变换原理、scope 绑定维护细节以及它在 Calypso 共享 Babel 配置中的真实接入方式。一、插件要解决什么问题Calypso 的代码中大量使用 WordPress 官方的国际化函数例如import { __, _x } from wordpress/i18n; __( Hello ); _x( World );在正常编译流程中import语句会被 Babel 降级为require/ CommonJS 形式进入生产 bundle 后__、_x这类本地变量名往往会被压缩器如 Terser重命名成a、b之类的短名。一旦调用点变成a( Hello )WordPress 的 i18n 提取工具例如 WP-CLI 的i18n make-pot或 Calypso 自己基于 babel-plugin-i18n-calypso 的 POT 生成流程就无法再通过__( 字符串 )的固定模式扫描到待翻译文本导致字符串漏翻。babel-plugin-preserve-i18n的思路与社区中的babel-plugin-optimize-react对 React 导入做类似变换一脉相承通过别名化导入、再用const重新声明原名把翻译函数名钉死在产物中。插件 README 中给出了完整的目标输出import { __ as alias__, _x as alias_x } from wordpress/i18n; const __ alias__; const _x alias_x; __( Hello ); _x( World );变换后调用点的写法__( Hello )与变换前逐字一致依旧可以在输出 bundle 中被 i18n 工具扫描出来而 Terser 压缩时若配合mangle.reserved选项将__、_x等名字加入保留名单则即使经过 minify这个可识别的调用模式依然完整存在见 README.md。二、源码实现AST 变换的完整流程插件的主入口是 src/index.js其 package.json 将main指向该文件。整个实现只有两个核心部分一个负责收集并别名化导入的函数以及一个挂载在ImportDeclaration上的 visitor。1. 翻译函数白名单const i18nImports new Set( [ __, _n, _nx, _x ] );插件只对来自wordpress/i18n的这四个命名导入做处理覆盖了 WordPress i18n 中最常用的四个形态__( text )普通翻译、_x( text, context )带上下文、_n( single, plural, number )复数、_nx( single, plural, number, context )复数 上下文。不在集合内的导入如sprintf、isRTL等原样保留不做任何干预。2. 收集导入并生成别名collectAllImportsAndAliasThem核心函数collectAllImportsAndAliasThem( path )完成三步工作src/index.js#L6-L38第一步校验模块来源。只有t.isStringLiteral( node.source ) node.source.value wordpress/i18n的导入声明才会进入处理逻辑避免误伤其他包的同名函数。第二步遍历 specifiers 并别名化。对每个ImportSpecifier即具名导入要求imported与local都是Identifierimport { __ as foo }这类带本地别名的写法也能正确处理随后命中白名单后记录{ original: localNode.name, aliased: alias localNode.name }即原名__的别名是alias__用t.importSpecifier( t.identifier( alias localNode.name ), t.identifier( importedNode.name ) )替换原 specifier把导入目标改成别名调用path.scope.removeBinding( localNode.name )移除原本地绑定的注册循环结束后path.scope.registerDeclaration( path )把修改后的导入声明重新注册到作用域。第三步返回收集到的别名列表供 visitor 使用。3. 在导入声明后插入 const 重声明visitor 只监听一个节点类型visitor: { ImportDeclaration( path ) { const aliases collectAllImportsAndAliasThem( path ); if ( aliases.length 0 ) { const declarations aliases.map( ( { original, aliased } ) t.variableDeclarator( t.identifier( original ), t.identifier( aliased ) ) ); const aliasDeclarationNode t.variableDeclaration( const, declarations ); path.insertAfter( aliasDeclarationNode ); const aliasDeclarationPath path.getNextSibling(); path.scope.registerDeclaration( aliasDeclarationPath ); } }, },见 src/index.js#L40-L57要点拆解当收集到至少一个别名时把每条记录生成一个variableDeclarator( 原名, 别名 )最终拼成一个const声明节点例如const __ alias__, _x alias_x;通过path.insertAfter把该声明紧跟在 import 语句之后插入使__、_x以const绑定形式继续存在于模块作用域中插入后立刻通过path.getNextSibling()拿到新节点的 Path并registerDeclaration到作用域保证后续对__、_x的引用能被正确解析。这种先removeBinding、再registerDeclaration的作用域管理是插件正确性的关键它让 Babel 在后续遍历中不会因绑定信息过期而报错也确保同一文件内既有的__( Hello )调用语义不发生任何变化。4. 插件元信息返回的对象带有name: babel-plugin-preserve-i18n便于 Babel 在报错和调试信息中标识该插件。包本身以module.exports function ( babel ) { ... }的形式导出标准的 Babel 插件工厂函数依赖 Babel 传入的babel.typest完成全部节点构造。三、包配置与工程形态从 package.json 可以看到该包的完整工程信息字段值说明nameautomattic/babel-plugin-preserve-i18n发布在 npm 上的包名version1.0.0当前版本descriptionA Babel plugin to preserves translation functions even when minified.一句话概括插件目标mainsrc/index.js入口即插件实现licenseGPL-2.0-or-later开源许可证publishConfig.accesspublic允许公开发布devDependenciesautomattic/calypso-eslint-overrides、automattic/calypso-typescript-config均workspace:^仅用于仓库内 lint 与 TS 配置仓库地址指向githttps://github.com/Automattic/wp-calypso.gitdirectory字段精确标注到packages/babel-plugin-preserve-i18n。其 tsconfig.json 仅扩展了 automattic/calypso-typescript-config 的js-package.json预设——注意插件本身是纯 JavaScript 实现TS 配置只服务于仓库统一的工程约束。四、在 Calypso 构建管线中的真实接入babel-plugin-preserve-i18n不是孤立的实验代码而是 Calypso 共享 Babel 配置的一等公民。在 packages/calypso-babel-config/package.json 中它被声明为calypso-babel-config的运行时依赖并在默认 preset 中直接启用plugins: [ require.resolve( babel/plugin-proposal-class-properties ), [ require.resolve( babel/plugin-transform-runtime ), { corejs: false, helpers: true, regenerator: false, useESModules: false, /* ... */ }, ], require.resolve( automattic/babel-plugin-preserve-i18n ), require.resolve( emotion/babel-plugin ), ],见 presets/default.js#L38-L54也就是说任何基于automattic/calypso-babel-config默认预设的 Calypso 模块包括 client 与 packages 下的 React/JS 源码在 Babel 编译阶段都会自动经过本插件的变换。与之配合的还有 config.js 定义的build_pot环境该环境启用automattic/babel-plugin-i18n-calypso并可通过outputPOT参数指定 POT 文件输出目录、注入content-type与x-generator头。整体链路可以概括为源码写入__( Hello )Babel默认 preset含 preserve-i18n把 import 别名化并插入const重声明调用点写法原样保留生产构建经 Terser 压缩时配合mangle.reserved保留翻译函数名构建产物bundle中依然存在可被扫描的__( Hello )调用模式WP i18n 工具或build_pot环境下的 i18n-calypso 插件据此抽取全部待翻译字符串生成 POT。这个顺序保证了翻译字符串提取与代码压缩优化两条需求不互相打架——这正是该插件在大型 JS 应用中的价值所在。五、适用边界与使用注意事项从源码结构与 README 可以梳理出以下几点实践须知只处理命名导入不处理默认导入visitor 中仅匹配t.isImportSpecifierimport i18n from wordpress/i18n这类默认导入不会触发变换模块来源必须精确匹配wordpress/i18n字符串字面量是唯一目标即使其他包也导出了__也不会被误伤别名命名规则别名固定为alias 本地名如alias__、alias_nx如果源码中恰巧存在同名标识符理论上存在冲突风险这也是使用时应留意的边界情况与 Terser 的配合是锦上添花而非必需即使不配置mangle.reserved经插件变换后的 bundle 在未压缩状态下也完全可被 i18n 工具提取配置mangle.reserved才能保证 minify 之后调用名不被改写压缩阶段的保护对象是调用模式而非字符串本身插件只关心函数名与调用形态的保留字符串常量仍由常规的 i18n 工具链负责收集与去重。如果希望在自有项目中复用它最直接的方式是像 Calypso 一样把它加入 Babel 配置的plugins数组本仓库为 workspace 依赖可通过yarn workspace引用automattic/babel-plugin-preserve-i18n随后按上文链路配置构建与提取流程即可。六、小结babel-plugin-preserve-i18n是一个小而精准的 Babel 插件它以一次 AST 变换import 别名化 const原名重声明 scope 绑定维护解决了压缩产物中的翻译调用可被提取这一国际化工程难题。核心证据集中在 src/index.js 的几十行实现以及 presets/default.js 中的真实接入点它服务的目标函数集合__、_n、_nx、_x与 WordPress i18n 工具的扫描模式一一对应。理解这个插件的原理也就理解了大型 JavaScript 应用中编译优化与字符串提取如何通过作用域与 AST 操作达成平衡。赞分享前端CMS【免费下载链接】wp-calypsoThe JavaScript and API powered WordPress.com项目地址https://gitcode.com/gh_mirrors/wp/wp-calypso点击查看免费下载相关推荐wp-calypso 国际化构建基石babel-plugin-i18n-calypso 提取 translate 调用生成 POT 全解析wp calypso 国际化构建基石babel plugin i18n calypso 提取 translate 调用生成 POT 全解析 本文围绕 pack前端CMSWordPress Gutenberg 的 Babel 插件 babel-plugin-makepot从 JS 源码自动生成 gettext POT 翻译模板WordPress Gutenberg 的 Babel 插件 babel plugin makepot从 JS 源码自动生成 gettext POT 翻译模板后端前端探索Babel插件魔法babel-plugin-macros探索Babel插件魔法 babel plugin macros 项目简介 Babel https://babeljs.io/ 是JavaScript的编译器创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

如何在终端渲染 LaTeX 公式?拆解 leaf 的 Unicode 数学符号转换实现

如何在终端渲染 LaTeX 公式?拆解 leaf 的 Unicode 数学符号转换实现

如何在终端渲染 LaTeX 公式?拆解 leaf 的 Unicode 数学符号转换实现 【免费下载链接】leaf Terminal Markdown previewer — GUI-like experience. 项目地址: https://gitcode.com/gh_mirrors/leaf37/leaf leaf 是一款终端 Markdown 预览器(Termi…

2026/10/21 4:29:42 阅读更多 →
Nangate 45nm开源工艺库+FreePDK45:从RTL到门级仿真的完整数字IC流程

Nangate 45nm开源工艺库+FreePDK45:从RTL到门级仿真的完整数字IC流程

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/21 5:31:50 阅读更多 →
单片机控制板异常排查六步法:从电源到动态特性全解析

单片机控制板异常排查六步法:从电源到动态特性全解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 12:28:57 阅读更多 →

最新新闻

Linux网络学习【传输层协议UDP】

Linux网络学习【传输层协议UDP】

🔥承渊政道:个人主页 ❄️个人专栏: 《C语言基础语法知识》 《数据结构与算法》 《C知识内容》 《Linux系统与网络知识》 《算法刷题指南》 《测评文章活动推广》 《大模型语言路线学习》 《MySQL数据库学习》 《Python知识内容》 《cpolar知识学习》 ✨…

2026/10/21 6:58:46 阅读更多 →
AI大模型落地最后一公里:收藏这份FDE工程师成长指南,小白程序员必看!

AI大模型落地最后一公里:收藏这份FDE工程师成长指南,小白程序员必看!

工业AI项目常卡在POC阶段,难以规模化落地。核心问题在于通用AI能力与千差万别的工业现场之间存在数据、设备、工况、业务流程等多重鸿沟。为填补这一空白,新职业“前线部署工程师”(FDE)应运而生。FDE是介于算法工程师与现场实施工…

2026/10/21 6:58:46 阅读更多 →
AIPM 是什么?

AIPM 是什么?

搜「AIPM」,你会同时撞见四种答案,它们互相不承认对方:岗位缩写、培训结业证、老认证的 AI 加课版、以及带公开能力模型与独立考试的标准化认证。 本文做三件事:拆开这个词的四种用法,给出两套可对照的参数表&#xff…

2026/10/21 6:58:46 阅读更多 →
CST有哪些典型应用场景?从天线设计到医疗成像,看电磁仿真如何走进真实研发

CST有哪些典型应用场景?从天线设计到医疗成像,看电磁仿真如何走进真实研发

当产品越来越智能、系统越来越复杂,电磁问题也不再只属于某一个专业环节。它可能出现在天线布局阶段,也可能暴露在EMC整改现场;可能影响高速互联链路的稳定性,也可能关系到人体暴露评估、医疗成像效果,甚至高端装备的隐…

2026/10/21 6:58:46 阅读更多 →
火炮周视瞄准镜初步设计:指标分解、光路构型与轴系精度校核

火炮周视瞄准镜初步设计:指标分解、光路构型与轴系精度校核

简介:这份文档面向兵器工程、光学仪器及火炮瞄准系统方向的学生与设计人员,围绕火炮周视瞄准镜的初步设计展开,解决从光学参数确定到系统结构选型的完整设计流程问题。资源包共1个doc文件,约395KB,内容为一份结构完整的…

2026/10/21 6:58:46 阅读更多 →
Linux僵尸、孤儿与守护进程:原理、区别与实战实现

Linux僵尸、孤儿与守护进程:原理、区别与实战实现

1. 项目概述&#xff1a;从“进程尸体”到“后台幽灵”的真实世界映射在 Linux 系统里&#xff0c;你执行ps aux | grep defunct时看到的<defunct>标记&#xff0c;不是报错&#xff0c;而是一具“进程尸体”——它已经死亡&#xff0c;却还没被收尸&#xff1b;你用nohu…

2026/10/21 6:57:46 阅读更多 →

日新闻

统一内存+量化:锐龙AI Max PRO 400如何本地跑320B大模型

统一内存+量化:锐龙AI Max PRO 400如何本地跑320B大模型

这段时间硬件圈和AI圈都在传一个事&#xff1a;AMD锐龙AI Max PRO 400系列把最高192GB统一内存搬进了PC形态的产品里&#xff0c;按宣传口径&#xff0c;本地跑320B参数的大家伙不再是纸面概念。我第一反应倒不是“内存真大”&#xff0c;而是这话背后的含金量——它把过去只能…

2026/10/21 0:00:11 阅读更多 →
AI助手深度使用体验:对话质量、长文本处理与指令遵循如何留住用户

AI助手深度使用体验:对话质量、长文本处理与指令遵循如何留住用户

1. 从“封号重开”这个行为说起&#xff1a;用户到底在追求什么“封号重开”这四个字&#xff0c;放在任何产品语境里都带着一股决绝的味道。一个账号从零开始积累使用记录、调教偏好、沉淀工作流&#xff0c;背后是大量的时间和精力成本。正常情况下&#xff0c;没有人愿意主动…

2026/10/21 0:00:11 阅读更多 →
ROS中YOLOv3工程落地:通信同步、坐标变换与性能调优

ROS中YOLOv3工程落地:通信同步、坐标变换与性能调优

1. 为什么在ROS里硬刚YOLOv3不是“炫技”&#xff0c;而是工程落地的必经之路我第一次在某高校机器人实验室看到那台搭载Jetson TX2的移动底盘原地打转、反复识别错垃圾桶时&#xff0c;就意识到&#xff1a;单纯跑通darknet_ros demo和真正让YOLOv3在ROS里“干活”&#xff0c…

2026/10/21 0:00:11 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型&#xff08;GMM&#xff09;的语音识别系统&#xff0c;很多人第一反应就是一堆数学公式&#xff0c;觉得门槛很高。但如果你真的在MATLAB里把它落地跑通&#xff0c;会发现核心其实就是三件事&#xff1a;把声音变成特征向量&#xff0c;用GMM给每个类别…

2026/10/20 10:02:13 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人&#xff0c;但落到具体操作上&#xff0c;无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程&#xff1a;对图像做反白、改调色板、彩色转灰度&#xff0c;最后把像素数据导出成txt文件。单看每一…

2026/10/20 20:43:59 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词&#xff0c;你会发现一个很有意思的现象&#xff1a;每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型&#xff0c;有人指的是运动控制系统&#xff0c;还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/21 4:27:17 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 10:02:08 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 9:50:17 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 9:50:45 阅读更多 →