知海

ModuleFederationPlugin 插件

webpackjsorg-main插件参考
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.jsondependencies 部分找到的包名相同。然而,默认情况下,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 模式下。

指定包版本

有三种方法可以指定共享库的版本。

数组语法

此语法允许你仅通过包名来共享库。这种方法适合原型开发,但鉴于像 reactreact-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 直接包含 providefallback 模块,而不是通过异步请求获取库。换句话说,这允许在初始 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", // 共享模块的所需版本
        },
      },
    }),
  ],
};
复制代码

帮助我们改进文档

发现翻译问题或内容错误?请告诉我们。