如何在 React 微前端中使用多个模块之间的公共依赖关系

Pra*_*tti 5 reactjs react-dom micro-frontend webpack-5 webpack-module-federation

嘿,我在我的 React 项目中使用 React 微前端和 webpack 模块联合。根据微前端结构更改文件夹结构后,处理模块的常见依赖关系面临一些困难。

出现以下错误:

    ERROR in resolving fallback for shared module react
    Module not found: Error: Can't resolve 'react' in '/Users/admin/Desktop/guru/project/microfrontend/modules/metronic/layout/components/subheader/components'
    ERROR in resolving fallback for shared module react
Module not found: Error: Can't resolve 'react-router-dom' in '/Users/admin/Desktop/guru/project/microfrontend/modules/metronic/layout/components/subheader/components'
Run Code Online (Sandbox Code Playgroud)

这里我分享一下我的代码结构

  1. 网络包
  2. 包.json
  3. 文件夹结构

网页包:

const path = require('path');
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const ModuleFederationPlugin = require("webpack/lib/container/ModuleFederationPlugin");
require('dotenv').config({ path: '../.env' });

module.exports = {
  // the output bundle won't be optimized for production but suitable for development
  mode: 'development',
  // the app entry point is /src/index.js
  entry: path.resolve(__dirname, 'src', 'index.js'),
  output: {
    // the output of the webpack build will be in /dist directory
    path: path.resolve(__dirname, 'dist'),
    // the filename of the JS bundle will be bundle.js
    filename: 'bundle.js',
    publicPath: '/'
  },
  devServer: {
    historyApiFallback: true,
  },
  resolve: {
    extensions: ['', '.js', '.jsx'],
  },
  module: {
    rules: [
      {
        // for any file with a suffix of js or jsx
        test: /\.jsx?$/,
        // ignore transpiling JavaScript from node_modules as it should be that state
        exclude: /node_modules/,
        // use the babel-loader for transpiling JavaScript to a suitable format
        loader: 'babel-loader',
        options: {
          // attach the presets to the loader (most projects use .babelrc file instead)
          presets: ["@babel/preset-env", "@babel/preset-react"]
        }
      },
      {
        // test: /\.s[ac]ss$/i,
        test: /\.(sa|sc|c)ss$/,
        use: [
          // Creates `style` nodes from JS strings
          "style-loader",
          // Translates CSS into CommonJS
          "css-loader",
          // Compiles Sass to CSS
          "sass-loader",
        ],
      },
      {
        test: /\.(woff(2)?|ttf|eot|svg|png)(\?v=\d+\.\d+\.\d+)?$/,
        use: [
          {
            loader: 'file-loader',
            options: {
              name: '[name].[ext]',
              outputPath: 'fonts/'
            }
          }
        ]
      }
    ]
  },
  // add a custom index.html as the template
  plugins: [
    new ModuleFederationPlugin({
        name: "app_container",
        remotes: {
            banners: "banners@http://localhost:3002/remoteEntry.js",
            newDashboard: "newDashboard@http://localhost:3008/remoteEntry.js",
            baggageService: "baggageService@http://localhost:3016/remoteEntry.js",

        },
        // shared: [ "react", "react-dom"]
        shared: {
          "react-router-dom": { singleton: true, eager: true, requiredVersion: "^5.1.2" },
          "@manaflair/redux-batch":{ singleton: true, eager: true, requiredVersion: "1.0.0" },
          "@reduxjs/toolkit":{ singleton: true, eager: true, requiredVersion: "1.3.6" },
          "react-redux":{ singleton: true, eager: true, requiredVersion: "7.1.3" },
          "redux":{ singleton: true, eager: true, requiredVersion: "4.0.5" },
          "redux-logger":{ singleton: true, eager: true, requiredVersion: "^3.0.6" },
          "redux-persist":{ singleton: true, eager: true, requiredVersion: "6.0.0" },
          "redux-saga":{ singleton: true, eager: true, requiredVersion: "1.1.3" },
          "react": { singleton: true, eager: true, requiredVersion: "^17.0.2" },
          "@fortawesome/fontawesome-free": { singleton: true, eager: true, requiredVersion: "5.13.0" },
          "react-dom": { singleton: true, eager: true, requiredVersion: "^17.0.2" },
          "lodash": { singleton: true, eager: true, requiredVersion: "4.17.21" },
          "lodash.debounce": { singleton: true, eager: true, requiredVersion: "^4.0.8" },
        }
    }),
    new HtmlWebpackPlugin({
        template: "./public/index.html"
    }),
    new webpack.DefinePlugin({
      "process.env": JSON.stringify(process.env)
    })
  ]
};
Run Code Online (Sandbox Code Playgroud)

在我们的项目中,不同的微前端模块中使用了通用的实用程序和组件,如何处理这些依赖关系。

包.json:

