MFE aggregation layer - build aggregation

Posted by shan111 on Tue, 28 Dec 2021 18:45:37 +0100

Build aggregation

Build aggregation usually uses software engineering to re aggregate the split sub applications into a micro front-end application in the build and compilation stage.

monorepo

├── packages
|   ├── pkg1
|   |   ├── package.json
|   ├── pkg2
|   |   ├── package.json
├── package.json

​ Strictly speaking, monorepo is only a management method for large front-end projects from the perspective of engineering management. It provides unified workflow management and Code Sharing between projects, and can be combined with auxiliary tools such as yarn workspaces to manage overall dependencies.

​ The project structure introduces sub applications from the main application, packages them, and publishes them as a whole. This is not a scheme of the micro front end.

npm package

├── src
├── package.json
|   |		|		|		├── app1:version
|   |		|		|		| 	├── src
|   |		|		|		| 	├── package.json
|   |		|		|		| 	├── webpack.config

​ In this way, the sub application is published as an independent npm package, which is jointly used as the dependency of the main application. Although the main application can use lazyLoad and other methods to split bundle s, the problem with this method is that if any sub application changes (the npm package version needs to be updated and the sub application needs to be republished), the whole application needs to be recompiled and released. This method only meets the requirements of independent development and cannot meet the requirements of independent operation and independent deployment.

module federation

​ Before webpack5 MF came out, some companies aggregated sub applications during the construction process by developing a set of their own construction tool chain. This method can extract common dependencies, realize style reuse and chunk splitting and lazy loading of sub applications, but the limitation is that the same framework must be used.

​ For the ToC business, this method can not only optimize the performance and loading speed, but also take into account the independent development requirements of the micro front end. However, after the rise of MF, we can rethink and build the architecture ecology in the way of MF.

Let's look at the MF definition first

Module federation allows a JavaScript application to dynamically load code from another application

MF allows JS applications to dynamically load code from other applications

What does MF provide

After MF (modulefederation plugin) is used in the webpack configuration file, the packaged sub applications will become the following three module forms:

  • host

    Analogy: socket

  • remote

    Analogy: plug

  • Bidirectional-hosts

    Analogy: two-way socket (both socket and plug)

An application can be a socket, a plug, or a two-way socket.

How to configure MF

Let's start with a socket

//webpack.config
module.exports = {
  ...
  plugins: [
    new ModuleFederationPlugin({
      name: "app_one_remote",
      remotes: {
        app_two: "app_two_remote",
        app_three: "app_three_remote@https://localhost:8080/remoteEntry.js"
      },
      shared: ["react", "react-dom","react-router-dom"]
    })
  ]
}
//App.js
const PageThree = React.lazy(() => import("app_three_remote/PageThree"));
const Main = () => {
    return (
        <div>
            <h1>Page main</h1>
            <React.Suspense fallback="Loading PageThree...">
                <PageThree />
            </React.Suspense>
        </div>
    );
}
ReactDom.render(<Main />, document.getElementById("root")
);
//index.html
<head>
  <script src="http://localhost:3002/app_one_remote.js"></script>
</head>
<body>
  <div id="root"></div>
</body>

Another plug

new ModuleFederationPlugin({
  name: "app_three_remote",
  library: { type: "var", name: "app_three_remote" },
  filename: "remoteEntry.js",
  exposes: {
    "./PageThree": "./src/PageThree"
  },
  shared: ["react", "react-dom"]
}),

In this case, in index When html is loaded, app_one_remote.js found dependent apps_ three_ remote. JS will dynamically load it.

The principle of MF is not expanded here. You can refer to it Analysis of Module Federation principle

What can MF do

​ With sockets, plugs and two-way sockets, we can use these three module forms to transform our application into a module dependency tree, which is a dynamically loaded dependency tree compiled independently. The first loaded application will automatically become a root socket.

  • Main application

    Plan the level-1 route as the base, and configure all dependencies and sub applications referenced by the level-2 route mapping.

  • Sub application

    Export entry file, deployment address, module, etc.

  • Platformization

    Develop the dynamic registration platform of the sub application, and dynamically generate the entry file, deployment address, routing mapping, etc. of the sub application to the webpack of the main application JS and router JS to recompile, deploy and update the main application, and improve the non development characteristics of the platform in combination with CI/CD.

MF landing micro front end

​ When MF technology is used to land on the micro front end, it is more suitable for the unified architecture system. For example, in the case of React or Angular, MF is very convenient for routing processing and public dependency processing. Suitable for the newly built micro front-end platform, MF still prefers to build aggregation scenarios.

​ If the architecture system for each sub application is not unified, especially when there are old projects on the platform level Web in the ToB scenario, MF is not a good choice because the main application and sub application cannot load sub applications for the primary route.

Operation mode

  1. First load

    Request remote route = > return main application resource = > main application loading completed = > main application takes over route = > dynamically load sub applications according to route

  2. Routing change

    Under the unified architecture, the master application controls the overall routing in the same form as the SPA application.

  3. Refresh page

    Same as first loading logic