国际化探索:提升开发体验与灵活性

date
Mar 17, 2025
slug
i18n-2
status
Published
tags
i18n
Technology
summary
最近公司平台需国际化改造,以适配不同语言环境。基于特定需求,展开了一系列技术探索与实践。
type
Post
在上一篇文章中,我们探讨了通过颗粒化方案实现平台的国际化改造。虽然该方案在减少语言包体积方面表现出色,但对开发者的友好度欠佳。
国际化探索:颗粒化方案
本文将介绍一个另一种方案,着重提升开发体验,同时保持语言包体积的优化。
 

优化方案

该方案在第一版的基础上进行了优化,主要改进如下:
  1. 单语言加载:只加载当前语言所需的语言包,减少不必要的加载。
  1. namespace 拆分与路由拆分:根据不同的命名空间和路由,对语言包进行拆分,进一步减小单个语言包的体积。
  1. 提高开发体验:引入 TypeScript 智能提示,提升开发效率和体验。

i18n 实现

以下是 I18nService 的部分实现:
 
看一下 I18nService 内部的实现,最基础的内容就是语言的检测,如果需要通过其他参数可以自行处理。
 

NS 拆分(路由拆分)

通过 loadNSunloadNS 方法,可以动态加载不同路由下的语言包内容。
同时也可以设置如 common 等通用语言包来进行全局使用,此功能的想法来此上一篇文章提及的 I18nProvider
同时也只会加载当前检测到的语言对应的语言包,能够进一步节省其语言包使用空间。

单语言加载

但其实还有另一种实现,这里并没有使用,通过资源路径的方式取加载,这样更方便,只是是异步的。
我们可以将 i18n 文件统一放在 public 目录下,然后进行统一访问,就能实现如下功能:
这样就会去找对应语言包目录下的 ns,实现更加精准的加载。

翻译函数

优化后的 t 函数支持参数传递、函数形式,并增强了 TypeScript 类型支持:
看一下 t 函数 的内部的逻辑:
  1. 转为数组
    1. 因为其参数既支持数组也支持字符串,所以统一转为数组进行处理。
  1. 找到每一个标识对应的翻译,并进行拼接。
  1. 翻译参数处理
    1. t 函数支持匿名参数、命名参数以及默认值等内容,来动态的返回其翻译。
  1. 返回最终翻译

使用

通过案例,可以看到 t 函数的灵活,包括其提供的类型提示,很大程度上增强了开发体验。
 

缺失翻译处理

添加一个 handleMissingTranslation 来处理未命中的情况,来进行兜底处理。
 

类型提示

通过 NestedTranslationPath 类型,实现对翻译键的强校验和智能提示:

语言包强校验

在一开始 i18n 实现 里面用到了如下的类型。
这里的用处是用于强校验不同语言包之间的 key 是否缺失。
如下所示:

t 函数路径提示

需要从两个方面来获取:
  1. 语言包声明上
回头看一下 I18nService 的声明:
用到了 NestedTranslation。它会解析所有的语言包得到所有的 key。
  1. Path 拆解
t 函数 用到了 Path
这里的 K 是继承 T 的,而 T 就是所有语言包对象的 key 值,P 则是根据对应的 NS 得到最终是哪个语言包下面的 key 值来进行提示。
两者进行结合,最终得到了完整的类型提示:
notion image
 

使用

接下来,来从一个案例具体看看其用法。

语言包定义

首先我们定义一个通用的语言包,其 NS 为 common。
其目录结构如下:
语言包内容如下:
zh.ts
en.ts
这里可以注意到 英文语言包里的 翻译内容继承了一个类型。
这是翻译类型校验,以一个语言包为标准,确保其他语言包不会缺少字段进行校验。
其类型写在了 index.ts 文件中。
index.ts
通过 loadNS 来加载语言包。
到这里为止是一套 NS 实现的组合包。
如果是异步加载 public/i18n 的情况,将其根据 lang 分别放置即可。这里不再做演示。
ps: 如果使用这种方式的话,要注意应使用 js 或 json。
 
再来看一下 i18n 的入口。
这里注意一下 I18nService<{ common: CommonTranslation }>,这里是实现类型提示的关键,和上面的翻译类型校验同理,获取其中的所有 key,为后续的 t 函数提示做铺垫。
 

组件中使用

这里注意一个点,在路由切分或者其他拆分的情况下,记得将导入 import './i18n' 放在顶部,以防止其导入的组件已经用到了其 NS。
 
第二版方案在开发体验上进行了显著优化,通过单语言加载、namespace 拆分和 TypeScript 智能提示,提高了开发效率和代码可维护性。同时,基于路由拆分和语言包拆分,分散其整体 i18n 体积。
 

© JinSo 2021 - 2025