前端国际化,该如何实现按需加载语言包?

简介: 前端西瓜哥

笔者最近接手了公司的国际化开发需求,花了不少时间调研了国际的一整套实施方案,有一点小心得,和大家分享一下。

本文仅针对国际化其中的一个小点 “按需加载语言包” 做分析。

前端国际化是什么?

所谓前端国际化,就是根据用户的语言设置以及浏览器的环境计算出网站能支持的一种语言,然后将网站的文案替换为对应语言的文案。

方案有:

  1. 针对不同语言,打包为不同的项目编译包,在 编译过程 国际化;
  2. 使用一个项目,通过 id 和语言来映射最终文案,在 运行过程 国际化;

第一种方案,在用户请求页面时就返回编译好的对应语言的 html。具体开发操作,其实就是将项目再拷贝一份,将里面的语言改为另一种语言,维护起来比较麻烦,只适合一些相对简单的静态页面。

或者可以利用打包工具,打包多份的构建文件包,但我没调研出什么可行具体方案,直觉告诉这可能不好测试、不好定位 BUG、不好维护,没有做太多的深入研究。

第二种方案更主流,在脚本运行时确定语言,再配合 id 获取文案,渲染到页面上。

需要保存 id 到文案的映射,形式就像下面这样:

constlocale= {

 'zh-CN': {

   hello: '你好',

   thank: '谢谢',

   steamedBuns: '小笼包',

   goodbye: '再见'

 }

}

不过更常见的是使用 json 文件来保存,并将不同的语言的 json 放到 locale 目录下:

projectRoot

|-- lang

|   |-- en-US.json

|   |-- fr.json

|   |-- zh-CN.json

然后我们在业务代码中使用对应的语言包,然后在用到文案的地方,通过 id 拿到文案。比如 React 中,可以这样使用:

<div>{ intl.formatMessage({ id: 'hello' }) }</div>

// 渲染为

<div>你好</div>

为什么需要按需加载语言包?

所谓按需加载语言包,就是只加载用到的语言包,而不是把所有的语言包一股脑全部加载。

单一一种语言的语言包其实已经很大了,而且随网站的页面数不断增加,文案增多,语言包的大小也会日益增大。比如我参与的项目中,单独一个语言包在不压缩的情况下,行数约为 500 行,文件大小约为 300K,以后还会更多。

如果不做按需加载,做全量加载的话,每多一个语言,文件就要增加 300K。每多一个文案,就要增加 n 行的文案。其实没有必要。

按需加载的方案

方案 1:后端返回的 HTML 直接带上语言包脚本

比如 notion 网站的语言设置如果为韩语,会通过在 HTML 里嵌入的方式,带上一个韩语对应的 JSON 语言包。

<scriptid="messages"type="application/json"data-locale="ko-KR">

   {"FrontPricingPage.individualSection.header":"개인용", ... }

</script>

然后后续的业务代码可以通过通过 JSON.parse(document.getElementById('messages').innerText) 拿到这个语言包对象。

或者可以直接嵌入一个 window.TTi18n = xxx 的 script 脚本,效果都一样,但去掉了 JSON 转换为对象过程。

这里的重点是 请求页面时后端要一次性计算出用户语言。这点可以配合 HTTP 请求头字段(Accept-Language, User-Agent)和用户信息来判断,然后将对应的语言包拼到 HTML 上返回。具体逻辑为:

  • 用户没有设置过语言 ==> 取 Accept-Language 中的第一权重语言;User-Agent 用于处理一些比较特别的客户端(比如钉钉浏览器)==> 如果该语言没有对应语言包,使用兜底语言包,通常为英文 ==> 计算结束
  • 用户设置了语言 ==> 结束

缺点:

  • 不能利用缓存,HTML 一般是不做缓存的;
  • 前后端配合有对接成本和沟通成本;
  • 语言包内容较多,拼到 html 消耗服务器资源;

方案2:前端通过动态 import 导入语言包

后端返回的模板填充好用户设置的语言。需要拼到 html 里面,比如放到全局的 useInfo 对象的 locale 属性中。不拼到 html 里的话,前端就需要多请求一个用户语言设置的接口,没太大必要。

然后和前端计算出客户端语言(navigator.language)进行组合,得到最后的语言。当然这一步也可以让后端去处理,就是方案 1 提到后端利用 HTTP 请求头字段去计算。

