diff --git a/packages/core/src/cli/build.ts b/packages/core/src/cli/build.ts index c305c84d5..b1a7ec41e 100644 --- a/packages/core/src/cli/build.ts +++ b/packages/core/src/cli/build.ts @@ -11,6 +11,7 @@ export async function build( const environments = await composeRsbuildEnvironments(config); const rsbuildInstance = await createRsbuild({ rsbuildConfig: { + plugins: config.plugins, environments: pruneEnvironments(environments, options.lib), }, }); diff --git a/packages/core/src/cli/inspect.ts b/packages/core/src/cli/inspect.ts index cfe67a6c7..1710e8d74 100644 --- a/packages/core/src/cli/inspect.ts +++ b/packages/core/src/cli/inspect.ts @@ -10,6 +10,7 @@ export async function inspect( const environments = await composeRsbuildEnvironments(config); const rsbuildInstance = await createRsbuild({ rsbuildConfig: { + plugins: config.plugins, environments: pruneEnvironments(environments, options.lib), }, }); diff --git a/packages/core/src/cli/mf.ts b/packages/core/src/cli/mf.ts index be87ae68d..d2bfcc46c 100644 --- a/packages/core/src/cli/mf.ts +++ b/packages/core/src/cli/mf.ts @@ -25,8 +25,15 @@ async function initMFRsbuild( } mfRsbuildConfig.config = changeEnvToDev(mfRsbuildConfig.config); + const rsbuildInstance = await createRsbuild({ - rsbuildConfig: mfRsbuildConfig.config, + rsbuildConfig: { + ...mfRsbuildConfig.config, + plugins: [ + ...(rslibConfig.plugins || []), + ...(mfRsbuildConfig.config.plugins || []), + ], + }, }); const devServer = await rsbuildInstance.startDevServer(); diff --git a/packages/core/src/config.ts b/packages/core/src/config.ts index 30f019b71..48df97cbe 100644 --- a/packages/core/src/config.ts +++ b/packages/core/src/config.ts @@ -4,6 +4,7 @@ import { type EnvironmentConfig, type RsbuildConfig, type RsbuildPlugin, + type RsbuildPlugins, defineConfig as defineRsbuildConfig, loadConfig as loadRsbuildConfig, mergeRsbuildConfig, @@ -1143,8 +1144,11 @@ const composeExternalHelpersConfig = ( return defaultConfig; }; -async function composeLibRsbuildConfig(config: LibConfig) { - checkMFPlugin(config); +async function composeLibRsbuildConfig( + config: LibConfig, + sharedPlugins?: RsbuildPlugins, +) { + checkMFPlugin(config, sharedPlugins); // Get the absolute path of the root directory to align with Rsbuild's default behavior const rootPath = config.root @@ -1258,7 +1262,11 @@ export async function composeCreateRsbuildConfig( rslibConfig: RslibConfig, ): Promise { const constantRsbuildConfig = await createConstantRsbuildConfig(); - const { lib: libConfigsArray, ...sharedRsbuildConfig } = rslibConfig; + const { + lib: libConfigsArray, + plugins: sharedPlugins, + ...sharedRsbuildConfig + } = rslibConfig; if (!libConfigsArray) { throw new Error( @@ -1274,7 +1282,10 @@ export async function composeCreateRsbuildConfig( // Merge the configuration of each environment based on the shared Rsbuild // configuration and Lib configuration in the settings. - const libRsbuildConfig = await composeLibRsbuildConfig(userConfig); + const libRsbuildConfig = await composeLibRsbuildConfig( + userConfig, + sharedPlugins, + ); // Reset certain fields because they will be completely overridden by the upcoming merge. // We don't want to retain them in the final configuration. diff --git a/packages/core/src/utils/helper.ts b/packages/core/src/utils/helper.ts index e5c3805e8..0fefa76a1 100644 --- a/packages/core/src/utils/helper.ts +++ b/packages/core/src/utils/helper.ts @@ -184,16 +184,20 @@ export function isPluginIncluded( ); } -export function checkMFPlugin(config: LibConfig): boolean { +export function checkMFPlugin( + config: LibConfig, + sharedPlugins?: RsbuildPlugins, +): boolean { if (config.format !== 'mf') { return true; } // https://github.com/module-federation/core/blob/4e5c4b96ee45899f3ba5904b8927768980d5ad0e/packages/rsbuild-plugin/src/cli/index.ts#L17 - const added = isPluginIncluded( - 'rsbuild:module-federation-enhanced', - config.plugins, - ); + const added = isPluginIncluded('rsbuild:module-federation-enhanced', [ + ...(sharedPlugins || []), + ...(config.plugins || []), + ]); + if (!added) { logger.warn( `${color.green('format: "mf"')} should be used with ${color.blue( diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e740298b8..9585662ec 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -687,6 +687,8 @@ importers: specifier: ^1.2.0 version: 1.2.0(@rsbuild/core@1.1.9) + tests/integration/plugins: {} + tests/integration/polyfill: dependencies: core-js-pure: diff --git a/tests/integration/plugins/index.test.ts b/tests/integration/plugins/index.test.ts new file mode 100644 index 000000000..5fac540ba --- /dev/null +++ b/tests/integration/plugins/index.test.ts @@ -0,0 +1,12 @@ +import fs from 'node:fs'; +import { buildAndGetResults } from 'test-helper'; +import { expect, test } from 'vitest'; +import { distIndex } from './rslib.config'; + +test('should run shared plugins only once', async () => { + const fixturePath = __dirname; + await buildAndGetResults({ fixturePath }); + + const content = fs.readFileSync(distIndex, 'utf-8'); + expect(content).toEqual('count: 1'); +}); diff --git a/tests/integration/plugins/package.json b/tests/integration/plugins/package.json new file mode 100644 index 000000000..e89a7a76b --- /dev/null +++ b/tests/integration/plugins/package.json @@ -0,0 +1,6 @@ +{ + "name": "plugins-test", + "version": "1.0.0", + "private": true, + "type": "module" +} diff --git a/tests/integration/plugins/rslib.config.ts b/tests/integration/plugins/rslib.config.ts new file mode 100644 index 000000000..cba12e767 --- /dev/null +++ b/tests/integration/plugins/rslib.config.ts @@ -0,0 +1,21 @@ +import fs from 'node:fs'; +import path from 'node:path'; +import type { RsbuildPlugin } from '@rsbuild/core'; +import { defineConfig } from '@rslib/core'; + +let count = 0; +export const distIndex = path.resolve(__dirname, 'dist/count.txt'); + +const testPlugin: RsbuildPlugin = { + name: 'test', + setup(api) { + api.onAfterBuild(() => { + fs.writeFileSync(distIndex, `count: ${++count}`); + }); + }, +}; + +export default defineConfig({ + lib: [{ format: 'esm' }, { format: 'cjs' }], + plugins: [testPlugin], +}); diff --git a/tests/integration/plugins/src/index.ts b/tests/integration/plugins/src/index.ts new file mode 100644 index 000000000..54cc258f8 --- /dev/null +++ b/tests/integration/plugins/src/index.ts @@ -0,0 +1 @@ +export const test = 'hello';