Webpackwebpack5 模块联邦(Module Federation)
Posted 嘻嘻的妙妙屋
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Webpackwebpack5 模块联邦(Module Federation)相关的知识,希望对你有一定的参考价值。
webpack5 模块联邦(Module Federation)
Webpack 5 增加了一个新的功能 “模块联邦”,它允许多个 webpack 构建一起工作。 从运行时的角度来看,多个构建的模块将表现得像一个巨大的连接模块图。 从开发者的角度来看,模块可以从指定的远程构建中导入,并以最小的限制来使用。
多个独立的构建可以组成一个应用程序,这些独立的构建之间不应该存在依赖关系,因此可以单独开发和部署它们。这通常被称作微前端,但并不仅限于此。
Webpack5 模块联邦让 Webpack 达到了线上 Runtime 的效果,让代码直接在项目间利用 CDN 直接共享,不再需要本地安装 Npm 包、构建再发布了! 我们知道 Webpack 可以通过 DLL 或者 Externals 做代码共享时 Common Chunk, 但不同应用和项目间这个任务就变得困难了,我们几乎无法在项目之间做到按需热插拔。
模块联邦可以将一个应用的包应用于另一个应用,同时具备整体应用一起打包的公共依赖抽取能力。
举个例子
假设我们现在有两个项目模块,分别是项目A以及项目B,我们需要在项目模块A中应用项目模块B。
项目模块B
webpack.config.js
const htmlWebpackPlugin = require('html-webpack-plugin');
const ModuleFederationPlugin = require('webpack').container;
module.exports =
mode: 'production',
entry: './src/index.js',
devServer:
port: '3001',
,
plugins: [
new HtmlWebpackPlugin(),
new ModuleFederationPlugin(
// 模块联邦名字,提供给其他模块使用
name: 'app2',
// 提供给外部访问的资源入口
filename: 'App2RemoteEntry.js',
// 引用的外部资源列表
remotes: ,
// 暴露给外部的资源列表
exposes:
/**
* ./Header 是让外部应用使用时基于这个路径拼接引用路径,如:App2/Header
* ./src/Header.js 是当前应用的要暴露给外部的资源模块路径
*/
'./Header': './src/Header.js',
,
// 共享模块,值当前被 exposes 的模块需要使用的共享模块,如lodash
shared: ,
),
],
;
项目模块A
webpack.config.js
const HtmlWebpackPlugin = require('html-webpack-plugin');
const ModuleFederationPlugin = require('webpack').container;
module.exports =
mode: 'production',
entry: './src/index.js',
devServer:
port: '3000',
,
plugins: [
new HtmlWebpackPlugin(),
new ModuleFederationPlugin(
// 模块联邦名字,提供给其他模块使用
name: 'app1',
// 提供给外部访问的资源入口
filename: 'App1RemoteEntry.js',
// 引用的外部资源列表
remotes:
/**
* App2 引用其他应用模块的资源别名
* app2 是 APP2 的模块联邦名字
* http://localhost:3001 是 APP2 运行的地址
* App2RemoteEntry.js 是 APP2 提供的外部访问的资源名字
* 可以访问到 APP2 通过 exposes 暴露给外部的资源
*/
App2: 'app2@http://localhost:3001/App2RemoteEntry.js',
,
// 暴露给外部的资源列表
exposes: ,
// 共享模块,如lodash
shared: ,
),
],
;
src/index.js
import Home from './Home';
/**
* 需要异步导入
* App2 为 remotes 中定义的资源别名
* ./Header 为 APP2 exposes 定义的 ./Header
*/
import('App2/Header').then((Header) =>
const body = document.createElement('div');
body.appendChild(Header.default());
document.body.appendChild(body);
);
APP1 执行 npx webpack
可以看到 dist/main.js 包含了 APP1 的 Header 模块,它依然是通过 CDN 引入的,APP1 执行 npx webpack serve
可以看到模块联邦使用成功!验证了模块联邦可以将一个应用的包应用于另一个应用,同时具备整体应用一起打包的公共依赖抽取的能力。
总结
试想一下,你有一个组件包通过 npm 发布后,你的10个业务项目引用这个组件包。当这个组件包更新了版本,你的10个项目想要使用最新功能就必须一一升级版本、编译打包、部署,这很繁琐。但是模块联邦让组件包利用CDN的方式共享给其他项目,这样一来,当你到组件包更新了,你的10个项目中的组件也自然更新了。
以上是关于Webpackwebpack5 模块联邦(Module Federation)的主要内容,如果未能解决你的问题,请参考以下文章