This article mainly introduces webPack 5 one of the new features “Module federation”(federated module), involving federated module features, use methods, application scope.


features

Webpack 5 introduced federated mode for better code sharing. Prior to this, we used NPM to deal with shared code. NPM packages need to go through three stages of build, publish and reference, while federated modules can directly reference other application code to achieve hot plug effect. Compared with NPM, NPM is simpler, faster and more convenient.

Method of use

  1. Introducing remote JS
  2. Webpack configuration
  3. Module USES

Introducing remote JS

So let’s say we have app1, app2, port 3001, port 3002. App1 uses the script tag to reference js from App2.

For example, app1 uses index.html and app2 uses remoteentry.js

 <head>
    <script src="http://localhost:3002/remoteEntry.js"></script>
  </head>Copy the code


Webpack configuration

Webpack configuration for App1:

const ModuleFederationPlugin = require("webpack/lib/container/ModuleFederationPlugin");
   
module.exports = {
  //....
  plugins: [
    new ModuleFederationPlugin({
      name: "app1",
      library: { type: "var", name: "app1" },
      remotes: {
        app2: "app2",
      },
      shared: ["react"."react-dom"],}),]};Copy the code

The webpack configuration for App2 is as follows

  plugins: [
    new ModuleFederationPlugin({
      name: "app2",
      library: { type: "var", name: "app2" },
      filename: "remoteEntry.js",
      exposes: {
        "./Button": "./src/Button",
      },
      shared: ["react"."react-dom"],})],Copy the code

You can see that app1 and App2 have basically the same configuration, except that App2 has a filename and an object reception.

Parameter interpretation

  1. nameThe application name is globally unique and non-conflicting.
  2. library. UMD standard export, consistent with name.
  3. remotesDeclare the remote application that you want to reference. In the preceding figure, app1 is configured with the remote application App2.
  4. filenameName of the JS file imported by other applications during remote application. Corresponding to the aboveremoteEntry.js
  5. exposesThe name of the module exposed by the remote application.
  6. sharedDependent packages.
    1. If this property is configured. During loading, WebPack checks whether the local application has a corresponding package. If not, it loads the dependent package of the remote application.
    2. In the case of App2, because it is a remote application, it is configured["react", "react-dom"], and it is consumed by App1, so WebPack first looks for the existence of these two packages in App1, and if not, uses the packages in App2. App1 also declares these two parameters. Because app1 is a native application, it will use app1’s dependencies directly.

Module USES

For components that use app2 in app1/ app.js code, the code is as follows:

import React from "react";

const RemoteButton = React.lazy(() => import("app2/Button"));

const App = () => (
  <div>
    <h1>Basic Host-Remote</h1>
    <h2>App 1</h2>
    <React.Suspense fallback="Loading Button">
      <RemoteButton />
    </React.Suspense>
  </div>
);

export default App;Copy the code

This particular row

const RemoteButton = React.lazy(() => import("app2/Button")); Copy the code

Use: import(‘ remote application name/exposed module name ‘) corresponding to name and expose in the Webpack configuration. It is used in the same way as importing a normal asynchronous component.


Scope of application

Because of the share attribute, the technology stacks and versions of local and remote applications must be compatible. For example, JS uses React, CSS uses sass, etc.

Federated modules and microfronts: Because of the expose property, it exposes both individual components and entire applications. And because the share attribute exists, the technology stack must be consistent. So with the addition of routing, you can implement a micro front end to the single-SPA pattern.

Usage scenario: Create a dedicated component application service to manage all components and applications. Other service layers only need to load corresponding components and functional modules based on their own service requirements. Unified module management, high code quality, fast construction. Especially suitable for matrix APP, or visual page building and other scenes.



Github address for the example