在现代前端开发中,Module Federation(MF)是一种越来越流行的架构模式。它允许我们将前端应用拆分成更小的、独立可部署的组件。这种方式带来了一些明显的优势,如团队独立性、技术栈灵活性等,但也引入了一系列新的挑战。在本文中,我们将讨论其中一个常见的问题:如何在MF项目中优化i18n(国际化)配置。
问题背景
我们开发的项目包含多个MF组件,同时也需要实现多语言支持。在这种情况下,有两个关键点需要考虑:
-
共享组件需要使用国际化配置,而这些组件可能会被多个不同的团队使用。
-
我们希望避免因共享组件的引入,导致整个项目的国际化文案全部被打包,从而增大打包体积。
为了实现组件的国际化功能,最简单的方法是让这些组件使用主应用的i18n实例。然而,这样做的一个显著缺陷是会导致整个项目的所有文案一同被打包,从而大幅增加打包体积。
为了解决这个问题,我们可以使用i18n的createInstance
方法,创建新的实例,最终实现项目与MF组件的i18n拆分。
解决方案
我们使用i18next
库示例说明如何实现这一目标,包括创建新的i18n实例并逐步分离项目和MF组件的文案。
步骤一:安装i18next依赖
首先确保在项目中安装了i18next
及其React绑定。
npm install i18next react-i18next
步骤二:配置主应用的i18n
在主应用中配置i18n实例,加载主应用特有的文案。
import i18n from 'i18next';
import { initReactI18next } from 'react-i18next';
import enLocaleResource from '@/public/locales/en.json';
import zhLocaleResource from '@/public/locales/zh.json';
import { getLangKey } from './localstorage';
export const i18nApp = i18n.createInstance();
i18nApp
.use(initReactI18next)
// init i18next
// for all options read: https://www.i18next.com/overview/configuration-options
.init({
lng: getLangKey(),
fallbackLng: 'en',
keySeparator: '.',
preload: ['en', 'zh'],
interpolation: {
escapeValue: false, // not needed for react as it escapes by default
},
react: {
useSuspense: false,
transSupportBasicHtmlNodes: true,
transKeepBasicHtmlNodesFor: ['b', 'br'],
},
resources: {
en: {
translation: enLocaleResource,
},
zh: {
translation: zhLocaleResource,
},
},
});
export default i18n;
步骤三:为MF组件创建独立的i18n实例
在MF组件中创建一个新的i18n实例,只加载组件特有的文案。
import { getLangKey } from '@/utils/localstorage';
import i18n from 'i18next';
import { initReactI18next } from 'react-i18next';
import enLocaleResource from '@/expose/locales/en.json';
import zhLocaleResource from '@/expose/locales/zh.json';
export const i18nExpose = i18n.createInstance();
export const t = i18nExpose.t;
i18nExpose
// pass the i18n instance to react-i18next.
.use(initReactI18next)
// init i18next
// for all options read: https://www.i18next.com/overview/configuration-options
.init({
lng: getLangKey(),
fallbackLng: 'en',
keySeparator: '.',
preload: ['en', 'zh'],
interpolation: {
escapeValue: false, // not needed for react as it escapes by default
},
react: {
useSuspense: false,
transSupportBasicHtmlNodes: true,
transKeepBasicHtmlNodesFor: ['b', 'br'],
},
resources: {
en: {
translation: enLocaleResource,
},
zh: {
translation: zhLocaleResource,
},
}
});
export default i18n;
步骤四:在组件中使用独立的i18n实例
定义组件需要使用的hook
import { i18nExpose } from '../utils/i18n';
const useExposeTranslation = () => {
return i18nExpose;
};
export default useExposeTranslation;
在需要使用国际化的MF组件中调用useExposeTranslation。
// MF组件 - MyComponent/index.js
import React from 'react';
import useExposeTranslation from './hooks/useExposeTranslation'
const MyComponent = () => {
const { t } = useExposeTranslation();
return (
<div>
{/* 你的组件内容 */}
</div>
);
};
export default MyComponent;
总结
通过使用i18next
库的createInstance
方法,我们可以为每个MF组件创建独立的i18n实例,从而实现项目与MF组件的i18n拆分。这样的方式不仅可以优化打包体积,还可以提高文案管理的灵活性,使得大型项目的国际化维护更加高效。希望本文对你有所帮助,欢迎交流更多的技术实践经验。