webpack5模块联邦

简介: WHAT(Module Federation 是什么?)

WHAT(Module Federation 是什么?)

Module Federation [ˌfedəˈreɪʃn] 使 JavaScript 应用得以在客户端或服务器上动态运行另一个 bundle 的代码。

这其中的关键点是:动态,包含两个含义:

1、按需,可以把一个包拆开来加载其中一部分;

2、运行时,跑在浏览器而非 node 编译时;

另一个 bundle 的代码,之前应用之间做共享是在文件级或 npm 包级 export 成员,现在可以在应用级 export 成员属性。

Module Federation 里有两个主要概念 host 和 remote。每个项目可以是 host 也可以是 remote,也可以两个都是。

配置 remote

webpack.config.js

const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const ModuleFederationPlugin = require("webpack/lib/container/ModuleFederationPlugin");

module.exports = {
  mode: "development",
  entry: "./src/index.js",
  cache: {
    type: "filesystem",
    cacheDirectory: path.resolve(__dirname, "node_modules/.cache/webpack"),
  },
  output: {
    filename: "bundle.js",
    path: path.resolve(__dirname, "dist"),
    publicPath: "http://localhost:8000/",
  },
  devServer: {
    port: 8000,
  },
  optimization: {
    usedExports: true,
  },
  devtool: false,
  module: {
    rules: [
      {
        test: /\.js$/,
        use: [
          {
            loader: "babel-loader",
            options: {
              presets: ["@babel/preset-react"],
            },
          },
        ],
        exclude: /node_modules/,
      },
      {
        test: /\.png$/,
        type: "asset/resource",
      },
      {
        test: /\.css$/,
        use: ["style-loader", "css-loader"],
      },
    ],
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: "./public/index.html",
    }),
    new ModuleFederationPlugin({ // 这里是重点部分
      filename: "remoteEntry.js",
      name: "remote",
      exposes: {
        "./NewsList": "./src/NewsList",
      },
    }),
  ],
};

src/index.js

import("./bootstrap");

src/bootstrap.js

import React from "react";
import ReactDOM from "react-dom";
import App from "./App";
ReactDOM.render(<App />, document.getElementById("root"));

src/App.js

import React from "react";
import NewsList from './NewsList';
const App = () => (
  <div>
    <h2>本地组件NewsList</h2>
    <NewsList />
  </div>
);

export default App;

src/NewsList.js 这个组件导出给别人使用,在 webpack 配置中可以看到。

import React from "react";
export default ()=>(
    <div>新闻列表</div>
)

配置 host

webpack.config.js

const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const ModuleFederationPlugin = require("webpack/lib/container/ModuleFederationPlugin");

module.exports = {
  mode: "development",
  entry: "./src/index.js",
  cache: {
    type: "filesystem",
    cacheDirectory: path.resolve(__dirname, "node_modules/.cache/webpack"),
  },
  output: {
    filename: "bundle.js",
    path: path.resolve(__dirname, "dist"),
    publicPath: "http://localhost:9000/",
  },
  devServer: {
    contentBase: path.join(__dirname, 'dist'),
    compress: true,
    port: 9000,
  },
  optimization: {
    usedExports: true,
  },
  devtool: false,
  module: {
    rules: [
      {
        test: /\.js$/,
        use: [
          {
            loader: "babel-loader",
            options: {
              presets: ["@babel/preset-react"],
            },
          },
        ],
        exclude: /node_modules/,
      },
      {
        test: /\.png$/,
        type: "asset/resource",
      },
      {
        test: /\.css$/,
        use: ["style-loader", "css-loader"],
      },
    ],
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: "./public/index.html",
    }),
    new ModuleFederationPlugin({ // 这里是重点部分
      filename: "remoteEntry.js",
      name: "host",
      remotes: {
        remote: "remote@http://localhost:8000/remoteEntry.js"
      }
    })
  ],
};

src/index.js

import("./bootstrap");

src/bootstrap.js

import React from "react";
import ReactDOM from "react-dom";
import App from "./App";
ReactDOM.render(<App />, document.getElementById("root"));

src/App.js 中导入了之前别人写好的 NewsList 组件,在 webpack 配置中可以看到。

import React from "react";
const RemoteNewsList = React.lazy(() => import("remote/NewsList"));

const App = () => (
  <div>
    <h2 >远程组件NewsList</h2>
    <React.Suspense fallback="Loading NewsList">
      <RemoteNewsList />
    </React.Suspense>
  </div>
);
export default App;

A 应用可以引用 B 整个应用,也可以应用 B 的页面和组件。这样一来,灵活性就非常大了。

配置参数