{
  "name": "microfrontend",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "start": "webpack-dev-server --open",
    "build": "webpack --config webpack.prod.config.js --mode production"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "react": "^17.0.2",
    "react-dom": "^17.0.2"
  },
  "devDependencies": {
    "@amcharts/amcharts3-react": "^3.0.0",
    "@babel/core": "^7.17.5",
    "@babel/preset-env": "^7.16.11",
    "@babel/preset-react": "^7.16.7",
    "@date-io/date-fns": "^1.3.11",
    "@formatjs/intl-pluralrules": "1.3.5",
    "@fortawesome/fontawesome-free": "^5.13.0",
    "@manaflair/redux-batch": "1.0.0",
    "@material-ui/core": "^4.10.2",
    "@material-ui/icons": "4.9.1",
    "@material-ui/pickers": "^3.3.10",
    "@material-ui/styles": "4.9.14",
    "@reduxjs/toolkit": "1.3.6",
    "@tanem/svg-injector": "8.0.50",
    "@wojtekmaj/react-daterange-picker": "^3.3.0",
    "apexcharts": "3.24.0",
    "axios": "0.21.2",
    "axios-mock-adapter": "1.18.1",
    "babel-loader": "^8.2.3",
    "bootstrap": "4.5.0",
    "bootstrap-daterangepicker": "^3.1.0",
    "clipboard-copy": "3.1.0",
    "clsx": "1.1.0",
    "cp-cli": "2.0.0",
    "css-mediaquery": "0.1.2",
    "date-fns": "2.8.1",
    "downshift": "3.4.2",
    "fg-loadcss": "2.1.0",
    "file-loader": "^6.2.0",
    "formik": "2.1.4",
    "highcharts": "^9.0.0",
    "highcharts-react-official": "^3.0.0",
    "html-react-parser": "^0.13.0",
    "html-webpack-plugin": "^5.5.0",
    "html2canvas": "^1.3.2",
    "http-service": "file:../modules/http-service",
    "i": "^0.3.7",
    "json2mq": "0.2.0",
    "jss-rtl": "^0.3.0",
    "lodash": "4.17.21",
    "lodash.debounce": "^4.0.8",
    "material-picker-4.0": "npm:@material-ui/pickers@^4.0.0-alpha.12",
    "material-ui-popup-state": "1.4.1",
    "metronic": "file:../modules/metronic",
    "npm": "^6.14.6",
    "object-path": "0.11.8",
    "perfect-scrollbar": "1.5.0",
    "prop-types": "15.7.2",
    "quill-emoji": "^0.1.7",
    "react-beautiful-dnd": "^13.1.0",
    "react-bootstrap": "1.0.1",
    "react-bootstrap-daterangepicker": "^7.0.0",
    "react-bootstrap-table-next": "4.0.2",
    "react-bootstrap-table2-paginator": "2.1.2",
    "react-copy-to-clipboard": "^5.0.2",
    "react-data-table-component": "^6.9.3",
    "react-datepicker": "2.16.0",
    "react-draggable": "4.4.2",
    "react-highcharts": "^16.1.0",
    "react-hooks-helper": "^1.6.0",
    "react-html-parser": "^2.0.2",
    "react-image-crop": "^8.6.12",
    "react-inlinesvg": "1.2.0",
    "react-intl": "3.6.2",
    "react-is": "16.13.1",
    "react-pdf": "^5.7.0",
    "react-perfect-scrollbar": "1.5.8",
    "react-portal": "4.2.0",
    "react-qr-reader": "^2.2.1",
    "react-quill": "^1.3.5",
    "react-redux": "7.1.3",
    "react-router-dom": "5.1.2",
    "react-router-last-location": "^2.0.1",
    "react-rte": "^0.16.1",
    "react-scripts": "3.2.0",
    "react-select": "3.1.0",
    "react-star-ratings": "^2.3.0",
    "react-swipeable-views": "0.13.9",
    "react-syntax-highlighter": "12.2.1",
    "react-table-hoc-fixed-columns": "^2.3.4",
    "react-toastify": "^6.0.6",
    "react-window": "1.8.5",
    "reactstrap": "^8.5.1",
    "redux": "4.0.5",
    "redux-logger": "^3.0.6",
    "redux-persist": "6.0.0",
    "redux-saga": "1.1.3",
    "sass": "^1.49.9",
    "sass-loader": "^12.6.0",
    "socicon": "3.0.5",
    "styled-components": "^5.1.1",
    "sweetalert2": "^10.12.6",
    "sweetalert2-react-content": "^3.2.2",
    "common-gui-components": "file:../modules/common-gui-components",
    "common-store": "file:../modules/common-store",
    "common-utils": "file:../modules/common-utils",
    "uuid": "^8.3.2",
    "webpack": "^5.70.0",
    "webpack-cli": "^4.9.2",
    "webpack-dev-server": "^4.7.4",
    "yup": "0.29.0"
  }
}
Run Code Online (Sandbox Code Playgroud)

我的文件夹结构:

在此输入图像描述