Что я наконец сделал:
Я создал каталог в / assets для хранения всех файлов перевода json.
При тестировании или разработке, при каждом запросе я проверяю если эти файлы были обновлены до или после / locales json files.
/ server. js
const { watchAssetsTrads } = require("./middleware/clientSideTrads");
const notInProd = env === "test" || env === "dev";
if (notInProd) app.use((req, res, next) => watchAssetsTrads(next));
I Мне нужно улучшить этот следующий файл, так как я узнал, как плохо справлялся со своими обещаниями, хотя он отлично работает.
/ middlewares / clientSideTrads. js
const debug = require("debug")("trads");
const fs = require('fs');
const lodash = require('lodash');
const path = require('path');
const locales = path.join(__dirname, '../locales/');
const assetsTrads = path.join(__dirname, '../assets/trads');
const getFilesNamesFrom = path => {
return new Promise((resolve, reject) => {
fs.readdir(path, (err, files) => {
if (err) return reject(err);
return resolve(files.filter(e => e !== ".DS_Store"));
});
});
};
const read = jsonPath => {
return new Promise((resolve, reject) => {
fs.readFile(jsonPath, (err, data) => {
if (err) return reject(err);
return resolve(JSON.parse(data));
});
});
};
const update = (jsonPath, newJson) => {
return new Promise((resolve, reject) => {
fs.writeFile(jsonPath, JSON.stringify(newJson), err => {
if (err) return reject(err);
return resolve();
});
});
};
const getLastUpdateTime = filePath => {
return new Promise((resolve, reject) => {
fs.stat(filePath, (err, stats) => {
if (err) return reject(err);
return resolve(stats.mtime);
});
});
};
const updateAssetsTrads = async (localesTradPath, assetsTradPath) => {
const localesTrad = await read(localesTradPath);
const selectedKeys = lodash.pickBy(localesTrad, function(value, key) {
if ((/^clientside/u).test(key)) return true;
return false;
});
await update(assetsTradPath, selectedKeys);
return null;
};
const watchAssetsTrads = async next => {
debug('Checking asset trads');
const files = await getFilesNamesFrom(locales);
files.forEach(async file => {
try {
const localesTradPath = path.join(locales, file);
const assetsTradPath = path.join(assetsTrads, file);
const lastUpdate = await getLastUpdateTime(localesTradPath);
const lastMerge = await getLastUpdateTime(assetsTradPath);
if (lastUpdate > lastMerge) {
updateAssetsTrads(localesTradPath, assetsTradPath);
debug('File updated');
}
}
catch (err) {
return debug(err);
}
return null;
});
return next();
};
module.exports = {
watchAssetsTrads
};
С i18n я управляю переводами через повара ie. Как я уже упоминал, мне нужно было использовать файл сценария, включенный во все страницы нижнего колонтитула. Там я импортировал это:
getCurrentLanguage. js
const getCookie = () => {
const cookies = document.cookie.split('; ');
const myCookie = cookies.filter(c => (/^my-cookie/u).test(c));
if (typeof myCookie[0] == 'undefined') return 'fr';
const cookieSplitted = myCookie[0].split('=');
const currentLanguage = cookieSplitted[1];
return currentLanguage;
};
const getCurrentLanguage = () => {
const currentLanguage = getCookie();
return currentLanguage;
};
export { getCurrentLanguage };
И затем я получаю все переводы и возвращаю один доступен для текущей языковой клиентской части (я понимаю, что мне нужен только один файл перевода, улучшается в будущем).
getTrads. js
const createTradsObjFrom = async (languages, tradsPaths) => {
try {
const obj = {};
for (const [index, lang] of languages.entries()) {
const path = tradsPaths[index];
obj[lang] = {
json: await $.getJSON(path)
};
}
return obj;
}
catch (err) {
throw new Error("some error");
}
};
const getTrads = currentLanguage => {
return new Promise((resolve, reject) => {
const tradsDir = "/assets/trads/";
const languages = [
"de",
"en",
"es",
"fr",
"it",
"nl",
"ru"
];
const tradsPaths = languages.map(e => tradsDir + e + '.json');
createTradsObjFrom(languages, tradsPaths)
.then(trads => resolve(trads[currentLanguage].json))
.catch(err => reject(err));
});
};
export { getTrads };