接着使用动态 import 加载语言包,加载的语言包可以暴露到全局环境中,再进行 React 的初始化渲染,或者是通过 context 注入到 React 组件中(React-Intl 的做法)。

例子:

locale 目录下的 zh-CN.json 文件

{

  "hello": "你好",

  "thank": "谢谢",

  "steamedBuns": "小笼包",

  "goodbye": "再见"

}

React 的入口文件

import(

 /* webpackChunkName: "lang" */

  `./locale/${lang}.json`

 ).then(m=> {

   window.TTi18n=m.default;

   ReactDOM.render(/* ... */);

})

如果使用的是 webpack,webpack 会解析代码,将 locale 目录下的每个 json 文件打包为单独的一个模块文件。我在代码中使用了 魔法注释,指定了模块文件的名字为 lang,所以最后打包的文件名格式会像这个样子:lang0.90dfe781.chunk.jslang1.fe9ff131.chunk.js

webpack 给这些文件添加了哈希值,文件如果内容没有变化,就能很好地使用缓存。当内容发生了更新,文件名就会改变,就不会走缓存,浏览器顺利拿到最新的语言包。

结语

总的来说,我觉得第二种方式,即动态 import 的方式来实现按需加载语言包要更合适。缺点是需要多请求一次语言包,不过可以有效利用缓存,其实也不算是缺点。

相关文章
|
2月前
|
前端开发 JavaScript 开发者
|
3月前
|
缓存 前端开发 JavaScript
前端优化之路:打包文件拆包、增加哈希值
前面对项目打包做了优化处理,但是还不够完美,有两点可继续优化。
|
2月前
|
存储 前端开发 JavaScript
前端语言串讲 | 青训营笔记
前端语言串讲 | 青训营笔记
29 0
|
3月前
|
开发框架 自然语言处理 前端开发
循序渐进VUE+Element 前端应用开发(9)--- 界面语言国际化的处理
循序渐进VUE+Element 前端应用开发(9)--- 界面语言国际化的处理
|
4月前
|
前端开发 JavaScript 测试技术
web前端语言框架:探索现代前端开发的核心架构
web前端语言框架:探索现代前端开发的核心架构
63 4
|
3月前
|
前端开发 JavaScript
前端 JS 经典:Vite 分包配置
前端 JS 经典:Vite 分包配置
94 0
|
5月前
|
前端开发 JavaScript Java
Java语言在Web前端开发中的技术应用
Java语言在Web前端开发中的技术应用
|
5月前
|
自然语言处理 前端开发 开发者
【Flutter前端技术开发专栏】Flutter中的国际化与本地化支持
【4月更文挑战第30天】Flutter支持国际化与本地化,借助`Intl`包和`Localizations`类,帮助开发者实现多语言应用。`Intl`提供日期、时间格式化,而`Localizations`管理不同语言环境的资源。在`pubspec.yaml`添加`intl`依赖,创建本地化资源文件并定义`LocalizationsDelegate`。通过`Localizations.of()`获取本地化资源,实现应用适应不同语言环境。
198 0
【Flutter前端技术开发专栏】Flutter中的国际化与本地化支持
|
5月前
|
Dart 前端开发 开发者
【Flutter前端技术开发专栏】Flutter Dart语言基础语法解析
【4月更文挑战第30天】Dart是Google为Flutter框架打造的高效编程语言,具有易学性、接口、混入、抽象类等特性。本文概述了Dart的基础语法,包括静态类型(如int、String)、控制流程(条件、循环)、函数、面向对象(类与对象)和异常处理。此外,还介绍了库导入与模块使用,帮助开发者快速入门Flutter开发。通过学习Dart,开发者能创建高性能的应用。
53 0
【Flutter前端技术开发专栏】Flutter Dart语言基础语法解析
|
5月前
|
缓存 前端开发 JavaScript
【专栏】GraphQL,Facebook 开发的API查询语言,正在前端开发中崭露头角
【4月更文挑战第27天】GraphQL,Facebook 开发的API查询语言,正在前端开发中崭露头角。它提供强类型系统、灵活查询和实时更新,改善数据获取效率和开发体验。掌握GraphQL涉及学习基础概念、搭建开发环境和实践应用。结合前端框架,利用缓存和批量请求优化性能,与后端协作设计高效API。尽管有挑战,但GraphQL为前端开发开辟新道路,引领未来趋势。一起探索GraphQL,解锁前端无限可能!
81 2
下一篇
无影云桌面