1、Module Federation# 模块联邦特性
-
是什么 允许多个独立的webpack应用之间动态共享代码,一个应用可以在运行时从一个应用加载并使用其代码模块,仿佛这些模块是本地的一部分
-
解决了什么问题 在模块联邦出现前,共享代码的方式只要存在以下几种
- npm包,通过单独构建组件成npm包的形式在不同项目中引入;但是这种方式无法实现实时同步
- git submodule的形式;管理复杂,同样需要更新主项目重新构建
- 外部化+CDN形式,通过external将库(如react\lodash)排除,在运行时通过
而模块联邦则解决上述问题: (1)去中心化,每个应用都是独立的,单独开发部署 (2)运行时动态加载,实现代码实时共享 (3)共享依赖,两个应用共享同一个库,可以协商使用其中一个版本,避免重复加载
-
工作原理 主要是有两个角色来工作
- remote远程应用,他暴露一些模块给其他应用使用
- host主机应用,消费或引用remote模块
// remote应用配置 module.export = { //... 其他配置 plugins: [ new ModuleFederationPlugin({ // 该应用的名称,作为唯一标识 name: 'remote_app', // 暴露给外部使用的模块文件 filename: 'remoteEntry.js', // 声明要暴露的模块 exposes: { // 键名:导入路径 // 值:本地模块的实际路径 './Button': './src/components/Button.jsx', './Header': './src/components/Header.jsx', }, // 声明共享的库 shared: { react: { singleton: true }, // singleton 确保只使用一个单例版本 'react-dom': { singleton: true }, }, }) ] } // host应用配置 module.exports = { // ... 其他配置 plugins: [ new ModuleFederationPlugin({ name: 'host_app', // 配置需要引用的远程应用 remotes: { // 键名:在代码中导入时使用的路径前缀 // 值:远程应用的名称@远程Entry.js的URL remote_lib: 'remote_app@http://localhost:3001/remoteEntry.js', }, // 同样可以声明共享依赖 shared: { react: { singleton: true }, 'react-dom': { singleton: true }, }, }), ], }; // 在 Host 应用的 React 组件中 import React from 'react'; // 动态导入 Remote 应用的 Button 组件 const RemoteButton = React.lazy(() => import('remote_lib/Button')); function App() { return ( <div> <h1>这是 Host 应用</h1> <React.Suspense fallback="Loading Button..."> <RemoteButton /> </React.Suspense> </div> ); } export default App; -
应用场景
- 微前端: 每个应用独立部署,主应用动态集成
- 跨项目组件库,将通用业务组件通过联邦共享,任何项目中都可以实时使用最新版本
- 巨型应用拆分:将一个庞大的单体项目拆分成多个独立,可联邦的部分,提升团队协作和构建速度
-
github关于这个模块的学习demo github.com/markz-demo/…
2、cache缓存特性
在webpack5之前,我们通常使用cache-loader和babel-loader的自带缓存来提升二次构建速度,但是这些方案配置比较繁琐,而且缓存力粒度不够理想,wepack5内置了持久化磁盘缓存,开箱即用,效果明显。
- 解决问题 webpack构建报告多个阶段(模块解析、依赖分析、转化、优化等)。在没有持久化缓存的情况下,每次都需要重头开始,即使只改动了一点点代码,这将使得效率低下
- 如何配置
// 简单配置
module.exports = {
// ... 其他配置
cache: {
type: 'filesystem', // 使用文件系统缓存
},
};
// 比较详细的配置
module.exports = {
cache: {
type:'filesystem',
// 自定义缓存目录,默认为 node_modules/.cache/webpack
cacheDirectory: path.resolve(__dirname, 'node_modules/.cache/webpack'),
// 构建依赖,当这些文件发生变化时,缓存会失效
buildDependencies: {
// 通常将项目配置文件加入,这样配置改变时缓存自动失效
config: [__filename],
},
// 缓存版本,当内部缓存数据结构变化时,可更改此版本号来使旧缓存失效
version: 'your-custom-version',
},
};
```