通过模块联合和 Redux 来反应微前端

问题描述 投票:0回答:1

我目前正在使用 React、webpack 和模块联合开发一个微前端应用程序。它由一个容器应用程序和两个“子”/遥控器组成。容器应用程序由一个应用程序栏、空的侧抽屉和主 div 组成,它导入的遥控器为实际页面内容公开一个独立的 React 应用程序,以及一个应为侧抽屉呈现导航项的单个组件,每个组件: MFE design

远程 MFE 每个都有自己的 Redux 存储,这对于页面内容部分来说效果很好,因为这包括带有 Redux 存储提供程序的 App.tsx。到目前为止,导航组件也工作得很好,因为它所做的只是将路线推送到浏览器历史记录中。

现在我遇到了一个问题:一个遥控器的公开导航组件还必须从其 Redux 存储和调度操作中选择数据。到目前为止这不起作用,因为它是一个公开的组件,并且当它在容器应用程序中渲染时,子 Redux 存储没有 Redux 存储提供程序。我该如何解决这个问题?我读过几次,在微前端之间共享 redux 状态是一种不好的做法,所以到目前为止我一直在努力避免这种情况。导航需要访问的数据基本上只是一个布尔值,这表明应用程序处于提升的“服务模式”,使远程 MFE 呈现更多项目(例如通常隐藏的“删除全部”按钮)。所以也许这也可以通过本地存储或类似的方式共享,这里有哪些最佳实践?

这是我的 webpack 配置和一些相关代码,以便更好地理解:

// container app webpack config (development)
...
plugins: [
    new ModuleFederationPlugin({
      name: "container_app",
      remotes: {
        config_app: "config_app@http://localhost:3001/remoteEntry.js",
        commissioning_app: "commissioning_app@http://localhost:3002/remoteEntry.js",
      },
      shared: {
        ...
      },
    }),
  ],
...
// config_app webpack config (development)
...
 plugins: [
    new ModuleFederationPlugin({
      name: "config_app",
      filename: "remoteEntry.js",
      exposes: {
        "./ConfigApp": "./src/bootstrap",
        "./ConfigAppNavigation": "./src/components/UI/Misc/ConfigAppNavigation",
      },
      shared: {
        ...
      },
    }),
  ],

...
// MiniDrawer.tsx in container_app, which uses ConfigAppNavigation to render the navigation items 
// (depending on current route, otherwise navigation items are rendered from other MFE child)
...
const ConfigAppNavigation = lazy(() => import("config_app/ConfigAppNavigation"));
const MiniDrawer: React.FC = () => {
  ...
  <Switch>
    ...
    <Route path="/">
      <Suspense fallback={<span>loading ...</span>}>
        <ConfigAppNavigation onNavigate={onDrawerClose} />
      </Suspense>
    </Route>
  </Switch>
  ...
}
...

如上所述,在切换到 MFE 设计之前,现在的组件 ConfigAppNavigation 从 config_app 的 Redux 存储中选择/更改了提到的布尔值,现在使用此设置不起作用。

reactjs webpack redux webpack-module-federation
1个回答
0
投票

第 1 步:在 Shell/主机应用程序中设置 Redux 安装 Redux 包:在您的 shell 或主机应用程序中,安装必要的 Redux 库。

npm install @reduxjs/toolkit react-redux

创建 Redux 存储:在主机应用程序中,使用 Redux 存储配置创建 store.js 文件。

// store.js
import { configureStore } from '@reduxjs/toolkit';
import rootReducer from './rootReducer';

const store = configureStore({
  reducer: rootReducer,
});

export default store;

设置 RootReducer:创建一个 rootReducer.js 文件,在其中组合不同的切片。在这里您可以为应用程序的不同部分添加多个减速器。

// rootReducer.js
import { combineReducers } from 'redux';
import someSliceReducer from './someSlice';

const rootReducer = combineReducers({
  someSlice: someSliceReducer,
  // add other reducers here as needed
});

export default rootReducer;

提供 Store:使用 Redux Provider 包装您的主机应用程序,以使本地和导入的组件都可以访问该商店。

// index.js
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import store from './store';
import App from './App';

ReactDOM.render(
  <Provider store={store}>
    <App />
  </Provider>,
  document.getElementById('root')
);

第 2 步:创建并公开 Redux 切片 每个切片代表您所在州的一部分。为您想要跨微前端共享的特定状态定义一个切片。

定义切片:为共享状态创建新切片,例如会议数据。

// someSlice.js
import { createSlice } from '@reduxjs/toolkit';

const someSlice = createSlice({
  name: 'someSlice',
  initialState: {
    sharedData: null,
  },
  reducers: {
    setSharedData: (state, action) => {
      state.sharedData = action.payload;
    },
  },
});

export const { setSharedData } = someSlice.actions;
export default someSlice.reducer;

导出操作:您需要 setSharedData 来更新主机和微前端组件中的状态。

第 3 步:配置微前端以使用主机存储 现在,我们希望微前端能够访问和使用主机的商店。以下是一些方法:

将商店公开为模块:在主机应用程序的index.js中,公开商店,以便其他应用程序可以导入它。

// index.js
import store from './store';
window.store = store; // Expose globally

在微前端访问Store:在每个微前端中,通过window.store访问全局store并将其传递给Provider。

import React from 'react';
import { Provider } from 'react-redux';
import YourComponent from './YourComponent';

function MicroFrontendApp() {
  return (
    <Provider store={window.store}>
      <YourComponent />
    </Provider>
  );
}

export default MicroFrontendApp;

第四步:在组件中使用共享状态 现在您的商店可以访问,您可以在本地和远程组件中与其交互。

访问组件中的状态:使用useSelector访问状态并使用useDispatch修改它。

import React from 'react';
import { useSelector, useDispatch } from 'react-redux';
import { setSharedData } from './someSlice';

const SomeComponent = () => {
  const sharedData = useSelector((state) => state.someSlice.sharedData);
  const dispatch = useDispatch();

  const handleUpdate = () => {
    dispatch(setSharedData('New Data'));
  };

  return (
    <div>
      <h1>Shared Data: {sharedData}</h1>
      <button onClick={handleUpdate}>Update Shared Data</button>
    </div>
  );
};

export default SomeComponent;

第五步:测试和调试 确保状态同步:检查主机应用程序中所做的更改是否反映在微前端中,反之亦然。 调试:Redux DevTools 可以帮助可视化状态并跟踪操作。确保浏览器安装了 Redux DevTools 扩展。

© www.soinside.com 2019 - 2024. All rights reserved.