使用 grunt-i18n-extract 扫描代码中的翻译标记
解读
在国内前端团队的日常迭代中,国际化(i18n)往往被“后置”:需求上线前才发现硬编码中文散落在各组件里,手工搜集不仅耗时,还容易漏掉模板字符串、动态 key 或 JSX 属性。grunt-i18n-extract 正是 Grunt 生态里专门“把代码里的翻译标记一次性扫出来”的插件,它通过静态 AST 分析,把符合规则的调用(如 i18n('key')、$t('key'))提取成 JSON/PO/CSV 等格式,供翻译平台或运营同学直接接手。面试时,考官想确认的是:你不仅知道怎么配任务,还能解决真实业务中的冲突、性能、增量扫描、多语言分支合并等痛点,而不是跑通 demo 就结束。
知识点
- grunt-i18n-extract 核心配置项:
src(支持 glob 数组,如['src/**/*.{js,vue}'])、dest(输出目录)、marker(正则/函数,匹配翻译函数名)、defaultLang(默认语言,国内一般zh-CN)、module(输出格式json|po|csv)、flatten(是否拍平 key 路径)、namespace(防止 key 冲突的前缀)。 - AST 与正则双策略:插件默认用正则快速提取,遇到 ES6 模板字符串、TS 类型、Vue SFC 时自动回退到Babel AST,保证
<template>{{ $t(order.status.${type}) }}</template>也能被正确捕获。 - 增量扫描:通过
grunt-newer组合,先对比 git diff 或文件 mtime,只扫描变更文件,10 万行代码项目也能 2 秒内完成提取。 - 冲突消解:同一 key 在不同文件出现不同默认值时,插件会生成
warning.log,CI 阶段可配置 failOnWarning=true 强制阻断合并,防止“中文覆盖英文”。 - 多分支合并:利用
grunt-merge-i18n(社区二次封装)把 feature 分支提取出的zh-CN.json自动合并到主干,支持运营锁 Key,已翻译条目不会被覆盖。 - 国内常见坑:
- 微信小程序
wxs标签被误识别为 JS,需在src里加!**/*.wxs排除; - Ant Design Pro 的
formatMessage被 TreeShaking 后变量名压缩,需把marker写成/\bformatMessage\s*\(\s*['"]([^'"]+)['"]/g`; - 服务端渲染项目,提取阶段没有
window,需在Gruntfile里加node: true环境变量,防止插件报navigator is not defined而中断。
- 微信小程序
答案
- 安装
npm i -D grunt-i18n-extract - Gruntfile.js 最小可运行配置
module.exports = function(grunt) { grunt.initConfig({ i18n_extract: { options: { marker: /(?<=\$t\(|i18n\(|formatMessage\()\s*['"`]([^'"`]+)['"`]/g, module: 'json', defaultLang: 'zh-CN', dest: 'locales', flatten: false, namespace: false, failOnWarning: true // 国内 CI 强制质量门禁 }, src: ['src/**/*.{js,vue,ts,tsx}'], } }); grunt.loadNpmTasks('grunt-i18n-extract'); grunt.registerTask('i18n', ['newer:i18n_extract']); // 增量 }; - 运行
输出目录grunt i18nlocales/zh-CN.json示例:{ "order.status.waitPay": "待支付", "order.status.done": "已完成" } - 接入翻译平台(以腾讯 TMT 为例)
- 把
zh-CN.jsonpush 到企业微信机器人,运营同学在线翻译后回传en-US.json; - 在
grunt-contrib-copy里加一条任务,把回传文件直接覆盖src/locales/lang,无需手动拷贝。
- 把
拓展思考
- 性能极限:当项目膨胀到 2000+ 页面、50 万行代码时,正则回溯会导致 CPU 飙到 100%。可临时关闭正则,强制走
@babel/parser+traverse,并开启cacheDirectory: '.grunt/cache',二次扫描耗时从 90s 降到 8s。 - key 规范治理:在
pre-commit钩子中调用grunt i18n,若发现 key 包含中文空格或特殊符号,自动阻断提交并提示“请用 camelCase”,从源头保证翻译平台能正确匹配。 - 微前端场景:主应用与多个子应用共用一套
locales。可在主应用 Gruntfile 里配置i18n_extract:combine,把各子应用产物合并成单文件,再上传到 CDN,避免运营重复翻译。 - SSR 运行时注入:提取完成后,利用
grunt-replace把window.__INITIAL_I18N__ = <%= zhCN %>注入到index.ejs,首屏直接渲染中文,省去一次 Ajax 请求,在国内 4G 弱网环境可提升 200ms+。