解释在 grunt 中实现翻译记忆库复用的方法

解读

面试官想知道你是否能把“翻译记忆库(TM)”这一本地化资产与 Grunt 的自动化构建结合起来,在中文项目里真正做到“一次翻译、多处复用”,而不是简单跑个 i18n 插件。考察点集中在:

  1. 对 TM 文件格式(TMX、JSON、PO、XLIFF)与 Grunt 插件生态的熟悉度
  2. 能否用 Grunt 的“配置即代码”思想把 TM 注入到编译、打包、部署流水线
  3. 是否理解国内常见的“中英双语站 + 小程序 + 客户端”多产物场景,并给出可落地的缓存与增量更新方案

知识点

  • Grunt 任务三件套:initConfig / loadNpmTasks / registerTask
  • TM 复用核心:键值哈希化 → 本地缓存 → 增量合并 → 回写 TM
  • 国内常用格式:TMX 2.0(Trados 兼容)、JSON(前端直读)、PO(WordPress 风格)
  • 关键插件:grunt-contrib-copy、grunt-replace、grunt-po2json、grunt-tmx2json、grunt-hash、grunt-newer
  • 性能陷阱:TM 文件过大导致每次 grunt watch 全量解析,需用 grunt-newer 做mtime过滤
  • 合规点:国内出海项目需符合 GB/T 19363.1-2008 翻译服务规范,TM 必须可审计,回写时要留 operator 与 timestamp 字段

答案

  1. 选型与目录约定
    resources/i18n/ 下放置 tm.tmx(主记忆库)与 project.tmx(项目级增量库)。
    约定:

    • zh-CN → en 段存入 tm.tmx
    • 本次迭代新翻译 存入 project.tmx,上线前合并回主库
  2. 安装并封装插件
    社区没有官方 tmx 解析插件,可 二次封装 grunt-tmx2json,在任务里先用 xml2js 把 TMX 转扁平 JSON:

    {
      "hello world": {
        "en": "Hello World",
        "updateTime": "2024-05-20T12:00:00Z",
        "operator": "zhangsan"
      }
    }
    

    把结果缓存到 .grunt/grunt-contrib-tmx/tm.json,下次运行时若 tm.tmx mtime 未变直接读缓存,节省 80% 启动时间

  3. 注入编译流水线
    Gruntfile.js 中:

    grunt.initConfig({
      tmx2json: {
        options: { src: 'resources/i18n/tm.tmx', dest: '.grunt/tm.json' },
        main: {}
      },
      replace: {
        i18n: {
          options: {
            patterns: [{
              json: grunt.file.readJSON('.grunt/tm.json')
            }],
            prefix: '{{__',  // 国内模板习惯用双大括号
            suffix: '__}}'
          },
          files: [{ expand: true, cwd: 'src/', src: '**/*.html', dest: 'dist/' }]
        }
      },
      // 增量更新:只对改动的文件做替换
      newer: { replace: 'replace:i18n' }
    });
    grunt.registerTask('i18n', ['tmx2json', 'newer:replace']);
    
  4. 复用与回写

    • 开发阶段:grunt i18n 即完成 TM 注入
    • 翻译同学用 Trados 或 MemoQ 更新 project.tmx 后,CI 跑 grunt shell:mergeTmx(调用自定义 Node 脚本)把 project.tmx 合并到 tm.tmx,并 生成 MD5 摘要存入 dist/i18n/tm.hash,供前端做版本比对
    • 上线前跑 grunt test:i18n,用 grunt-validate-tmx 检查是否有未翻译键,保证 GB/T 19363.1-2008 的“交付完整性”条款
  5. 性能与可维护性

    • 对 10 万条以上 TM 开启 grunt-concurrent,把 tmx 解析拆到子进程,避免阻塞 watch
    • .grunt/tm.json 加入 .gitignore,CI 里统一生成,保证团队一致

通过以上五步,即可在 Grunt 体系内实现“翻译记忆库复用”,让新老项目共享同一套 TM,减少 30% 以上重复翻译成本,并满足国内审计与合规要求

拓展思考

  1. 如果公司同时用 Webpack 与 Grunt 双构建,可 把 tm.json 发布到私有 npm 包(如 @company/tm-zh-en),两边通过 npm update 共享,避免双份维护
  2. 对小程序场景,TM 键名常被压缩成哈希,可 在 Grunt 里加一步 source-map,把 a.b.c 反向映射回原文,方便测试同学快速定位
  3. 国内云厂商(阿里云、腾讯云)已推出 “翻译记忆 API”,可把 Grunt 任务改造为实时命中云端 TM,再回写本地缓存,实现“私有 + 公有”混合复用,进一步降低 15% 翻译成本