国际化探索:颗粒化方案
date
Mar 10, 2025
slug
i18n-1
status
Published
tags
i18n
Technology
summary
最近公司平台需国际化改造,以适配不同语言环境。基于特定需求,展开了一系列技术探索与实践。
type
Post
最近公司平台需国际化改造,以适配不同语言环境。基于特定需求,展开了一系列技术探索与实践。
但是平台的国际化需满足以下前提:
- 不需要支持站内实时切换语言,需刷新页面完成切换。
- 平台包含大量业务页面,导致语言包体积庞大且各页面语言包独立性高;故尽可能的切割语言包,如按路由拆分,按需获取。
- 考虑到部分页面内容需要提前就需确定,无法采用异步加载语言包的方式。
颗粒化方案
方案核心
方案的核心是将国际化颗粒度细化到极致,通过以下步骤实现:
- 极致颗粒度国际化:将每个文本片段都独立处理。
- 利用 Tree Shaking:通过 TypeScript 的特性,移除未使用的 i18n 变量,减少体积。
- vite 插件提取 i18n 内容:将语言包按需拆分。
- 打包压缩:通过变量压缩等手段进一步减小语言包体积。
调研
i18n
fnando • Updated Mar 9, 2025
在调研过程中,我们发现大多数 i18n 实现库都侧重于站内切换语言,这会导致同时加载多个语言包,随着页面增多,语言包体积膨胀,不符合我们的需求。
不过,我们注意到了 I18nextProvider,它通过提供不同的 i18n 实例来加载不同的语言包,能在一定程度上实现路由间的分片加载,这启发了我们在第二版方案中实现类似的功能。
i18next-http-backend
i18next • Updated Mar 3, 2025
此外,对于异步加载语言包的方案,如将语言包放在 public 目录下,根据语言动态加载,虽然可行,但因一些限制,我们无法采用这种方式。
i18n 实现
以取浏览器语言为例
使用
语言包定义
组件中使用
打包优化
- Tree Shaking:利用 TypeScript 的特性,过滤掉未使用的 i18n 变量,减少打包体积。
- 变量压缩:通过压缩工具,将变量名进行压缩,进一步减小体积。例如:
语言拆分
利用 vite 配置和插件,将 i18n 语言包内容进行提炼和拆分。首先,通过 rollup 的 manualChunks 提取所有
i18n.ts
文件,并为其生成唯一的 chunk 名称。vite.config.js
打包之后,我们就能看到生成的 i18n 的文件:

然后,利用 vite 插件对这些 chunk 进行处理,将其中的语言包内容拆解成单独的语言文件,如
i18n-zh-*.js
和 i18n-en-*.js
,实现单语言加载。i18nPlugin.js
利用之前
manualChunks
打包好的 i18n 文件标识,取找到所有的文件并通过 AST 进行语言提炼,生成单独语言的新文件。
单语言映射
在
index.html
中加入一个标识,然后在 vite 插件中,通过 transformIndexHtml
方法,将提炼后的语言包文件进行载入并替换该标识,从而实现单语言映射。index.html
i18nPlugin.js
拆除了单独看这个替换的函数部分:
这里的 map 是关系,建立映射关系,将原本的语言包映射到单一语言包上。
比如原本引入的是
i18n-1abc4c9b-d12e7f4b.js
文件,通过映射之后,假设现在加载的是中文,那么就会变成 i18n-1abc4c9b-d12e7f4b.js
→ i18n-zh-1abc4c9b-d12e7f4b.js
,从而节省了一半的体积。该方案的主要优化逻辑是在打包阶段实现的,通过颗粒化处理和打包优化,显著减少了语言包的体积。然而,这种方式对开发者来说并不友好,开发体验较差。
在后续的方案中,我们将重点优化开发体验,通过单语言拆分和路由拆分等方向来改进。