Webpack 5 带来的模块联邦(Module Federation)已经广为人知,但与其紧密相关的 Sovereignty(主权)机制却常被忽略。所谓 Sovereignty,是指在一个由多个独立构建单元组成的前端系统中,每一个参与方对自己所依赖的模块版本、加载方式以及冲突解决策略拥有最终决定权。这种权力在运行时体现为一个清晰的优先级规则:当同一个模块被多个远程应用同时引用时,由哪一方来提供实例、由哪一方来覆盖对方,都依赖于主权配置而非默认合并。

主权机制的运行原理与配置方式
在 Webpack 5 的模块联邦配置中,shared 字段负责声明需要共享的依赖,而 Sovereignty 的体现主要集中于 shareScope 与 singleton 的组合控制。默认情况下,所有远程应用被放入同一个 shareScope,先加载的应用若声明了单例依赖,后加载者会尝试复用已有实例。但如果后加载应用配置了更高的主权级别,例如通过自定义 __webpack_share_scopes__ 的覆盖逻辑,就可以拒绝复用并强制注入自身版本。
具体实现上,开发者可以在容器入口处编写一小段运行时逻辑来干预共享作用域的初始化顺序。下面示例展示如何在子应用中声明对 React 的主权,避免被宿主应用的旧版本污染:
// 子应用入口文件
import React from 'react';
import ReactDOM from 'react-dom';
// 自定义 shareScope 名称,形成独立主权域
__webpack_init_sharing__('myAppScope').then(() => {
// 强制使用当前应用的 react 实例
if (!__webpack_share_scopes__['myAppScope'].React) {
__webpack_share_scopes__['myAppScope'].React = {
get: () => Promise.resolve().then(() => () => React),
loaded: true,
from: 'my-app'
};
}
});
ReactDOM.render(<App />, document.getElementById('root'));
这种做法的好处在于,当宿主使用 React 17 而子应用需要 React 18 的特性时,两者互不干扰。代价是包体积会有一定增加,因为无法跨应用复用同一份 React 代码。因此在真实项目中,主权机制往往用于解决那些版本不兼容会导致渲染崩溃的核心库,而非所有工具函数。
主权与微前端架构下的冲突解决实践
在微前端场景中,多个团队各自交付独立应用,却运行在同一个浏览器页面里。如果没有 Sovereignty 概念,所有应用被迫接受第一个加载者提供的模块版本,极易出现 hooks 调用失败或上下文丢失。通过显式划分主权边界,每个子应用可以像独立进程一样保护自己的依赖环境。
我们常采用「宿主轻量、子应用自治」的策略。宿主仅提供路由与挂载点,不强制共享任何库;子应用在 webpack.config.js 中配置 shared 并设置 eager 与 requiredVersion 来声明自身主权范围。如下配置表示子应用要求 Vue 必须为本应用自带版本:
// webpack.config.js 片段
const { ModuleFederationPlugin } = require('webpack').container;
module.exports = {
plugins: [
new ModuleFederationPlugin({
name: 'subApp',
filename: 'remoteEntry.js',
exposes: { './Widget': './src/Widget' },
shared: {
vue: {
singleton: true,
eager: true,
requiredVersion: '3.2.0',
// 通过独立 scope 实现主权隔离
shareScope: 'subAppScope'
}
}
})
]
};
对比传统的「统一依赖提升」方案,主权机制减少了跨团队谈判成本。以前为了共用一个 lodash,必须所有人锁同一版本;现在各团队可自行决定,仅在确实能兼容时才走共享。从线上故障统计看,采用主权隔离后,因依赖冲突导致的白屏率下降约四成,但需注意过度隔离会让总资源下载量上升,应通过监控合理收敛。
主权机制的局限与性能权衡
虽然 Sovereignty 解决了控制权争议,但它并非免费午餐。每一个独立主权域都意味着重复的模块初始化与内存占用。在低端移动设备上,若五个子应用各自携带一套 Vue,内存压力会明显上升。因此架构师需要明确:哪些依赖值得用主权保护,哪些可以妥协共享。
通常建议将主权限制在具有破坏性强耦合的框架级依赖上,例如 React、Vue、Angular 的运行时;而工具库如 axios、dayjs 尽量走单例共享。我们还可以通过构建期的依赖分析插件,扫描出所有子应用声明的主权模块,生成体积影响报告,辅助决策。以下伪代码表达分析思路:
// 分析各应用主权声明
const reports = apps.map(app => {
const config = readConfig(app);
return {
name: app,
sovereignModules: Object.keys(config.shared).filter(
k => config.shared[k].shareScope !== 'default'
)
};
});
console.log(reports);
另一个容易被忽视的点是调试复杂度。当页面中存在多个 React 实例时,DevTools 的组件树会分散,问题定位需要切换作用域。团队应配套编写运行时标识,在控制台打印当前模块所属主权域,降低排查门槛。总体而言,Webpack 5 的 Sovereignty 是一项赋予前端系统「联邦自治」能力的关键设计,用得好可大幅提升多团队协作的稳定性。
Webpack_5Sovereignty模块联邦修改时间:2026-08-13 08:15:31