前端国际化文件拆分

· 2 min read

前端对于静态显示的内容如标题,弹框文本等,有时需要做国际化。随着国际化的内容增多,单个文件下进行维护就显得不怎么方便。这时我们需要按照功能等拆分为多个JSON或者JS文件,这样维护性上便会提高。

拆分后的JSON文件我们希望是这样

image

如何实现呢,继续看。

环境

这里贴下,我实现时的环境

  • React v16.4.2
  • React-intl v^2.7.2
  • Webpack v4.17.1

安装 merge-jsons-webpack-plugin插件

yarn add  merge-jsons-webpack-plugin --dev

Webpack配置

const MergeJsonWebpackPlugin = require('merge-jsons-webpack-plugin');

new MergeJsonWebpackPlugin({
      output: {
        groupBy: [
          {pattern: "./src/main/webapp/i18n/en/*.json", fileName: "./i18n/en.json"}
          // jhipster-needle-i18n-language-webpack - JHipster will add/remove languages in this array
        ]
      }
    })

APP中加载

以下为react程序加载code,angular,vue等类似。

export const getLocale = lang => axios.get(`/i18n/${lang}.json`);


setupAxiosInterceptors(() => (location.href = '/#/login'));
const rootEl = document.getElementById('root');
const messages = {};
const locale = 'en';
const render = () =>
  ReactDOM.render(
    <AppContainer>
      <IntlProvider locale={locale} messages={messages[locale]}>
        {
          // @ts-ignore
          <Provider store={store}>
            <AppComponent />
          </Provider>
        }
      </IntlProvider>
    </AppContainer>,
    rootEl
  );

getLocale(locale).then(res => {
  messages[locale] = res.data;
  render();
});

原理

原理简单,但还是啰嗦下,Webpack作为构建工具,将N个JSON文件合并为一个,移动到特定的路径下,而我们WEB请求了合并后的文件,从而对外是一个文件,而在维护编写层面却可以是多个。中间的构建合并交给了Webpack解决。

合并后的文件缓存问题

都知道,前端其实会有缓存机制,对于不变的前端资源,比如图片视频,国际化等,假如我们增加了部分翻译,但是用户访问的还是缓存化的文件,怎么办呢。这时我们就要想办法,让浏览器不使用缓存文件而走新的。

解决办法

请求增加时间戳参数,利用增加参数改变了请求地址,自然就不会走缓存了。 效果即是,前端构建打包新版,用户就会走新的i18n文件,否则走缓存。

export const getLocale = lang =>
  axios.get(`/i18n/${lang}.json`, {
    params: {
      buildTimestamp: process.env.BUILD_TIMESTAMP
    }
  });

最佳方案是?

上面的办法可以解决,但再想想。

严谨来说 构建时间跟i18n变化不变化其实是必要条件而非充分必要条件,最好的方案是假如i18n文件内容发生变化,则请求就走新的,否则走缓存,这就完美了。

能不能做到呢?肯定是可以的。不都是代码嘛。假如要做到,应该是MergeJsonWebpackPlugin合并json文件时增加哈希指纹【就像JS打包一样】,进而请求文件地方,打上合并后的文件名即可。可惜目前插件不支持,等着咱们开发呢,不是吗。

结语

到这里,应该完了。目前没新坑发现。 问题虽小,但却基础。bye!