diff --git a/.changeset/breezy-tools-serve.md b/.changeset/breezy-tools-serve.md new file mode 100644 index 00000000000..724f8b21ec5 --- /dev/null +++ b/.changeset/breezy-tools-serve.md @@ -0,0 +1,5 @@ +--- +'@module-federation/rsbuild-plugin': patch +--- + +allow override to enable mf on other formats with `forceMfOnAllFormats` diff --git a/.changeset/lovely-waves-draw.md b/.changeset/lovely-waves-draw.md new file mode 100644 index 00000000000..d2a55a85993 --- /dev/null +++ b/.changeset/lovely-waves-draw.md @@ -0,0 +1,5 @@ +--- +'@module-federation/rsbuild-plugin': patch +--- + +Do not set chunkLoading to jsonp when chunkFormat is module / esm diff --git a/.cursorignore b/.cursorignore index 2ab6da1ea8a..6af59d7f51d 100644 --- a/.cursorignore +++ b/.cursorignore @@ -15,8 +15,6 @@ **/tsconfig.* **/*/stats.json -# First ignore everything -* # Then allow specific packages and their contents !packages/webpack-bundler-runtime/ @@ -25,23 +23,19 @@ !packages/sdk/**/* !packages/enhanced/ !packages/enhanced/**/* +!packages/rsbuild-plugin/ +!packages/rsbuild-plugin/**/* # Allow package.json files !package.json !packages/*/package.json !**/package.json -# Explicitly ignore specific packages -packages/dts-plugin/ -packages/typescript/ -packages/native-* -packages/core/ packages/assemble-release-plan/ packages/native-federation-typescript/ packages/esbuild/ # Ignore specific directories -apps/ webpack/tooling/ webpack/setup/ webpack/test/ @@ -52,6 +46,7 @@ tools/ .vscode/ .verdaccio/ + # Ignore specific files .cursorignore jest.preset.js diff --git a/apps/website-new/docs/en/guide/basic/rsbuild.mdx b/apps/website-new/docs/en/guide/basic/rsbuild.mdx index 58df77a26ef..239b639b255 100644 --- a/apps/website-new/docs/en/guide/basic/rsbuild.mdx +++ b/apps/website-new/docs/en/guide/basic/rsbuild.mdx @@ -38,6 +38,8 @@ export default defineConfig({ remote1: 'remote1@http://localhost:2001/mf-manifest.json', }, shared: ['react', 'react-dom'], + // Optional: Force Module Federation to be applied to all formats + // forceMfOnAllFormats: true, }), ], }); @@ -81,5 +83,13 @@ export default defineConfig({ }); ``` +### Configuration Options + +The `pluginModuleFederation` accepts all standard Module Federation plugin options, plus these additional options: + +| Option | Type | Default | Description | +|--------|------|---------|-------------| +| `forceMfOnAllFormats` | `boolean` | `false` | When set to `true`, Module Federation will be applied to all formats, overriding the internal format check. This allows applying Module Federation even to library formats like UMD or CommonJS. | + ### Note If you need to use the Module Federation runtime capabilities, please install [@module-federation/enhanced](/en/guide/basic/runtime.html) diff --git a/packages/rsbuild-plugin/src/cli/index.ts b/packages/rsbuild-plugin/src/cli/index.ts index efa7a7f479f..2f8e39a89f7 100644 --- a/packages/rsbuild-plugin/src/cli/index.ts +++ b/packages/rsbuild-plugin/src/cli/index.ts @@ -16,7 +16,14 @@ import type { RsbuildPlugin, Rspack } from '@rsbuild/core'; import logger from '../logger'; type ModuleFederationOptions = - moduleFederationPlugin.ModuleFederationPluginOptions; + moduleFederationPlugin.ModuleFederationPluginOptions & { + /** + * When set to true, Module Federation will be applied to all formats, + * overriding the isMFFormat check + * @default false + */ + forceMfOnAllFormats?: boolean; + }; export type { ModuleFederationOptions }; @@ -44,13 +51,19 @@ export function isMFFormat(bundlerConfig: Rspack.Configuration) { ); } +/** + * Module Federation plugin for Rsbuild + * @param options Plugin options + */ export const pluginModuleFederation = ( moduleFederationOptions: ModuleFederationOptions, ): RsbuildPlugin => ({ name: RSBUILD_PLUGIN_MODULE_FEDERATION_NAME, setup: (api) => { + const { forceMfOnAllFormats = false, ...restOptions } = + moduleFederationOptions; const sharedOptions: [string, sharePlugin.SharedConfig][] = parseOptions( - moduleFederationOptions.shared || [], + restOptions.shared || [], (item, key) => { if (typeof item !== 'string') throw new Error('Unexpected array in shared'); @@ -77,7 +90,7 @@ export const pluginModuleFederation = ( throw new Error('Can not get bundlerConfigs!'); } bundlerConfigs.forEach((bundlerConfig) => { - if (!isMFFormat(bundlerConfig)) { + if (!forceMfOnAllFormats && !isMFFormat(bundlerConfig)) { return; } else { // mf @@ -135,20 +148,23 @@ export const pluginModuleFederation = ( } } - if (!bundlerConfig.output?.chunkLoadingGlobal) { + if ( + !bundlerConfig.output?.chunkLoadingGlobal && + bundlerConfig.output?.chunkFormat !== 'module' + ) { bundlerConfig.output!.chunkLoading = 'jsonp'; } // `uniqueName` is required for react refresh to work if (!bundlerConfig.output?.uniqueName) { - bundlerConfig.output!.uniqueName = moduleFederationOptions.name; + bundlerConfig.output!.uniqueName = restOptions.name; } if ( !bundlerConfig.plugins!.find((p) => p && p.name === PLUGIN_NAME) ) { bundlerConfig.plugins!.push( - new ModuleFederationPlugin(moduleFederationOptions), + new ModuleFederationPlugin(restOptions), ); } } @@ -158,7 +174,7 @@ export const pluginModuleFederation = ( // dev config only works on format: 'mf' api.modifyRsbuildConfig((config) => { // Change some default configs for remote modules - if (moduleFederationOptions.exposes) { + if (restOptions.exposes) { config.dev ||= {}; // For remote modules, Rsbuild should send the ws request to the provider's dev server.