React应用改造为single spa后i18n失效无法加载translation.json怎么办
问题根源
当应用改造为single-spa微应用后,运行时的上下文域名为主应用域名,i18next-http-backend默认使用相对路径请求翻译文件,因此请求路径会自动拼接主应用域名,而非微应用本身的服务域名,导致404问题。该问题需要同时调整i18n配置与webpack配置解决。
解决方案
1. 调整i18n初始化配置
给i18next-http-backend指定完整的翻译文件请求路径,建议用环境变量区分开发/生产环境,避免硬编码:
import i18n from "i18next"; import { initReactI18next } from "react-i18next"; import i18nextHttpBackend from "i18next-http-backend"; import Cookies from "js-cookie"; import LanguageDetector from "i18next-browser-languagedetector"; i18n .use(i18nextHttpBackend) .use(initReactI18next) .use(LanguageDetector) .init({ lng: Cookies.get("locale") || "es", fallbackLng: "en", debug: false, supportedLngs: ["en", "es"], interpolation: { escapeValue: false, }, // 新增backend配置指定请求路径 backend: { // 开发环境填微应用本地启动地址,生产环境填微应用部署的域名路径 loadPath: `${process.env.REACT_APP_MICRO_APP_BASE_URL}/locales/{{lng}}/{{ns}}.json` } }); export default i18n;
在项目.env文件中配置对应环境的微应用基础地址即可,例如开发环境可配置为REACT_APP_MICRO_APP_BASE_URL=http://localhost:3000。
2. 调整webpack配置输出locales静态资源
安装copy-webpack-plugin将项目中存放的locales文件夹(通常放在public目录下)拷贝到最终打包输出目录,确保翻译文件可以被正常访问:
首先安装依赖:npm install copy-webpack-plugin --save-dev
修改webpack.config.js配置:
const { merge } = require("webpack-merge"); const singleSpaDefaults = require("webpack-config-single-spa-react"); const Dotenv = require("dotenv-webpack"); const CopyWebpackPlugin = require("copy-webpack-plugin"); const path = require("path"); module.exports = (webpackConfigEnv, argv) => { console.log(webpackConfigEnv); const defaultConfig = singleSpaDefaults({ orgName: "WHATEVR", projectName: "WHATEVER", webpackConfigEnv, argv, }); return merge(defaultConfig, { plugins: [ new Dotenv(), // 新增拷贝规则,将locales文件输出到打包目录 new CopyWebpackPlugin({ patterns: [ { from: path.resolve(__dirname, "public", "locales"), to: "locales" } ] }) ], devServer: { headers: { "Access-Control-Allow-Origin": "*", "Access-Control-Allow-Methods": "GET, POST, PUT, DELETE, PATCH, OPTIONS", "Access-Control-Allow-Headers": "X-Requested-With, content-type, Authorization", }, // 配置静态资源目录,确保本地开发时locales可访问 static: { directory: path.join(__dirname, 'public'), publicPath: '/', } }, }); };
内容的提问来源于stack exchange,提问作者Myvin Barboza
相关产品推荐
相关产品推荐

