Skip to content

Commit

Permalink
fix: hmr failed when adding initial chunk (#2743)
Browse files Browse the repository at this point in the history
  • Loading branch information
SoonIter committed Jul 5, 2024
1 parent 5ebc802 commit 40d9f3f
Show file tree
Hide file tree
Showing 5 changed files with 106 additions and 0 deletions.
17 changes: 17 additions & 0 deletions e2e/cases/lazy-compilation/add-initial-chunk/index.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { dev, gotoPage, rspackOnlyTest } from '@e2e/helper';
import { expect } from '@playwright/test';

// https://github.com/web-infra-dev/rspack/issues/6633
rspackOnlyTest(
'should render pages correctly when using lazy compilation and add new initial chunk',
async ({ page }) => {
const rsbuild = await dev({
cwd: __dirname,
});

await gotoPage(page, rsbuild);
await expect(page.locator('#test')).toHaveText('Hello World!');

rsbuild.close();
},
);
41 changes: 41 additions & 0 deletions e2e/cases/lazy-compilation/add-initial-chunk/rsbuild.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { defineConfig } from '@rsbuild/core';
import { pluginReact } from '@rsbuild/plugin-react';

export default defineConfig({
plugins: [pluginReact()],
source: {
entry: {
index: './src/index.js',
},
},
tools: {
rspack(config) {
config.output ??= {};
config.output.asyncChunks = false;
},
},
performance: {
chunkSplit: {
strategy: 'custom',
override: {
chunks: 'all',
cacheGroups: {
lib: {
enforce: true,
test: /(initial\.js|core-js)/,
name: 'lib',
chunks: 'all',
},
default: false,
defaultVendors: false,
},
},
},
},
dev: {
lazyCompilation: true,
},
output: {
polyfill: 'usage',
},
});
7 changes: 7 additions & 0 deletions e2e/cases/lazy-compilation/add-initial-chunk/src/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import x from './initial';
import 'core-js';

const ele = document.createElement('div');
ele.innerHTML = `Hello ${x}`;
ele.setAttribute('id', 'test');
document.body.append(ele);
3 changes: 3 additions & 0 deletions e2e/cases/lazy-compilation/add-initial-chunk/src/initial.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import 'core-js/package.json';

export default 'World!';
38 changes: 38 additions & 0 deletions packages/core/src/server/socketServer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,19 @@ interface ExtWebSocket extends Ws {
isAlive: boolean;
}

function isEqualSet(a: Set<string>, b: Set<string>): boolean {
if (a.size !== b.size) {
return false;
}

for (const v of a.values()) {
if (!b.has(v)) {
return false;
}
}
return true;
}

export class SocketServer {
private wsServer!: Ws.Server;

Expand All @@ -17,6 +30,7 @@ export class SocketServer {
private readonly options: DevConfig;

private stats?: Stats;
private initialChunks?: Set<string>;

private timer: ReturnType<typeof setInterval> | null = null;

Expand Down Expand Up @@ -151,6 +165,7 @@ export class SocketServer {
errors: true,
errorsCount: true,
errorDetails: false,
entrypoints: true,
children: true,
};

Expand All @@ -166,6 +181,29 @@ export class SocketServer {
return null;
}

// web-infra-dev/rspack#6633
// when initial-chunks change, reload the page
// e.g: ['index.js'] -> ['index.js', 'lib-polyfill.js']
const newInitialChunks: Set<string> = new Set();
if (stats.entrypoints) {
for (const entrypoint of Object.values(stats.entrypoints)) {
const chunks = entrypoint.chunks;
if (Array.isArray(chunks)) {
for (const chunkName of chunks) {
chunkName && newInitialChunks.add(chunkName);
}
}
}
}
const shouldReload =
Boolean(stats.entrypoints) &&
Boolean(this.initialChunks) &&
!isEqualSet(this.initialChunks as Set<string>, newInitialChunks);
this.initialChunks = newInitialChunks;
if (shouldReload) {
return this.sockWrite('content-changed');
}

const shouldEmit =
!force &&
stats &&
Expand Down

0 comments on commit 40d9f3f

Please sign in to comment.