2024年4月8日
By: Chase

CT项目多语言方案调整

前言

一个在博客里提到甲方名字会被投诉的桌面端electron项目, 前后端都打包在electron内交付.

基本要求支持多语言. 同时客户希望交付后自己能拓展业务文本翻译.

项目用i18next. 官网视频讲得很好了, 也提供了很多demo代码.

目前方案

目前的"机智"方案是多语言的设置全部从接口拿, 靠交付后客户自己设置.

比如要新增语言类型[en, zh], 再新增key, 比如name: { en: 'name', zh: 'zh'}. 然后接口拿到, 转入i18n的resource设置.

我用我七舅老爷的三姨妈打赌, 临交付要么后端内置db给全了基本语言包, 要么就是交付前公司安排个测试或者谁, 咔咔一顿录入, 然后再前端开发查漏补缺一通.

而且面临着开发过程中不能顺便把翻译的key做全了.

调整方案

  1. 基本的语言key包直接放到前端代码json维护.
  2. 接口拿到拓展的key做merge.

我之前做的比较成熟的国际化项目(东南亚5国), 以及i18n自己安利的https://locize.com/插件, 实际上都是将语言resource和前端项目分离, 通过接口服务获取.

因为我们是一个前后端都内置打包交付的项目, 如果后期交付了, 不能再发版.

所以还需要:

  1. 接口服务还需要支持拓展新增语言类型

图示: 图-2

开发要求

常规的div文本

import { useTranslation } from 'react-i18next'

const DemoDiv = () => {
    const { t } = useTranslation()
    return (
        <div>
            {t('你好')}
        <div>
    )
} 

提取出去的常量

// 原
const CONSTANTS = {
    title: '你好'
}

const DemoDiv = () => {
    return (
        <div>
            {CONSTANTS.title}
        <div>
    )
}

// 新
const getConstants = (t) => ({
    title: t('你好')
})

const DemoDiv = () => {
    const { t } = useTranslation()

    return (
        <div>
            {getConstants(t).title}
        <div>
    )
} 

antd的框架全面实现

项目里用了很多antd的组件, 需要同步翻译它的语言包.

官网文档有下面截图的这个玩意: ConfigProvider 的 locale.

图-1

代码在App.js的包裹实现是这样的:

// antd的语言包
import zh_CN from 'antd/lib/locale/zh_CN'
import en_GB from 'antd/lib/locale/en_GB'

const LANGUAGE_LIST = {
    zh: {
        name: '中文',
        value: 'zh',
        antdLocale: zh_CN
    },
    en: {
        name: 'English',
        value: 'en',
        antdLocale: en_GB
    }
}
const App = () => {
    // 全局redux里订阅当前语言设置
    // 注意 languageCode 需要和 LANGUAGE_LIST 的 key 对应上啊
    const { languageCode } = useSelector(state => state.global)

    ...

    return (
        <>
            ...
                <ConfigProvider
                    ...
                    // antd组件的语言包设置
                    locale={LANGUAGE_LIST[languageCode].antdLocale}
                >
                    ...
                </ConfigProvider>
            ...
        </>
    )
}

代码里的书写要求:

<Form>
    <Form.Item
        label={t('项目名称')}
        name="project_name"
        // 不写message, 自动会给英文提示'please enter {"项目名称"的翻译文本}'
        rules={[{ required: true }]}
        // 如果写message, 需要添加 {"请输入项目名称"} 的翻译文本
        rules={[{ required: true, message: t('请输入项目名称') }]}
    >
        <Input />
    </Form.Item>
</Form>
Tags: i18n 多语言