如何为react-i18next翻译文件添加哈希以解决浏览器缓存问题?
解决react-i18next翻译文件浏览器缓存问题的方案
方案一:通过react-app-rewired修改Webpack配置
react-scripts封装了Webpack配置,可借助react-app-rewired自定义配置,给翻译文件添加哈希:
- 安装依赖
npm install react-app-rewired customize-cra --save-dev
- 根目录创建
config-overrides.js文件,写入以下配置:
const { override, addWebpackModuleRule } = require('customize-cra'); const path = require('path'); const { WebpackManifestPlugin } = require('webpack-manifest-plugin'); module.exports = override( // 匹配public/locales下的json文件,输出时添加哈希 addWebpackModuleRule({ test: /locales\/.*\.json$/, include: path.resolve(__dirname, 'public'), type: 'asset/resource', generator: { filename: 'locales/[name].[contenthash:8].[ext]' } }), // 生成资源清单,方便获取带哈希的文件名 config => { config.plugins.push( new WebpackManifestPlugin({ fileName: 'asset-manifest.json', publicPath: '/', generate: (seed, files) => { return files.reduce((manifest, file) => { manifest[file.name] = file.path; return manifest; }, seed); } }) ); // 移除默认CopyPlugin对locales目录的复制,避免重复输出 config.plugins = config.plugins.filter(plugin => { return !(plugin.constructor.name === 'CopyPlugin' && plugin.options.patterns.some(p => p.from.includes('locales'))); }); return config; } );
- 修改
package.json中的脚本命令:
"scripts": { "start": "react-app-rewired start", "build": "react-app-rewired build", "test": "react-app-rewired test", "eject": "react-scripts eject" }
- 调整i18n配置,从资源清单中读取带哈希的文件路径:
import i18n from 'i18next'; import { initReactI18next } from 'react-i18next'; import manifest from '../build/asset-manifest.json'; // 动态获取带哈希的翻译文件路径 const getTranslationPath = (lang) => { const key = `locales/${lang}/translation.json`; // 生产环境用清单中的路径,开发环境降级到原路径 return process.env.NODE_ENV === 'production' ? manifest[key] : `/locales/${lang}/translation.json`; }; i18n .use(initReactI18next) .init({ lng: 'en', fallbackLng: 'en', interpolation: { escapeValue: false }, backend: { loadPath: (lng) => getTranslationPath(lng) } }); export default i18n;
方案二:添加版本查询参数(无需修改Webpack)
给翻译文件的请求URL添加版本号作为查询参数,强制浏览器获取最新文件:
- 在i18n配置中引入版本参数:
import i18n from 'i18next'; import { initReactI18next } from 'react-i18next'; // 从环境变量获取版本,默认值可自定义 const APP_VERSION = process.env.REACT_APP_VERSION || 'v1'; i18n .use(initReactI18next) .init({ lng: 'en', fallbackLng: 'en', interpolation: { escapeValue: false }, backend: { loadPath: `/locales/{{lng}}/translation.json?v=${APP_VERSION}` } }); export default i18n;
- 构建时动态设置版本号(比如用Git提交哈希),修改
package.json的build脚本:
"scripts": { "build": "REACT_APP_VERSION=$(git rev-parse --short HEAD) react-scripts build" }
每次更新翻译后,重新构建时版本参数会变化,浏览器会自动请求新文件。
方案三:将翻译文件移至src目录
把public/locales迁移到src/locales,Webpack会自动处理这些文件并添加哈希:
- 调整i18n配置,直接导入翻译文件:
import i18n from 'i18next'; import { initReactI18next } from 'react-i18next'; import enTranslation from './locales/en/translation.json'; import frTranslation from './locales/fr/translation.json'; i18n .use(initReactI18next) .init({ resources: { en: { translation: enTranslation }, fr: { translation: frTranslation } }, lng: 'en', fallbackLng: 'en', interpolation: { escapeValue: false } }); export default i18n;
这种方式无需额外配置,翻译文件会被打包进项目资源,自动带上哈希后缀,彻底解决缓存问题。
内容的提问来源于stack exchange,提问作者Saelhenen
相关产品推荐
相关产品推荐

