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
-
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
-
Routing change
Under the unified architecture, the master application controls the overall routing in the same form as the SPA application.
-
Refresh page
Same as first loading logic