ModuleFederationPlugin

ModuleFederationPlugin 允許建置在執行階段提供或使用其他獨立建置的模組。

const { ModuleFederationPlugin } = require('webpack').container;
module.exports = {
  plugins: [
    new ModuleFederationPlugin({
      // options' typings in typescript
      runtime: string | false,
    }),
  ],
};

選項

執行階段

使用指定的檔名建立新的執行階段區塊。

webpack.config.js

const { ModuleFederationPlugin } = require('webpack').container;
module.exports = {
  plugins: [
    new ModuleFederationPlugin({
      runtime: 'my-runtime-name',
    }),
  ],
};

共用函式庫

在組態中的 shared 鍵中,您可以定義在聯合模組之間共用的函式庫。套件名稱與在 package.json 的 dependencies 區段中找到的相同。不過,預設 webpack 只會共用函式庫的根層級。

const { ModuleFederationPlugin } = require('webpack').container;
module.exports = {
  plugins: [
    new ModuleFederationPlugin({
      // adds date-fns as shared module
      shared: ['date-fns'],
    }),
  ],
};

因此,您可以在應用程式中執行類似下列動作

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 組態中將 / 附加到套件名稱

const { ModuleFederationPlugin } = require('webpack').container;
module.exports = {
  plugins: [
    new ModuleFederationPlugin({
      // adds date-fns as shared module
      // all files of the package will be shared
      shared: ['date-fns/'],
    }),
  ],
};

/ 語法允許您存取封包的所有檔案。然而,它應該只在必要時使用,因為它會影響效能,特別是在 development 模式。

指定封包版本

有三個方法可以指定共用函式庫的版本。

陣列語法

此語法允許您僅使用封包名稱來共用函式庫。此方法適用於原型製作,但由於 reactreact-dom 等函式庫需要額外的需求,因此它不允許您擴充到大型生產環境。

const { ModuleFederationPlugin } = require('webpack').container;
module.exports = {
  plugins: [
    new ModuleFederationPlugin({
      // adds lodash as shared module
      // version is inferred from package.json
      // there is no version check for the required version
      // so it will always use the higher version found
      shared: ['lodash'],
    }),
  ],
};
物件語法

此語法提供您對每個共用函式庫有更多控制權,您可以在其中定義封包名稱為鍵,版本 (semver) 為值。

module.exports = {
  plugins: [
    new ModuleFederationPlugin({
      shared: {
        // adds lodash as shared module
        // version is inferred from package.json
        // it will use the highest lodash version that is >= 4.17 and < 5
        lodash: '^4.17.0',
      },
    }),
  ],
};
具有共用提示的物件語法

此語法允許您提供額外的 提示 給每個共用封包,您可以在其中定義封包名稱為鍵,而值為包含提示的物件,以修改共用行為。

const deps = require('./package.json').dependencies;

module.exports = {
  plugins: [
    new ModuleFederationPlugin({
      shared: {
        // adds react as shared module
        react: {
          requiredVersion: deps.react,
          singleton: true,
        },
      },
    }),
  ],
};

共用提示

eager

布林值

此提示將允許 webpack 直接包含提供的和備用模組,而不是透過非同步請求擷取函式庫。換句話說,這允許在初始區塊中使用此共用模組。此外,請注意,當啟用此提示時,所有提供的和備用模組將始終被下載。

import

false | 字串

應置於共用範圍的提供模組。此提供模組也作為備用模組,如果在共用範圍中找不到共用模組或版本無效時使用。(此提示的預設值為屬性名稱。)

packageName

字串

用於從描述檔案中判斷所需版本的套件名稱。這僅在無法從請求中自動判斷套件名稱時才需要。

requiredVersion

false | 字串

套件所需版本。它接受語意化版本控制。例如,"^1.2.3"。

shareKey

字串

根據此金鑰從共用範圍中查詢所要求的共用模組。

shareScope

字串

共用範圍的名稱。

singleton

布林值

此提示僅允許共用範圍中存在共用模組的單一版本(預設為停用)。某些函式庫使用全域內部狀態(例如 react、react-dom)。因此,一次只執行函式庫的一個執行個體至關重要。

如果共用範圍中存在相同依賴項的版本,則使用語意化版本最高的版本。

strictVersion

布林值

此提示允許 webpack 在版本無效時拒絕共用模組(如果本地備用模組可用且共用模組不是單例,則預設為 true,否則為 false,如果未指定所需版本,則無效)。如果找不到所需版本,則會擲出執行時期錯誤。

version

false | 字串

提供的模組版本。它允許 webpack 取代較低匹配版本,但不能取代較高版本。

預設情況下,webpack 會使用相依項的 package.json 檔案中的版本。

其他範例

module.exports = {
  plugins: [
    new ModuleFederationPlugin({
      // adds vue as shared module
      // version is inferred from package.json
      // it will always use the shared version, but print a warning when the shared vue is < 2.6.5 or >= 3
      shared: {
        vue: {
          requiredVersion: '^2.6.5',
          singleton: true,
        },
      },
    }),
  ],
};
module.exports = {
  plugins: [
    new ModuleFederationPlugin({
      // adds vue as shared module
      // there is no local version provided
      // it will emit a warning if the shared vue is < 2.6.5 or >= 3
      shared: {
        vue: {
          import: false,
          requiredVersion: '^2.6.5',
        },
      },
    }),
  ],
};
module.exports = {
  plugins: [
    new ModuleFederationPlugin({
      // adds vue as shared module
      // there is no local version provided
      // it will throw an error when the shared vue is < 2.6.5 or >= 3
      shared: {
        vue: {
          import: false,
          requiredVersion: '^2.6.5',
          strictVersion: true,
        },
      },
    }),
  ],
};
module.exports = {
  plugins: [
    new ModuleFederationPlugin({
      shared: {
        'my-vue': {
          // can be referenced by import "my-vue"
          import: 'vue', // the "vue" package will be used as a provided and fallback module
          shareKey: 'shared-vue', // under this name the shared module will be placed in the share scope
          shareScope: 'default', // share scope with this name will be used
          singleton: true, // only a single version of the shared module is allowed
          strictVersion: true, // don't use shared version when version isn't valid. Singleton or modules without fallback will throw, otherwise fallback is used
          version: '1.2.3', // the version of the shared module
          requiredVersion: '^1.0.0', // the required version of the shared module
        },
      },
    }),
  ],
};

進一步閱讀

4 貢獻者

XiaofengXie16chenxsanburhanudaychristian24