如何为使用rollup.js构建的NPM包添加i18n多语言翻译?
解决Rollup构建React NPM包中react-i18next的实例注入错误
针对你遇到的react-i18next:: You will need to pass in an i18next instance by using initReactI18next错误,主要原因是Rollup的打包机制导致i18n实例未被正确注入React上下文,或模块处理方式不符合react-i18next的要求,以下是具体修复方案:
一、调整现有react-i18next配置与Rollup打包设置
1. 确保i18n实例被组件正确引用
直接在入口文件导入./i18n可能被Rollup的tree-shaking优化忽略,或者实例未全局挂载到React上下文。可以通过两种方式修复:
- 显式在组件中导入实例:
// 组件文件中 import { useTranslation } from 'react-i18next'; import { i18n } from '../i18n'; export const MyLibraryComponent = () => { const { t } = useTranslation(); return <div>{t('greeting')}</div>; }; - 用
I18nextProvider包裹库根组件:
如果你的库对外暴露根组件,用Provider包裹确保实例上下文传递:import { I18nextProvider } from 'react-i18next'; import { i18n } from './i18n'; export const LibraryRoot = ({ children }) => { return <I18nextProvider i18n={i18n}>{children}</I18nextProvider>; };
2. 配置Rollup插件处理依赖模块
Rollup默认不处理CommonJS模块和JSON文件,需要添加对应插件确保i18next相关依赖被正确打包:
// rollup.config.js import resolve from '@rollup/plugin-node-resolve'; import commonjs from '@rollup/plugin-commonjs'; import json from '@rollup/plugin-json'; import typescript from '@rollup/plugin-typescript'; import peerDepsExternal from 'rollup-plugin-peer-deps-external'; export default { input: 'src/index.tsx', output: [ { file: 'dist/index.js', format: 'cjs', sourcemap: true }, { file: 'dist/index.esm.js', format: 'esm', sourcemap: true } ], plugins: [ peerDepsExternal(), // 排除peer依赖,避免重复打包 resolve(), // 解析node_modules中的模块 commonjs(), // 处理i18next等CommonJS格式的依赖 json(), // 解析语言包JSON文件 typescript({ tsconfig: './tsconfig.json' }) ], external: ['react', 'react-dom', 'react-i18next', 'i18next'] // 将这些设为外部依赖,由使用方提供 };
同时在package.json中添加peer依赖声明,确保使用方环境有对应版本的依赖:
"peerDependencies": { "react": "^17.0.0 || ^18.0.0", "react-dom": "^17.0.0 || ^18.0.0", "react-i18next": "^12.0.0 || ^13.0.0", "i18next": "^22.0.0 || ^23.0.0" }
3. 确保i18n初始化时机正确
如果组件渲染时i18n还未初始化完成,也会触发该错误,可以改为异步初始化:
// i18n.ts export const initI18n = async () => { await i18n .use(LanguageDetector) .use(initReactI18next) .init({ debug: false, fallbackLng: 'en', nsSeparator: ':', resources: { en: en }, keySeparator: false, returnNull: false }); };
然后在入口文件中调用初始化:
// index.tsx import { initI18n } from './i18n'; // 先初始化i18n再导出组件 initI18n(); export { MyLibraryComponent } from './components/MyLibraryComponent';
二、适合库开发的替代i18n库
如果调整后仍有问题,可以考虑更适合NPM库的轻量方案:
- react-intl:遵循国际化标准,支持复数、日期/时间格式化,组件级使用灵活,无需全局实例。
- lingui:轻量体积,TypeScript友好,通过babel插件优化打包,适合库和应用场景。
- react-i18nify:API极简,配置简单,适合小型库快速实现多语言。
内容的提问来源于stack exchange,提问作者sw-tracker
相关产品推荐
相关产品推荐

