React-每个组件的翻译

Pal*_*čák 2 translation internationalization i18next reactjs create-react-app

我正在为我的React应用程序使用create-react-app,目前正在尝试找出翻译。

现在,我在每个语言环境中都有一个大的JSON文件,每个语言环境文件都包含所有组件的翻译-这并不理想,我希望每个组件都有单独的翻译文件。

因此,语言环境的结构将如下所示:ComponentA-语言环境-en.json-sk.json

ComponentB-语言环境-en.json-sk.json

实现此目标的最佳方法是什么?我应该使用哪些模块来实现这一目标?

我不想将这些语言环境文件包含到构建中,因为我们将支持10种语言,因此捆绑包的大小将太大。

Pal*_*čák 5

我要回答我自己的问题。经过研究,我发现用例很少,因此我决定进行一些语言环境预处理以实现所需的功能。

我正在与create-react-app一起运行默认配置,react-i18next我的文件结构如下所示:

src
  - Component A
    - locales
      - en.json
      - sk.json
  - Component B
    - locales
      - en.json
Run Code Online (Sandbox Code Playgroud)

以下是该react-i18next模块的设置:

i18n
  .use(Backend)
  .use('en')
  .use(reactI18nextModule)
  .init({
    fallbackLng: 'en',
    debug: false,
    backend: {
      loadPath: function() {
        return `${config.BASE_URL}locales/{{lng}}.json`;
      }
    },
    react: {
      wait: true
    }
  });
Run Code Online (Sandbox Code Playgroud)

由于我使用的是默认配置,create-react-app因此可以从public应用程序的文件夹中提供语言环境并自行构建。

现在变得棘手。由于语言环境文件位于组件树中(而不是公共文件夹中),因此我们需要对语言环境进行一些预处理-基本上,我们需要合并所有JSON文件并将其移至公共文件夹中。

使用以下节点任务(prepare-locales.js)即时创建公用文件夹文件:

const jsonConcat = require('json-concat');
const minifyJson = require('minify-json');
const glob = require('glob');
const availableLocales = ['en', 'sk'];
const path = require('path');

module.exports.development = function() {
  availableLocales.forEach(locale => {
    glob(`./src/**/locales/${locale}.json`, {}, (err, globFiles) => {
      if (globFiles.length) {
        const file = `./public/locales/${locale}.json`;

        jsonConcat(
          {
            src: globFiles,
            dest: file
          },
          json => {
            minifyJson(file);
          }
        );
      }
    });
  });
};

module.exports.production = function() {
  glob('./build/static/js/main.*.js', {}, (err, globFiles) => {
    const files = require('source-map-explorer')(globFiles[0]).files;

    let localeFolders = [];
    Object.keys(files).forEach(fileName => {
      localeFolders.push(path.dirname(fileName).replace('./', ''));
    });
    localeFolders = [...new Set(localeFolders)];

    availableLocales.forEach(locale => {
      const localeFiles = localeFolders.map(
        lf => `./src/${lf}/locales/${locale}.json`
      );

      if (localeFiles.length) {
        const file = `./build/locales/${locale}.json`;

        jsonConcat(
          {
            src: localeFiles,
            dest: file
          },
          json => {
            minifyJson(file);
          }
        );
      }
    });
  });
};
Run Code Online (Sandbox Code Playgroud)

对于开发版本,我将隐藏在树中找到的所有JSON文件。

对于生产版本,我正在使用,source-map-explorer而我仅隐含构建中使用的那些语言环境。

这是我简化package.json的工作所需的任务:

{
  "devDependencies": {    
    "json-concat": "0.0.1",
    "minify-json": "^1.0.0",
    "npm-watch": "^0.4.0",
    "path": "^0.12.7",
    "react-scripts": "2.1.1",
    "source-map-explorer": "^1.6.0"
  },
  "scripts": {    
    "start": "react-scripts start & npm run prepare-locales:development:watch",
    "build:production": "react-scripts build && npm run prepare-locales:production",    
    "prepare-locales:development:watch": "npm-watch prepare-locales:development",
    "prepare-locales:development": "node -e 'require(\"./prepare-locales.js\").development()'",
    "prepare-locales:production": "node -e 'require(\"./prepare-locales.js\").production()'"
  },
  "watch": {
    "prepare-locales:development": {
      "patterns": "src/**/locales/",
      "extensions": "json"
    }
  }  
}
Run Code Online (Sandbox Code Playgroud)

也许这不是最好的解决方案,但它适用于我的用例,并希望它将对遇到类似问题的人有所帮助。