React的i18next国际化从全量改为页面引入

360 阅读1分钟

原来一次性引入整个项目的所有国际化文件

  1. 项目原来用i18next作为国际化,配置文件
backends: [
    resourcesToBackend((language, namespace, callback) => {
      import(`@/locales/${language}.ts`)
        .then((resources) => callback(null, resources.default))
        .catch((error) => callback(error, null));
    })
]
  1. zh-CN下,是所有的翻译文件,通过一个index.js引入所有的翻译内容 如:
import a from './a.js';
import b from './b.js';
import c from './c.js';

export default {
    a,
    b,
    c
}
  • 这样有个严重的问题是,当项目很大的时候,相当于一次性加载了项目中所有的翻译内容,导致项目启动编译时间非常长,或者单文件太大,导致内存溢出。

改进方式,页面级别引入

import { lazyI18N } from '@/lazy-i18n';
import enUS from '@/locales/en-US/a';
import zhCN from '@/locales/zh-CN/a';
import zhHK from '@/locales/zh-HK/a';

lazyI18N({ 'zh-CN': zhCN, 'en-US': enUS, 'zh-HK': zhHK });


// lazy-i18n.js文件

import i18n from 'i18next';

export const lazyI18N = (pathObj: any) => {
  const language = localStorage.getItem('hl') || 'zh-CN';
  i18n.addResources(language, 'cc-admin', pathObj[language]);
};

旧版本替换的脚本

const fs = require('fs');
const path = require('path');
const { exec } = require('child_process');

function getAllFiles(dirPath, arrayOfFiles = []) {
  const files = fs.readdirSync(dirPath);

  files.forEach(function (file) {
    if (fs.statSync(path.join(dirPath, file)).isDirectory()) {
      arrayOfFiles = getAllFiles(path.join(dirPath, file), arrayOfFiles);
    } else {
      arrayOfFiles.push(path.join(dirPath, file));
    }
  });

  return arrayOfFiles;
}

const files = getAllFiles('./src/locales/zh-HK/a');
const needImport = files.map((filePath) => filePath.replaceAll('src/locales/zh-HK', 'src'));

const importStatement = "import { lazyI18N } from '@/lazy-i18n';";

needImport.forEach((src) => {
  let realSrc = src.replaceAll('.js', '.tsx');
  try {
    fs.accessSync(realSrc, fs.constants.F_OK);
  } catch (e) {
    realSrc = src.replaceAll('.js', '.ts');
    try {
      fs.accessSync(realSrc, fs.constants.F_OK);
    } catch (err1) {
      realSrc = '';
    }
  }
  if (realSrc !== '') {
    fs.readFile(realSrc, 'utf8', (err, data) => {
      if (err) return console.log(err);

      let result = `${data}`;
      const pSrc = realSrc.replaceAll('src', '').replaceAll('.tsx', '').replaceAll('.ts', '');
      const isExistImportStatement = data.indexOf(importStatement);

      if (isExistImportStatement === -1) {
        const enUS = `import enUS from '@/locales/en-US${pSrc}';`;
        const zhCN = `import zhCN from '@/locales/zh-CN${pSrc}';`;
        const zhHK = `import zhHK from '@/locales/zh-HK${pSrc}';`;
        const fn = "lazyI18N({ 'zh-CN': zhCN, 'en-US': enUS, 'zh-HK': zhHK });";
        result = `${importStatement}\n${enUS}\n${zhCN}\n${zhHK}\n${fn}\n${data}`;
      }

      fs.writeFile(realSrc, result, 'utf8', (e) => {
        if (e) return console.log(e);
        exec(`eslint --fix ${realSrc}`);
        return true;
      });
      return true;
    });
  }
});