[Vscode]使用[i18n ally 插件]管理你的前端国际化项目

982 阅读4分钟

最近非常惊讶,工作过程中发现很多做国际化项目的同事,居然没有用过任何国际化管理插件...

实在不能容忍大家还停留在"农耕时代",于是特意花时间详细整理了一下过去的笔记,配上大量gif动态图。

以后抓到一个"农民",直接链接贴脸!

应用场景

针对所有需要引入国际化插件的项目,如vue-i18n

国际化后新增的开发难点

1,变量替换文本后,可读性极差

image.png

login.loginText 这种规范命名还能勉强猜测到文本内容,但是对于不熟悉的词汇、长提示语等几乎无法猜测,后续定位问题时难度增加

2,翻译文本较难管理

image.png

  • "登录" 文本 的英文、德语等等版本是否已翻译完成?内容是什么样?
  • 我现在需要修改内容,其他N个版本要怎样才能快速修改?
  • 如何查看本项目整体翻译状况,翻译进度是怎么样?是否有遗漏?
  • 如何自动翻译?

在语种、语言内容逐渐增多时,会越发难以查阅和管理文本的翻译情况。

3,添加新文本时难以查重和管理

  • 新的文本是否已经翻译过?
  • 如何快速找到已翻译过的tag和文本?

当语种增多、内容增多、文本模块增多、多人合作时,以上问题会越发严重

推荐使用 i18n Ally 插件,都能解决以上问题。

展示一下最终效果

变量文本可视化

20250209215519_rec_.gif

快速添加文本标志

20250209222109_rec_.gif

自动检查已有翻译并快捷录入

20250209222321_rec_.gif

同时查看和管理所有语言版本

20250209215957_rec_.gif

全局管理翻译情况

20250209220704_rec_.gif

(以源语言为基础)自动翻译

这里可能需要梯子,否则 google 翻译无法正常运行!

20250209220205_rec_.gif

(项目)全局翻译

20250209221004_rec_.gif

i18n Ally 插件

All in one i18n extension for VS Code

i18n Ally 基本配置说明文档

只需要安装这一个插件,可以看到我的 Vuei18n 插件是没有安装的!

修改 .vscode/settings.json

{
    "i18n-ally.localesPaths": ["src/lang"], // 翻译文件项目路径 
    "i18n-ally.keystyle": "nested", // 翻译路径格式 ( nested:嵌套式  flat:扁平式)
    "i18n-ally.sortKeys": true,
    "i18n-ally.namespace": true,
    "i18n-ally.enabledParsers": ["json"], // 翻译文件可允许的格式,默认json。
    "i18n-ally.sourceLanguage": "zh-CN", // 翻译源语言 (源文件) 
    "i18n-ally.displayLanguage": "zh-CN", // 显示语言 (显示文件/翻译文件)
    "i18n-ally.translate.engines": ["deepl", "google"], // 翻译器
    "i18n-ally.extract.keygenStyle": "camelCase", // 翻译字段命名样式采用驼峰
    "i18n-ally.enabledFrameworks": [
        "vue"
    ],
    "workbench.activityBar.visible": true,
}
  • localesPathssourceLanguage,需要根据项目语言文件路径,语言标识情况修改。
  • enabledParsers 只推荐 json

以一个vue3项目为例

vue-i18n -- 这是一个项目插件,跟vscode 插件无关。

文件结构

image.png

注意:最好提前将对应语言的json文件都创建好,方便后续步骤。

lang/index.ts

import { createI18n, I18nOptions } from 'vue-i18n';
import type { App } from 'vue';

const zhModules = import.meta.glob('./zh/*.json', { eager: true });
const enModules = import.meta.glob('./en/*.json', { eager: true });

const zhObj = getLangByModules(zhModules);
const enObj = getLangByModules(enModules);

const messages = {
  ...zhObj,
  ...enObj,
} as I18nOptions['messages'];

/**
 * 获取当前系统使用语言字符串
 *
 * @returns zh|en ...
 */
export const getLanguage = () => {
  // 浏览器使用语言
  const language = localStorage.getItem('language') || navigator.language;
  // const language = 'en';
  const locales = Object.keys(messages as any);

  for (const locale of locales) {
    if (language.indexOf(locale) > -1) {
      return locale;
    }
  }
  return 'zh';
};

const i18n = createI18n({
  legacy: false,
  locale: getLanguage(),
  messages: messages,
  globalInjection: true,
});

export function setupI18n(app: App<Element>) {
  app.use(i18n);
}

export default i18n;
// ---------------- function --------------------------

/**
 * 需要保证文件夹内至少有一个json文件,方便获取到文件名
 * 注意:当对应文件夹内匹配不到json文件时, 会连整个语言类型都不会注册,即  enObj 为 {} 而不是 { en: {} }
 * @returns
 */
function getLangByModules(modules: any) {
  const moduleArr = Object.keys(modules);
  const langMsgObj = moduleArr.reduce((obj: any, key) => {
    const content = (modules[key] as any).default || {};
    const langType = key.split('/')[1];
    const moduleName = key.split('/')[2].split('.')[0];

    if (obj[langType] === undefined) {
      obj[langType] = {};
    }
    obj[langType][moduleName] = content;
    return obj;
  }, {});
  return langMsgObj;
}

使用过程种遇到的坑点总结

坑点1: i18n侧边栏没有出现

情况:如果i18n能正常工作,但是侧边栏没出现,

image.png

原因:可能是因为当前版本的侧边栏图标是默认隐藏的

解决方案:右键侧边栏 --- 勾选 i18n 即可

image.png

坑点2:批量翻译异常,居然反过来把原本的语言改了

情况:点击批量翻译时,没有看到新的文件被创建,反而是原本的中文被替换成英文了

原因:可能是对应翻译版本的文件没有创建。 比如中译英, zh-CN/form.json 存在,但是 en/form.json 不存在,就会出现这个问题。

解决方案:提前创建好对应语言版本的json文件

image.png