webpack 5 联邦模块介绍

本文主要介绍webpack 5 的新特性之一 "module federation"(联邦模块),涉及联邦模块特性、使用方法、适用范围。css


特性

webpack 5引入联邦模式是为了更好的共享代码。 在此以前,咱们共享代码通常用npm发包来解决。 npm发包须要经历构建,发布,引用三阶段,而联邦模块能够直接引用其余应用代码,实现热插拔效果。对比npm的方式更加简洁、快速、方便。html

使用方法

  1. 引入远程js
  2. webpack配置
  3. 模块使用

引入远程JS

假设咱们有app1,app2两个应用,端口分别为3001,3002。 app1应用要想引用app2里面的js,直接用script标签便可。前端

例如app1应用里面index.html引入app2应用remoteEntry.jsreact

<head>
    <script src="http://localhost:3002/remoteEntry.js"></script>
  </head>复制代码


webpack配置

app1的webpack配置:webpack

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"],
    }),
  ],
};
复制代码

对于app2的webpack配置以下git

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

能够看到app1和app2的配置基本相同,除了app2 多了filename和exposes之外。github

参数解释web

  1. name 应用名,全局惟一,不可冲突。
  2. library。UMD标准导出,和name保持一致便可。
  3. remotes 声明须要引用的远程应用。如上图app1配置了须要的远程应用app2.
  4. filename 远程应用时被其余应用引入的js文件名称。对应上面的remoteEntry.js
  5. exposes 远程应用暴露出的模块名。
  6. shared 依赖的包。
    1. 若是配置了这个属性。webpack在加载的时候会先判断本地应用是否存在对应的包,若是不存在,则加载远程应用的依赖包。
    2. 以app2来讲,由于它是一个远程应用,配置了["react", "react-dom"] ,而它被app1所消费,因此webpack会先查找app1是否存在这两个包,若是不存在就使用app2自带包。 app1里面一样申明了这两个参数,由于app1是本地应用,因此会直接用app1的依赖。

模块使用

对于app1/App.js代码使用app2的组件,代码以下:npm

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;复制代码

具体这一行sass

const RemoteButton = React.lazy(() => import("app2/Button")); 复制代码

使用方式为:import('远程应用名/暴露的模块名'),对应webpack配置里面的name和expose。使用方式和引入一个普通异步组件无差异。


适用范围

因为share这个属性的存在,因此本地应用和远程应用的技术栈和版本必须兼容,统一用同一套。好比js用react,css用sass等。

联邦模块和微前端的关系:由于expose这个属性便可以暴露单个组件,也能够把整个应用暴露出去。同时因为share属性存在,技术栈必须一致。因此加上路由,能够用来实现single-spa这种模式的微前端。

使用场景:新建专门的组件应用服务来管理全部组件和应用,其余业务层只须要根据本身业务所需载入对应的组件和功能模块便可。模块管理统一管理,代码质量高,搭建速度快。特别适用矩阵app,或者可视化页面搭建等场景。


例子的github地址

相关文章
相关标签/搜索