如何高效检测多语言翻译文件底层键是否在项目目录中存在引用
多语言翻译键未引用检测效率优化方案
两种方案的性能差异结论
遍历所有文件一次的方案,和逐个翻译键遍历文件的方案性能差异完全不可忽略:
- 逐个翻译键遍历文件的时间复杂度为
O(M*N):M为翻译键总数,N为项目文件总数,千级翻译键+千级文件的场景下,需要执行百万级的文件读取操作,开销极高。 - 遍历文件一次的方案时间复杂度为
O(N):仅需读取所有目标文件一次,开销和翻译键数量无关,比前者效率高几个量级。
基础实现步骤(已验证最优方向)
你提到的第二种思路是正确的,完整的基础流程如下:
- 先递归打平多语言JSON,提取所有叶子节点的键路径,存入
Set结构作为待校验集合(Set的删除、查询操作都是O(1),比普通对象效率更高)
打平逻辑参考代码:function flattenLocale(obj, parentPath = '') { const result = new Set() for (const key in obj) { const currentPath = parentPath ? `${parentPath}.${key}` : key const value = obj[key] // 仅把值为基础类型的叶子节点加入待校验集合 if (typeof value === 'object' && value !== null && !Array.isArray(value)) { result.add(...flattenLocale(value, currentPath)) } else { result.add(currentPath) } } return result } // 调用示例,根据你导出的locale结构调整根路径前缀 const pendingKeys = flattenLocale(locale.data, 'data') - 按照
.gitignore规则过滤目录,排除无关文件,只保留需要扫描的源码文件 - 逐个读取过滤后的文件内容,匹配文件中出现的所有翻译键,每匹配到一个就从
pendingKeys中删除 - 全部扫描完成后,
pendingKeys中剩余的就是未被引用的翻译键
可进一步提升效率的优化点
- 提前终止扫描:每处理完一个文件就检查
pendingKeys的大小,如果已经为空,直接停止后续所有文件的读取,翻译键覆盖率较高的场景下能节省90%以上的时间。 - 正则批量匹配:提前把所有待校验的键拼成一个全局正则(注意转义路径中的
.等特殊字符),读取一个文件后只执行一次正则匹配,就能拿到当前文件里所有出现的翻译键,不需要循环每个键逐个判断,字符串匹配效率提升非常明显。 - 提前过滤文件类型:除了
.gitignore的规则,还可以主动限定只扫描业务源码文件,比如前端项目只扫描.js、.ts、.jsx、.tsx、.vue文件,直接跳过图片、字体、编译产物、依赖目录,大幅减少需要读取的文件总数。 - 异步IO并发读取:如果用Node.js等Runtime实现,不要用同步文件读取接口,用异步IO批量并发读取文件,IO密集型场景下效率比同步读取高好几倍。
- 缓存扫描结果:如果需要频繁执行校验(比如集成到本地开发钩子、CI流程),可以缓存每个文件的修改时间或者哈希值,下次执行时如果文件没有变更,直接跳过读取,不需要重复扫描。
额外注意事项
静态扫描无法识别动态拼接的翻译键,比如locale.data.NAV[moduleType].TITLE这类写法,需要你额外做兼容处理,否则会出现误判。
内容的提问来源于stack exchange,提问作者Tal C
相关产品推荐
相关产品推荐

