借助 GTP 从 0-1 快速落地前端项目国际化~

374 阅读4分钟

背景

开源项目 js-analyzer(一个可视化的前端依赖分析工具) 有了英语 issues, 不过目前项目内各种操作信息都还都是中文,准备将项目支持国际化,方便更多人使用。如果你还没使用过这个工具,也可以去 guthub 了解一下~

准备

因为是 vue3 项目,网上一搜,全是使用 i18n,说实话,个人觉得这个维护起来真的特别别扭。既要要定义变量名,还要维护多个语言文件..... 我的项目不大,场景也简单,搞这个太重了,主要是维护起来太痛苦了。

// i18n.ts
import { createI18n } from 'vue-i18n'

const messages = {  en: {
    message: {
      hello: 'hello world'
    }
  },
  ja: {
    message: {
      hello: 'こんにちは、世界'
    }
  }
}
const i18n = createI18n({
  locale: 'en',
  messages
})

export default i18n

初步设想

感觉可以把所有的语言定义在一个对象里,然后通过系统的需要自动切换取值。

// 定义
const languageMap = {
    "关系图": { "en": "Relationship Map", "ja": "関係図" },
}

// 使用
const type = 'en'
const text = languageMap['关系图'][type]

收集中文

接下来,就是要全局查找项目中的中文字符串,我们可以使用正则表达式找出所有中文 [\u4e00-\u9fa5]+

20240625143952.png

复制出所有中文放到一个文本编辑器里

关系图
包管理
热 词
隐式引用
默认标题
导出信息
我的项目
项目管理
....

AI 生成翻译和 JSON

传统的做法,就是一个一个手动写,还得用词典一个一个翻译成各种语言,这个过程真的很痛苦,还记得我早些年做的一个项目使用 in18 做国际化,这个过程我花了整整 3 天!一个一个去翻译、复制、粘贴。这还仅仅是中文翻译成英文,更别说其他语言了。

所以想让 AI 生成帮助我们想要的 JSON 格式,例如:

{
    "关系图": { "en": "Relationship Map", "ja": "関係図" },
    ...
}

将刚刚复制出所有中文+提示一起发送给 AI,内容如下:

引用列表

引用次数

引用名

引用源

引用文件
...

将上面的列表转换成如下格式的json列表:
{
 '{上面的某一项}': { 'en': '{对应的英文翻译}', 'ja': '{对应的日语翻译}' },
 ...
}

回答结果:

{
  "关系图": { "en": "Relationship Map", "ja": "関係図" },
  "包管理": { "en": "Package Management", "ja": "パッケージ管理" },
  "热词": { "en": "Hot Words", "ja": "ホットワード" },
  "隐式引用": { "en": "Implicit Reference", "ja": "暗黙の参照" },
  "默认标题": { "en": "Default Title", "ja": "デフォルトのタイトル" },
  "导出信息": { "en": "Export Information", "ja": "情報をエクスポートする" },
  "我的项目": { "en": "My Project", "ja": "私のプロジェクト" },
  "项目管理": { "en": "Project Management", "ja": "プロジェクト管理" },
  // 更多省略.....
}

结果出乎意料的好,几秒钟就生成好了我项目所有的语言配置信息。

这里我使用的是 coze, 模型选择:GPT4 Turbo 128k,其他参数默认

代码示例

自定义国际化的全部代码

// language.ts
import { computed } from "vue"

type Lang = 'en' | 'ja'
const defaultLanguage = 'zh_CN'

// 支持的语言列表
export const languageOptions = [
    { value: 'en', label: 'English' },
    { value: 'zh_CN', label: '中文(简体)' },
]

// 翻译映射
export const languageMap = {
    "关系图": { "en": "Relationship Map", "ja": "関係図" },
    "包管理": { "en": "Package Management", "ja": "パッケージ管理" },
    "热词": { "en": "Hot Words", "ja": "ホットワード" },
    "隐式引用": { "en": "Implicit Reference", "ja": "暗黙の参照" },
    "默认标题": { "en": "Default Title", "ja": "デフォルトのタイトル" },
    // 更多省略.....
} as const

// 获取翻译文本
export function $tf(text: keyof typeof languageMap) {
    const language = localStorage.getItem('language') || defaultLanguage

    if (language === defaultLanguage) return text
    return languageMap[text][language as Lang]
}

// 切换语言
export function switchLanguage (type: Lang) {
    localStorage.setItem('language', type)
    window.location.reload()
}

使用:

// test.ts
import { $tf, switchLanguage } from '@/language';

// 已存在的文本
const test = $tf('关系图')

// 映射表里不存在的文本, ts 会报错
const test = $tf('关系图1') // error: 类型“"导出信息1"”的参数不能...

// 切换语言
switchLanguage('en')

切换语言后,我使用 window.location.reload()刷新当前系统,是因为项目不存在什么表单信息,可以直接刷新,不影响体验。

批量替换

上面已经准备好了翻译库,接下来就是将项目中的所有中文调用 $tf()获取文本,这里我们使用正则一键替换:

20240625174551.png

  1. 中文字符串替换
  • 正则:(['"][\u4e00-\u9fa5]+[^'"]+['"])

  • 替换:$tf($1)

  1. vue template 中文字符串替换
  • 正则: >([\u4e00-\u9fa5]+)

  • 替换:>{{$tf('$1')}}

  1. 处理漏网之鱼

肯定还有一些没被正确替换的,我们还是继续用 [\u4e00-\u9fa5]+ 正则去搜索检查,看看是不是所有的中文都被处理。

  1. 收尾工作

这样,我们就可以把大部分字符串一键替换,不过还有一些收尾工作:

  • 修正自动替换错误的内容。

  • 补全 import 信息。

  • 不同语言长度不一致,我们还需要切换不同的语言,修正页面样式到合适的宽度。

完成效果

英语

20240626171456.png

日语

20240625191355.png

总结

到此为止,整个国际化的工作就完成了。以上只是提供一种思路,当然,如果你的使用的 i18n, 同样也可以使用 AI 生成自定义的 json。核心 promt 如下:

{list}
将上面的列表转换成如下格式的json列表:
{
 '{上面的某一项}': { 'en': '{对应的英文翻译}', 'ja': '{对应的日语翻译}' },
 ...
}

希望能帮助到你~