MF format 不是普通 library format
核心判断
format: "mf" 虽然出现在 LibConfig.format 里,但它不是 ESM/CJS/UMD 那样的普通库格式。它更像一个应用 remote 构建目标。
维护时不要把 MF 当成“另一个 library output”。它有自己的 runtime、shared module、remoteEntry、dev server 和 web target 假设。
MF 的特殊默认值
Rslib 对 MF 做了这些处理:
bundle: false直接报错。- 默认 target 是 web。
dev.writeToDisk = true。- output
uniqueName = pkgJson.name。 optimization.nodeEnv使用 development 或 production 字符串。- 需要 Module Federation 插件。
- minify 对 MF 更积极。
这些都和普通 library format 不同。
为什么不能 bundleless
MF remote 依赖 federation runtime 来暴露模块、加载 shared、处理 remoteEntry 和 chunks。Bundleless 的“保留源码模块结构”不符合 federation remote 的分发模型。
如果允许 MF bundleless,会出现两个模型冲突:
- federation 希望 runtime 管理 remote 模块。
- bundleless 希望输出文件之间保留普通 import。
因此 Rslib 禁止。
为什么 target 默认 web
MF remote 通常由浏览器或 web runtime 加载。即使构建工具运行在 Node,产物 target 也通常是 web。
这就是 composeTargetConfig 对 MF 特殊默认 web 的原因。
为什么 nodeEnv 不能 false
普通库构建中,Rslib 默认 optimization.nodeEnv = false,避免把 process.env.NODE_ENV 固化进库产物。
但 MF 需要构建 shared module,第三方包内部可能依赖 process.env.NODE_ENV 替换。如果 nodeEnv false,shared 包构建可能不符合预期。
所以 MF 分支会根据 env 设置:
- development。
- production。
为什么需要 uniqueName
Rspack output uniqueName 用于避免多个构建运行时冲突。MF remote 如果没有稳定 uniqueName,多个 remote 或 host 同时加载时可能出现 runtime 命名冲突。
Rslib 使用 package.json name 作为 uniqueName。
为什么要检查 MF 插件
format: "mf" 本身不足以构建 federation remote。用户必须配置 Module Federation 插件。Rslib 通过 checkMFPlugin 提前检查,避免后续 Rspack 产物不是用户以为的 MF remote。
这是典型“提前报配置错误”的策略。
和普通 web library 的区别
一个普通 ESM web library 可能只是:
它仍然是 library 产物。
MF 则涉及 remoteEntry、shared、exposes、runtime loading。两者不能混为一谈。
修改风险
MF 相关改动要检查:
tests/e2e/module-federationmf-dev- shared dependencies。
- remoteEntry。
- development 和 production。
- minify。
- writeToDisk。
不要因为某个普通 library case 需要调整默认值,就顺手影响 MF。