module federation 是一种在多个 webpack 项目中共享代码的方式,可以看看下面这个图。
它和 umd 的区别是借用的另一个项目的部分代码,而不是固定的代码。
截屏2021-04-03 下午10.33.58.png

例子

源码:mfe-webpack-demo
项目一配置

  1. // 项目1
  2. // webpack.config.js
  3. const HtmlWebpackPlugin = require("html-webpack-plugin");
  4. const ModuleFederationPlugin =
  5. require("webpack/lib/container/ModuleFederationPlugin");
  6. module.exports = {
  7. // other webpack configs...
  8. plugins: [
  9. new ModuleFederationPlugin({
  10. name: "app_one_remote",
  11. remotes: {
  12. app_two: "app_two_remote"
  13. },
  14. exposes: {
  15. ‘./AppContainer':'./src/App'
  16. },
  17. shared: ["react", "react-dom","react-router-dom"]
  18. }),
  19. new HtmlWebpackPlugin({
  20. template: "./public/index.html",
  21. chunks: ["main"]
  22. })
  23. ]
  24. }

项目一入口

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <script src="http://localhost:3002/remoteEntry.js"></script>
  5. </head>
  6. <body>
  7. <div id="root"></div>
  8. </body>
  9. </html>

项目一消费

import React from "react";

const Dialog = React.lazy(() => import("app_two/Dialog"));

const Page1 = () => {
    return (
        <div>
            <h1>Page 1</h1>
            <React.Suspense fallback="Loading Material UI Dialog...">
                <Dialog />
            </React.Suspense>
        </div>
    );
}

export default Page1;

项目二配置

module.exports = {
  plugins: [
    new ModuleFederationPlugin({
      name: "app_two",
      library: { type: "var", name: "app_two" },
      filename: "remoteEntry.js",
      exposes: {
        Dialog: "./src/Dialog"
      },
      remotes: {
        app_one: "app_one",
      },
      shared: ["react", "react-dom","react-router-dom"]
    }),
    new HtmlWebpackPlugin({
      template: "./public/index.html",
      chunks: ["main"]
    })
  ]
}

项目二入口

<!DOCTYPE html>
<html lang="en">
<head>
  <script src="http://localhost:3001/remoteEntry.js"></script>
</head>
  <body>
    <div id="root"></div>
  </body>
</html>

项目二消费

import React from "react";
import Routes from './Routes'
const AppContainer = React.lazy(() => import("app_one/AppContainer"));

const App = () => {
    return (
        <div>
            <React.Suspense fallback="Loading App Container from Host">
                <AppContainer routes={Routes}/>
            </React.Suspense>
        </div>
    );
}

export default App;

参考