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
5 changes: 5 additions & 0 deletions .changeset/rspack-hmr-for-ssr-dev.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"rsbuild-plugin-react-router": patch
---

Enable Rspack HMR for ESM server outputs by not forcing `dev.hmr=false` in the React Router plugin.
2 changes: 0 additions & 2 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1078,8 +1078,6 @@ export const pluginReactRouter = (
},
dev: {
writeToDisk: true,

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

While removing hmr: false and liveReload: true is the correct change to enable HMR, the tests have not been updated. The test should configure basic plugin options in tests/index.test.ts will now fail because it asserts that hmr is false. Please update the tests to reflect that these options now use Rsbuild's defaults.

hmr: false,
liveReload: true,
// Only add SSR middleware if SSR is enabled and not using a custom server
// In SPA mode (ssr: false), we just serve static files from the client build
setupMiddlewares:
Expand Down
3 changes: 2 additions & 1 deletion tests/features.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ describe('pluginReactRouter', () => {
rsbuild.addPlugins([pluginReactRouter()]);
const config = await rsbuild.unwrapConfig();

expect(config.dev.hmr).toBe(false);
// The plugin should not override Rsbuild's HMR defaults.
expect(config.dev.hmr).toBe(true);
expect(config.dev.liveReload).toBe(true);
expect(config.dev.writeToDisk).toBe(true);
});
Expand Down
3 changes: 2 additions & 1 deletion tests/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ describe('pluginReactRouter', () => {
rsbuild.addPlugins([pluginReactRouter()]);
const config = await rsbuild.unwrapConfig();

expect(config.dev.hmr).toBe(false);
// The plugin should not override Rsbuild's HMR defaults.
expect(config.dev.hmr).toBe(true);
expect(config.dev.liveReload).toBe(true);
expect(config.dev.writeToDisk).toBe(true);
});
Expand Down
54 changes: 49 additions & 5 deletions tests/setup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,11 @@ rstest.mock('@scripts/test-helper', () => ({
createStubRsbuild: rstest.fn().mockImplementation(async ({ rsbuildConfig = {} } = {}) => {
const baseConfig = {
dev: {
hmr: false,
// Match Rsbuild defaults so plugin changes are observable in tests.
// (Historically the plugin forced `hmr: false` / `liveReload: true`.)
hmr: true,
liveReload: true,
writeToDisk: true,
writeToDisk: false,
setupMiddlewares: [],
},
environments: {
Expand Down Expand Up @@ -98,17 +100,24 @@ rstest.mock('@scripts/test-helper', () => ({
],
};

const mergedConfig = deepMerge(baseConfig, rsbuildConfig);
let mergedConfig = deepMerge(baseConfig, rsbuildConfig);

return {
const mergeRsbuildConfig = (a: any, b: any) => deepMerge(a, b);
const pending: Promise<unknown>[] = [];

const stub: any = {
addPlugins: rstest.fn(),
unwrapConfig: rstest.fn().mockResolvedValue(mergedConfig),
unwrapConfig: rstest.fn(),
processAssets: rstest.fn(),
onBeforeStartDevServer: rstest.fn(),
onBeforeBuild: rstest.fn(),
onAfterBuild: rstest.fn(),
getNormalizedConfig: rstest.fn().mockImplementation(() => mergedConfig),
modifyRsbuildConfig: rstest.fn(),
onAfterEnvironmentCompile: rstest.fn(),
// Keep as a spy-only hook; tests in this repo assert against the merged
// Rsbuild config (modifyRsbuildConfig), not post-normalization environment
// mutations.
modifyEnvironmentConfig: rstest.fn(),
transform: rstest.fn(),
logger: {
Expand All @@ -118,6 +127,7 @@ rstest.mock('@scripts/test-helper', () => ({
},
context: {
rootPath: '/Users/bytedance/dev/rsbuild-plugin-react-router',
action: 'dev',
},
compiler: {
webpack: {
Expand All @@ -127,5 +137,39 @@ rstest.mock('@scripts/test-helper', () => ({
},
},
};

stub.modifyRsbuildConfig.mockImplementation((arg: any) => {
const handler = typeof arg === 'function' ? arg : arg?.handler;
if (typeof handler !== 'function') return;

const res = handler(mergedConfig, { mergeRsbuildConfig });
if (res && typeof res.then === 'function') {
const p = res.then((next: any) => {
if (next) mergedConfig = next;
return next;
});
pending.push(p);
return p;
}
if (res) mergedConfig = res;
return res;
});

// In Rsbuild, `addPlugins()` triggers plugin setup before config is read.
stub.addPlugins.mockImplementation((next: any[]) => {
for (const plugin of next) {
if (typeof plugin?.setup === 'function') {
// Tests do not await `addPlugins`, so ensure `unwrapConfig` waits for setup.
pending.push(Promise.resolve(plugin.setup(stub)));
}
}
});

stub.unwrapConfig.mockImplementation(async () => {
await Promise.all(pending);
return mergedConfig;
});

return stub;
}),
}));
Loading