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
モードではパフォーマンスに影響を与えるため、必要な場合にのみ使用してください。
共有ライブラリのバージョンを指定する方法は3つあります。
この構文では、パッケージ名のみでライブラリを共有できます。この方法はプロトタイピングには適していますが、react
やreact-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
boolean
このヒントを使用すると、webpackは、非同期リクエストを介してライブラリをフェッチする代わりに、提供されたモジュールとフォールバックモジュールを直接含めることができます。つまり、この共有モジュールを最初のチャンクで使用できます。また、このヒントが有効になっている場合は、提供されたモジュールとフォールバックモジュールが常にダウンロードされることに注意してください。
import
false | string
共有スコープに配置する必要がある提供されたモジュール。この提供されたモジュールは、共有スコープに共有モジュールが見つからない場合、またはバージョンが無効な場合のフォールバックモジュールとしても機能します。(このヒントの値は、デフォルトでプロパティ名になります。)
packageName
string
記述ファイルから必要なバージョンを決定するために使用されるパッケージ名。これは、リクエストからパッケージ名を自動的に決定できない場合にのみ必要です。
requiredVersion
false | string
パッケージの必須バージョン。セマンティックバージョニングを受け入れます。たとえば、"^1.2.3"など。
shareKey
string
要求された共有モジュールは、共有スコープからこのキーで検索されます。
shareScope
string
共有スコープの名前。
singleton
boolean
このヒントは、共有スコープ内で共有モジュールの単一バージョンのみを許可します(デフォルトでは無効)。一部のライブラリはグローバルな内部状態を使用します(例:react、react-dom)。したがって、一度に実行されるライブラリのインスタンスを1つだけにすることが重要です。
共有スコープに同じ依存関係の複数のバージョンがある場合は、最も高いセマンティックバージョンが使用されます。
strictVersion
boolean
このヒントを使用すると、バージョンが無効な場合にwebpackが共有モジュールを拒否できます(ローカルのフォールバックモジュールが利用可能で、共有モジュールがシングルトンでない場合はデフォルトでtrue
、それ以外の場合はfalse
です。必須バージョンが指定されていない場合は効果がありません)。必須バージョンが見つからない場合は、ランタイムエラーをスローします。
version
false | string
提供されたモジュールのバージョン。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
},
},
}),
],
};