前端国际化解决方案
前端国际化的项目的时候,因为业务不是很复杂,相关的需求一般都停留在文案的翻译上,即国际化多语言,基本上使用相关的 I18n 插件即可满足开发的需求。但是随着业务的迭代和需求复杂度的增加,这些 I18n 插件不一定能满足相关的需求开发。这里讲一下技术栈基于 Vue的实现,因此相关的解决方案也是基于 Vue 以及相关的国际化插件(vue-i18n)进行展开。背景1- 没有大量语言包文...
以前做前端国际化的项目的时候,因为业务不是很复杂,相关的需求一般都停留在文案的翻译上,即国际化多语言,基本上使用相关的 I18n 插件即可满足开发的需求。但是随着业务的迭代和需求复杂度的增加,这些 I18n 插件不一定能满足相关的需求开发。
这里讲一下技术栈基于 Vue的实现,因此相关的解决方案也是基于 Vue 以及相关的国际化插件(vue-i18n)进行展开。
背景
1- 没有大量语言包文件
当项目比较简单,没有大量语言包文件的时候,将语言包直接打包进业务代码中是没有太大问题的。
2- 有大量语言包文件
这个时候是需要考虑:
- 语言包单独打包。
- 减少业务代码体积 。
- 通过异步加载的方式去使用。
- 考虑到国际化语言包相对来说是非高频修改的内容,因此可以考虑将语言包进行缓存,每次页面渲染时优先从缓存中获取语言包来加快页面打开速度。
解决方案
从 2.6.0 版本开始,webpack的 import 语法可以指定不同的模式解析动态导入,具体可以参见文档(https://webpack.docschina.org/api/module-methods/#import-)
因此结合 webpack 及 vue-i18n 提供的相关的 API 即可完成语言包的分包及异步加载语言包,同时在运行时完成语言的切换的工作。
文件目录结构:
src
|--components
|--pages
|--di18n-locales // 项目应用语言包
| |--zh-CN.js
| |--en-US.js
| |--pt-US.js
|--App.vue
|--main.js
main.js:
import Vue from 'vue'
import VueI18n from 'vue-i18n'
import App from './App.vue'
Vue.use(VueI18n)
const i18n = new VueI18n({
locale: 'en',
messages: {}
})
function loadI18nMessages(lang) {
return import(`./di18n-locales/${lang}`).then(msg => {
i18n.setLocaleMessage(lang, msg.default)
i18n.locale = lang
return Promise.resolve()
})
}
loadI18nMessages('zh').then(() => {
new Vue({
el: '#app',
i18n,
render: h => h(App)
})
})
以上首先解决了语言包的分包和异步加载的问题.
语言包做缓存,以及相关的缓存机制,思路
打开页面后,优先判断 localStorage 是否存在对应语言包文件,如果有的话,那么直接从 localStorage 中同步的获取语言包,然后完成页面的渲染,如果没有的话,那么需要异步从 CDN 获取语言包,并将语言包缓存到 localStorage 当中,然后完成页面的渲染.
语言包做缓存,以及相关的缓存机制, 需要考虑到以下的问题
如果语言包发生了更新,那么如何更新 localStorage 中缓存的语言包?
首先在代码编译的环节,通过 webpack 插件去完成每次编译后,语言包的版本 hash 值的收集工作,同时注入到业务代码当中。当页面打开,业务代码开始运行后,首先会判断业务代码中语言包的版本和 localStorage 中缓存的版本是否一致,如果一致则同步获取对应语言包文件,若不一致,则异步获取语言包
在 localStorage 中版本号及语言包的存储方式?
数据都是存储到 localStorage 当中的, localStorage 因为是按域名进行划分的,所以如果多个国际化项目部署在同一域名下,那么可按项目名进行 namespace 的划分,避免语言包/版本hash被覆盖。
总结:
初期对于国际化项目做的一些简单的优化。总结一下就是:语言包单独打包成 chunk,并提供异步加载及 localStorage 存储的功能,加快下次页面打开速度。
更多推荐
所有评论(0)