Obtainium 如何用 standardize.mjs 同步各语言翻译文件的键?
【免费下载链接】ObtainiumGet Android app updates straight from the source.项目地址: https://gitcode.com/GitHub_Trending/ob/Obtainium
Obtainium 是一个 Flutter(Android-first)应用,用easy_localization做国际化:用户界面文案全部走tr()/plural(),键定义在assets/translations/下的各语言 JSON 文件里(见 DEVELOPER_GUIDE.md 第 1 节与技术栈表)。当你在en.json里新增、重排或调整了键之后,各语言文件会逐渐和英文模板脱节——缺键、键序不一致、多出不该存在的键。assets/translations/目录下的 standardize.mjs 就是为此准备的脚本:它以en.json为模板,强制所有其他翻译文件使用与模板相同的键、相同的顺序。本文说明这个脚本的运行机制和正确用法。
脚本做了什么
先弄清standardize.mjs的行为边界,再运行它。根据 standardize.mjs 源码,它对assets/translations/目录做如下处理:
- 模板文件固定为
en.json:脚本以en.json读取到的键及顺序作为基准(第 12–18 行)。 - 扫描目标文件:读取该目录下所有
.json文件,排除en.json本身、以及文件名以package开头的文件(第 14–16 行),因此同目录的package.json、package-lock.json不会被误处理。 - 按模板重建每个目标文件(第 20–25 行):
- 输出文件的键完全按
en.json的键、以en.json中的顺序排列; - 目标文件中已有的翻译值会保留;
- 目标文件缺少的键,用
en.json中对应的英文文案补上。
- 输出文件的键完全按
- 模板中不存在的键会被丢弃(第 26–33 行):脚本会通过
console.error输出类似...: keys missing from template will be dropped: key1, key2的提示,列出每个文件中被丢弃的键及文件名。 - 原子写回:新内容先写入
<file>.tmp,再renameSync覆盖原文件(第 34–36 行),避免中途失败留下半个文件。
两点值得注意:
- 脚本不依赖运行位置。它用
import.meta.dirname取脚本自身所在目录作为翻译目录(第 12 行),所以在仓库任何位置执行node assets/translations/standardize.mjs结果都一样。 - 它不碰翻译本身。已有的译文值原样保留,它只保证键集合和键顺序与
en.json一致。
运行步骤
前提:本机有 Node.js(脚本只用到fs、path内置模块,不需要额外依赖)。
备份翻译文件。standardize.mjs 第 5–6 行明确警告:运行前先备份翻译文件,以便标准化的输出有误时能恢复之前的翻译。脚本会直接覆盖原文件,且模板中不存在的键会被永久丢弃,备份是脚本自己要求的前置步骤。
在仓库根目录执行,把该目录复制一份到仓库外:
cp -r assets/translations /path/to/backup/translations_backup/path/to/backup替换为你机器上任意仓库外的备份位置。确认
en.json是最新的模板。标准化的结果完全由 en.json 决定:如果你新加的用户界面文案还没有写进en.json,运行脚本也不会给其他语言文件补上这个键。按 DEVELOPER_GUIDE.md 第 7 节的约定,所有用户可见字符串的键都必须至少存在于en.json。运行脚本:
node assets/translations/standardize.mjs脚本对每个语言文件都是静默重写的,唯一的输出是第 4 点提到的
console.error提示。
验证结果
检查标准错误输出:运行后如果没有任何
console.error输出,说明所有语言文件的键都包含在en.json中;如果出现keys missing from template will be dropped: ...行,说明对应文件里有模板外的键。这些键已经被丢弃——如果你确认它们不该存在(例如旧键重命名后遗留),可以直接忽略;如果是误删的键,用第 1 步的备份恢复该文件,并先修改en.json(补上或对齐键名)再重新运行。抽查文件结构:对照 en.json 和任意一个语言文件(如 zh.json),两者的键应当完全一致且顺序相同;
zh.json中原本没有的键位置,值应当是en.json里对应的英文文案。确认没有残留临时文件:
assets/translations/下不应有*.json.tmp文件。跑项目检查:按 DEVELOPER_GUIDE.md 第 8 节的惯例,提交前执行:
flutter analyze # must be clean dart format --set-exit-if-changed .
限制与边界
- 脚本只处理
assets/translations/下的 JSON 文件;其他目录的翻译文件不在处理范围内。 - 它的粒度是"顶层键":对嵌套对象(如
apk、apps这类带one/other的复数键),键名相同即视为同一键,整体沿用目标文件的值,不会深入到对象内部逐层对齐。 - 同目录的 package.json 只是声明了
translate依赖,与标准化工具无关,脚本会跳过它。 - 键的取舍完全由
en.json说了算:任何你认为"各语言应该有而模板没有"的键,都先改en.json,再运行脚本。
完成以上步骤后,各语言翻译文件即与en.json的键集合和顺序完全一致,可以随代码一起提交。
【免费下载链接】ObtainiumGet Android app updates straight from the source.项目地址: https://gitcode.com/GitHub_Trending/ob/Obtainium
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考