You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何高效检测多语言翻译文件底层键是否在项目目录中存在引用

多语言翻译键未引用检测效率优化方案

两种方案的性能差异结论

遍历所有文件一次的方案,和逐个翻译键遍历文件的方案性能差异完全不可忽略:

  • 逐个翻译键遍历文件的时间复杂度为 O(M*N):M为翻译键总数,N为项目文件总数,千级翻译键+千级文件的场景下,需要执行百万级的文件读取操作,开销极高。
  • 遍历文件一次的方案时间复杂度为 O(N):仅需读取所有目标文件一次,开销和翻译键数量无关,比前者效率高几个量级。

基础实现步骤(已验证最优方向)

你提到的第二种思路是正确的,完整的基础流程如下:

  1. 先递归打平多语言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')
    
  2. 按照.gitignore规则过滤目录,排除无关文件,只保留需要扫描的源码文件
  3. 逐个读取过滤后的文件内容,匹配文件中出现的所有翻译键,每匹配到一个就从pendingKeys中删除
  4. 全部扫描完成后,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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 08:06:05