<!-- Please make sure you have read the submission guidelines before posting an PR --> <!-- https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr --> <!-- Please make sure that your commit message follows our format --> <!-- Example: `fix(nx): must begin with lowercase` --> <!-- If this is a particularly complex change or feature addition, you can request a dedicated Nx release for this pull request branch. Mention someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they will confirm if the PR warrants its own release for testing purposes, and generate it for you if appropriate. --> ## Current Behavior <!-- This is the behavior we have today --> When we had initially designed our Module Federation support for React, we had to get some changes put in place in webpack itself directly to allow for ESM. However, the best support for Module Federation for both Rspack and Webpack comes from CJS. ## Expected Behavior <!-- This is the behavior we should expect with the changes in this PR --> Ensure CJS is used to ensure interopability between webpack and rspack module federation applications ## Related Issue(s) <!-- Please link the issue being fixed so it gets closed when this is merged. --> Fixes #
88 lines
2.7 KiB
TypeScript
88 lines
2.7 KiB
TypeScript
import {
|
|
ModuleFederationConfig,
|
|
NxModuleFederationConfigOverride,
|
|
} from '@nx/webpack/src/utils/module-federation';
|
|
import { getModuleFederationConfig } from './utils';
|
|
import type { AsyncNxComposableWebpackPlugin } from '@nx/webpack';
|
|
import { ModuleFederationPlugin } from '@module-federation/enhanced/webpack';
|
|
|
|
/**
|
|
* @param {ModuleFederationConfig} options
|
|
* @return {Promise<AsyncNxComposableWebpackPlugin>}
|
|
*/
|
|
export async function withModuleFederation(
|
|
options: ModuleFederationConfig,
|
|
configOverride?: NxModuleFederationConfigOverride
|
|
): Promise<AsyncNxComposableWebpackPlugin> {
|
|
if (global.NX_GRAPH_CREATION) {
|
|
return (config) => config;
|
|
}
|
|
|
|
const { sharedDependencies, sharedLibraries, mappedRemotes } =
|
|
await getModuleFederationConfig(options);
|
|
|
|
return (config, ctx) => {
|
|
config.output.uniqueName = options.name;
|
|
config.output.publicPath = 'auto';
|
|
|
|
config.output.scriptType = 'text/javascript';
|
|
config.optimization = {
|
|
...(config.optimization ?? {}),
|
|
runtimeChunk: false,
|
|
};
|
|
|
|
if (
|
|
config.mode === 'development' &&
|
|
Object.keys(mappedRemotes).length > 1 &&
|
|
!options.exposes
|
|
) {
|
|
config.optimization.runtimeChunk = 'single';
|
|
}
|
|
|
|
config.plugins.push(
|
|
new ModuleFederationPlugin({
|
|
name: options.name,
|
|
filename: 'remoteEntry.js',
|
|
exposes: options.exposes,
|
|
remotes: mappedRemotes,
|
|
shared: {
|
|
...sharedDependencies,
|
|
},
|
|
/**
|
|
* remoteType: 'script' is required for the remote to be loaded as a script tag.
|
|
* remotes will need to be defined as:
|
|
* { appX: 'appX@http://localhost:3001/remoteEntry.js' }
|
|
* { appY: 'appY@http://localhost:3002/remoteEntry.js' }
|
|
*/
|
|
remoteType: 'script',
|
|
/**
|
|
* Apply user-defined config overrides
|
|
*/
|
|
...(configOverride ? configOverride : {}),
|
|
runtimePlugins:
|
|
process.env.NX_MF_DEV_REMOTES &&
|
|
!options.disableNxRuntimeLibraryControlPlugin
|
|
? [
|
|
...(configOverride?.runtimePlugins ?? []),
|
|
require.resolve(
|
|
'@nx/webpack/src/utils/module-federation/plugins/runtime-library-control.plugin.js'
|
|
),
|
|
]
|
|
: configOverride?.runtimePlugins,
|
|
virtualRuntimeEntry: true,
|
|
}),
|
|
sharedLibraries.getReplacementPlugin()
|
|
);
|
|
|
|
// The env var is only set from the module-federation-dev-server
|
|
// Attach the runtime plugin
|
|
config.plugins.push(
|
|
new (require('webpack').DefinePlugin)({
|
|
'process.env.NX_MF_DEV_REMOTES': process.env.NX_MF_DEV_REMOTES,
|
|
})
|
|
);
|
|
|
|
return config;
|
|
};
|
|
}
|