Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions e2e/cases/module-federation/v1-without-entry/index.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { expect, rspackTest } from '@e2e/helper';

rspackTest('should start MF app in dev without entry', async ({ devOnly }) => {
await expect(devOnly()).resolves.toBeTruthy();
});

rspackTest('should build MF app without entry', async ({ build }) => {
await expect(build()).resolves.toBeTruthy();
});
25 changes: 25 additions & 0 deletions e2e/cases/module-federation/v1-without-entry/rsbuild.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { defineConfig } from '@rsbuild/core';
import { pluginReact } from '@rsbuild/plugin-react';

export default defineConfig({
plugins: [pluginReact()],
moduleFederation: {
options: {
name: 'remote',
exposes: {
'./Button': './src/Button',
},
filename: 'remoteEntry.js',
shared: {
react: {
singleton: true,
requiredVersion: '^19.0.0',
},
'react-dom': {
singleton: true,
requiredVersion: '^19.0.0',
},
},
},
},
});
5 changes: 5 additions & 0 deletions e2e/cases/module-federation/v1-without-entry/src/Button.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export const Button = () => (
<button type="button" id="button">
Button
</button>
);
9 changes: 9 additions & 0 deletions e2e/cases/module-federation/v2-without-entry/index.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { expect, rspackTest } from '@e2e/helper';

rspackTest('should start MF app in dev without entry', async ({ devOnly }) => {
await expect(devOnly()).resolves.toBeTruthy();
});

rspackTest('should build MF app without entry', async ({ build }) => {
await expect(build()).resolves.toBeTruthy();
});
16 changes: 16 additions & 0 deletions e2e/cases/module-federation/v2-without-entry/rsbuild.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { pluginModuleFederation } from '@module-federation/rsbuild-plugin';
import { defineConfig } from '@rsbuild/core';
import { pluginReact } from '@rsbuild/plugin-react';

export default defineConfig({
plugins: [
pluginReact(),
pluginModuleFederation({
name: 'remote',
exposes: {
'./Button': './src/Button',
},
shared: ['react', 'react-dom'],
}),
],
});
5 changes: 5 additions & 0 deletions e2e/cases/module-federation/v2-without-entry/src/Button.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export const Button = () => (
<button type="button" id="button">
Button
</button>
);
33 changes: 28 additions & 5 deletions packages/core/src/plugins/entry.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { castArray, color, createVirtualModule } from '../helpers';
import type { RsbuildEntryDescription, RsbuildPlugin } from '../types';
import { castArray, color, createVirtualModule, isObject } from '../helpers';
import type { RsbuildEntryDescription, RsbuildPlugin, Rspack } from '../types';

export const pluginEntry = (): RsbuildPlugin => ({
name: 'rsbuild:entry',
Expand Down Expand Up @@ -32,16 +32,39 @@ export const pluginEntry = (): RsbuildPlugin => ({
}
});

api.onBeforeCreateCompiler(({ bundlerConfigs }) => {
if (bundlerConfigs.every((config) => !config.entry)) {
// Check missing entry config
api.onBeforeCreateCompiler({
order: 'post',
handler: ({ bundlerConfigs }) => {
const hasEntry = bundlerConfigs.some((config) => config.entry);
if (hasEntry) {
return;
}

const isModuleFederationPlugin = (plugin: Rspack.Plugin) =>
isObject(plugin) &&
plugin.constructor.name === 'ModuleFederationPlugin';

const hasModuleFederation = bundlerConfigs.some(({ plugins }) =>
plugins?.some(isModuleFederationPlugin),
);

// Allow entry to be left empty when module federation is enabled
if (hasModuleFederation) {
bundlerConfigs.forEach((config) => {
config.entry = {};
});
return;
}

throw new Error(
`${color.dim('[rsbuild:config]')} Could not find any entry module, please make sure that ${color.yellow(
'src/index.(ts|js|tsx|jsx|mts|cts|mjs|cjs)',
)} exists, or customize entry through the ${color.yellow(
'source.entry',
)} configuration.`,
);
}
},
});
},
});
Loading