ModuleFederationPlugin 插件
markdown
# ModuleFederationPlugin 插件
`ModuleFederationPlugin` 允许一个构建在运行时向其他独立构建提供或消费模块。
```ts
import webpack from "webpack";
const { ModuleFederationPlugin } = webpack.container;
export default {
plugins: [
new ModuleFederationPlugin({
// 选项的类型定义(TypeScript)
runtime: string | false,
}),
],
};
选项
runtime
使用指定的名称创建一个新的运行时(runtime) chunk。
webpack.config.js
js
import webpack from "webpack";
const { ModuleFederationPlugin } = webpack.container;
export default {
plugins: [
new ModuleFederationPlugin({
runtime: "my-runtime-name",
}),
],
};
共享库
通过配置中的 shared 选项,你可以定义在联邦模块之间共享的库。包名与 package.json 中 dependencies 部分找到的包名相同。然而,默认情况下,webpack 只会共享库的根级别内容。
js
import webpack from "webpack";
const { ModuleFederationPlugin } = webpack.container;
export default {
plugins: [
new ModuleFederationPlugin({
// 将 date-fns 作为共享模块
shared: ["date-fns"],
}),
],
};
因此,在你的应用程序中,你可以这样做:
js
import { format } from "date-fns";
format(new Date(2014, 1, 11), "MM/dd/yyyy");
webpack 会自动在所有将 date-fns 定义为共享库的联邦模块之间共享 date-fns。
然而,如果你想访问包中不在根级别的某些内容,例如 date-fns/locale/en-GB/index.js,你需要在 shared 配置中给包名追加 /:
js
import webpack from "webpack";
const { ModuleFederationPlugin } = webpack.container;
export default {
plugins: [
new ModuleFederationPlugin({
// 将 date-fns 作为共享模块
// 包的所有文件都将被共享
shared: ["date-fns/"],
}),
],
};
/ 语法允许你访问一个包的所有文件。但是,它应该只在必要时使用,因为它会影响性能,特别是在 development 模式下。
指定包版本
有三种方法可以指定共享库的版本。
数组语法
此语法允许你仅通过包名来共享库。这种方法适合原型开发,但鉴于像 react 和 react-dom 这样的库会有额外的要求,它将不允许你扩展到大型生产环境。
js
import webpack from "webpack";
const { ModuleFederationPlugin } = webpack.container;
export default {
plugins: [
new ModuleFederationPlugin({
// 将 lodash 作为共享模块
// 版本从 package.json 中推断
// 不会对所需版本进行版本检查
// 所以它总是会使用找到的更高版本
shared: ["lodash"],
}),
],
};
对象语法
此语法为你提供了对每个共享库的更多控制,你可以将包名定义为键(key),版本(semver)定义为值。
js
export default {
plugins: [
new ModuleFederationPlugin({
shared: {
// 将 lodash 作为共享模块
// 版本从 package.json 中推断
// 它将使用最高的 lodash 版本,该版本满足 >= 4.17 且 < 5
lodash: "^4.17.0",
},
}),
],
};
带有共享提示(sharing hints)的对象语法
此语法允许你为每个共享包提供额外的提示,你可以将包名定义为键(key),值(value)为包含修改共享行为的提示的对象。
js
import { readFileSync } from "node:fs";
const deps = JSON.parse(
readFileSync(new URL("./package.json", import.meta.url)),
).dependencies;
export default {
plugins: [
new ModuleFederationPlugin({
shared: {
// 将 react 作为共享模块
react: {
requiredVersion: deps.react,
singleton: true,
},
},
}),
],
};
共享提示
eager
boolean
此提示允许 webpack 直接包含 provide 和 fallback 模块,而不是通过异步请求获取库。换句话说,这允许在初始 chunk 中使用此共享模块。此外,请注意,启用此提示后,所有提供的和回退的模块将始终被下载。
import
false | string
应放置在共享作用域(shared scope)中的提供的模块。如果共享作用域中找不到共享模块或版本无效,此提供的模块也用作回退模块。(此提示的值默认为属性名。)
packageName
string
用于从描述文件确定所需版本的包名。当无法从请求中自动确定包名时,才需要此选项。
requiredVersion
false | string
此字段指定包的所需版本。它接受语义化版本,例如 "^1.2.3"。此外,如果版本以 URL 形式提供,它也会获取该版本,例如:"git+ssh://git@github.com:foo/bar.git#v1.0.0"。
shareKey
string
所请求的共享模块在共享作用域中以此键(key)查找。
shareScope
string
共享作用域的名称。
singleton
boolean
此提示仅允许在共享作用域中存在单个版本的共享模块(默认禁用)。某些库使用全局内部状态(例如 react、react-dom)。因此,在同一时间只运行该库的一个实例至关重要。
当共享作用域中存在多个版本的相同依赖时,将使用最高的语义版本。
strictVersion
boolean
此提示允许 webpack 在版本无效时拒绝共享模块(当本地回退模块可用且共享模块不是单例时,默认为 true,否则为 false,如果未指定所需版本,则无效)。如果找不到所需版本,则抛出运行时错误。
version
false | string
提供的模块的版本。它允许 webpack 替换匹配的较低版本,但不能替换较高版本。
默认情况下,webpack 使用依赖的 package.json 文件中的版本。
附加示例
js
export default {
plugins: [
new ModuleFederationPlugin({
// 将 vue 作为共享模块
// 版本从 package.json 中推断
// 它将始终使用共享版本,但当共享的 vue < 2.6.5 或 >= 3 时打印警告
shared: {
vue: {
requiredVersion: "^2.6.5",
singleton: true,
},
},
}),
],
};
js
export default {
plugins: [
new ModuleFederationPlugin({
// 将 vue 作为共享模块
// 未提供本地版本
// 如果共享的 vue < 2.6.5 或 >= 3,它将发出警告
shared: {
vue: {
import: false,
requiredVersion: "^2.6.5",
},
},
}),
],
};
js
export default {
plugins: [
new ModuleFederationPlugin({
// 将 vue 作为共享模块
// 未提供本地版本
// 当共享的 vue < 2.6.5 或 >= 3 时,它将抛出错误
shared: {
vue: {
import: false,
requiredVersion: "^2.6.5",
strictVersion: true,
},
},
}),
],
};
js
export default {
plugins: [
new ModuleFederationPlugin({
shared: {
"my-vue": {
// 可以通过 "my-vue" 导入被引用
import: "vue", // "vue" 包将被用作提供和回退模块
shareKey: "shared-vue", // 共享模块将以该名称放置在共享作用域中
shareScope: "default", // 将使用具有此名称的共享作用域
singleton: true, // 只允许共享模块的单例版本
strictVersion: true, // 当版本无效时,不要使用共享版本。单例或没有回退的模块将抛出异常,否则使用回退
version: "1.2.3", // 共享模块的版本
requiredVersion: "^1.0.0", // 共享模块的所需版本
},
},
}),
],
};
帮助我们改进文档
发现翻译问题或内容错误?请告诉我们。
