1 year ago

#352623

test-img

Praveen Khatti

How to use common dependencies between multiple modules in React micro frontend

Hey I am using react microfrontend in my react project with webpack module federation. After changing folder structure as per microfrontend structure facing some difficulties to handle common dependencies of modules.

Getting Following Error:

    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'

Here I am sharing my code structure

  1. webpack
  2. package.json
  3. folder structure

Webpack:

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)
    })
  ]
};

In our project have common utils and components that is being used in different micro frontend modules how to handle that dependencies.

package.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"
  }
}

My folder structure:

enter image description here

reactjs

react-dom

webpack-5

micro-frontend

webpack-module-federation

0 Answers

Your Answer

Accepted video resources