我正在为我的React应用程序使用create-react-app,而我目前正在尝试找出翻译。
现在,我每个语言环境都有一个大的JSON文件,每个语言环境文件都包含所有组件的翻译-这并不理想,我希望每个组件都有单独的翻译文件。
因此语言环境的结构如下所示: 组分A -语言环境 -en.json -sk.json
ComponentB -语言环境 -en.json -sk.json
实现此目标的最佳方法是什么?我应该使用哪些模块来实现这一目标?
我不想将这些语言环境文件包含到构建中,因为我们将支持10种语言,因此捆绑包的大小将太大。
答案 0 :(得分:2)
我要回答我自己的问题。经过研究,我发现用例很少,因此我决定进行一些语言环境预处理以实现所需的功能。
我正在与create-react-app
一起运行react-i18next
的默认配置,我的文件结构如下所示:
src
- Component A
- locales
- en.json
- sk.json
- Component B
- locales
- en.json
以下是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
}
});
由于我使用的是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);
}
);
}
});
});
};
对于开发版本,我将隐藏在树中找到的所有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"
}
}
}
也许这不是最好的解决方案,但它适用于我的用例,希望它将对遇到类似问题的人有所帮助。
答案 1 :(得分:0)
这是一个如何将i18next + React + Typescript与类定义和用于翻译的单独文件一起使用的示例https://gitlab.com/damjan89/i18next-typescript-example