字段 类型 含义
name string 必传值,即输出的模块名,被远程引用时路径为${name}/${expose}
library object 声明全局变量的方式,name为umd的name
filename string 构建输出的文件名
remotes object 远程引用的应用名及其别名的映射,使用时以key值作为name
exposes object 被远程引用时可暴露的资源路径及其别名
shared object 与其他应用之间可以共享的第三方依赖,使你的代码中不用重复加载同一份依赖

以上代码都可以在我的demo中看到:https://github.com/wuxianqiang/webacpk5-remote

相关文章
|
6天前
|
缓存 前端开发 JavaScript
深入了解Webpack:模块打包的革命
【10月更文挑战第11天】深入了解Webpack:模块打包的革命
|
4天前
|
缓存 前端开发 JavaScript
Webpack技术深度解析:模块打包与性能优化
【10月更文挑战第13天】Webpack技术深度解析:模块打包与性能优化
|
5月前
|
存储 API
使用Webpack的module.hot API来定义模块的热替换
使用Webpack的`module.hot` API实现模块热替换,简单示例展示如何在`myModule`变化时执行回调。`module.hot.accept`接收模块路径和回调函数,当模块或其依赖变更时触发回调,用于执行更新逻辑。可通过`module.hot.data`保存和恢复状态以实现热替换时保持应用程序的状态。
|
1月前
|
前端开发 开发者
在前端开发中,webpack 作为一个强大的模块打包工具,为我们提供了丰富的功能和扩展性
【9月更文挑战第1天】在前端开发中,Webpack 作为强大的模块打包工具,提供了丰富的功能和扩展性。本文重点介绍 DefinePlugin 插件,详细探讨其原理、功能及实际应用。DefinePlugin 可在编译过程中动态定义全局变量,适用于环境变量配置、动态加载资源、接口地址配置等场景,有助于提升代码质量和开发效率。通过具体配置示例和注意事项,帮助开发者更好地利用此插件优化项目。
75 13
|
2月前
|
缓存 前端开发 JavaScript
Webpack 模块解析:打包原理、构造形式、扣代码补参数和全局导出
Webpack 模块解析:打包原理、构造形式、扣代码补参数和全局导出
75 1
|
2月前
|
前端开发 开发者
在前端开发中,webpack 作为模块打包工具,其 DefinePlugin 插件可在编译时动态定义全局变量,支持环境变量定义、配置参数动态化及条件编译等功能。
在前端开发中,webpack 作为模块打包工具,其 DefinePlugin 插件可在编译时动态定义全局变量,支持环境变量定义、配置参数动态化及条件编译等功能。本文阐述 DefinePlugin 的原理、用法及案例,包括安装配置、具体示例(如动态加载资源、配置接口地址)和注意事项,帮助开发者更好地利用此插件优化项目。
71 0
|
4月前
|
前端开发 JavaScript 架构师
Webpack模块联邦:微前端架构的新选择
Webpack的模块联邦是Webpack 5引入的革命性特性,革新了微前端架构。它允许独立的Web应用在运行时动态共享代码,无需传统打包过程。基本概念包括容器应用(负责加载协调)和远程应用(独立应用,可暴露模块)。实现步骤涉及容器和远程应用的`ModuleFederationPlugin`配置,以及在应用间导入和使用远程模块。模块联邦的优势在于独立开发、按需加载、版本管理和易于维护。通过实战案例展示了如何构建微前端应用,包括创建容器和远程应用,以及消费远程组件。高级用法涉及动态加载、路由集成、状态管理和错误处理。
88 3
|
4月前
|
缓存 前端开发 JavaScript
Webpack作为模块打包器,为前端项目提供了高度灵活和可配置的构建流程
【6月更文挑战第12天】本文探讨了优化TypeScript与Webpack构建性能的策略。理解Webpack的解析、构建和生成阶段是关键。优化包括:调整tsconfig.json(如关闭不必要的类型检查)和webpack.config.js选项,启用Webpack缓存,实现增量构建,代码拆分和懒加载。这些方法能提升构建速度,提高开发效率。
58 3
|
5月前
|
前端开发 JavaScript 开发者
深入了解Webpack:前端模块打包工具
深入了解Webpack:前端模块打包工具
92 1
|
10月前
|
前端开发 JavaScript 开发者
webpack模块打包器
Webpack是一种前端资源构建工具,可以将多个文件和模块打包成一个或多个bundle。它具有高度的可配置性,支持各种类型的文件和插件,可以自定义打包过程和结果。Webpack的核心概念包括入口、出口和模式,可以分别用于指示打包的起点、输出位置和优化级别。Webpack还具有自动化构建过程,通过Tapable机制组织多个处理流程,并允许插件监听特定事件来参与整个构建过程。总之,Webpack是一个功能强大的前端资源构建工具,提供了高度可配置的选项和插件机制,方便开发者进行自定义和扩展。