Skip to content

Commit bfc36c4

Browse files
authored
Merge pull request #78 from unstubbable/webpack-race-conditions
Prevent race conditions during webpack compilation
2 parents 97c58bd + 247f98c commit bfc36c4

File tree

2 files changed

+49
-28
lines changed

2 files changed

+49
-28
lines changed

.changeset/selfish-beans-jump.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@mfng/webpack-rsc': patch
3+
---
4+
5+
Prevent race conditions during webpack compilation

packages/webpack-rsc/src/webpack-rsc-server-plugin.ts

Lines changed: 44 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -131,31 +131,46 @@ export class WebpackRscServerPlugin {
131131
});
132132
};
133133

134+
let needsAdditionalPass = false;
135+
134136
compiler.hooks.finishMake.tapPromise(
135137
WebpackRscServerPlugin.name,
136138
async (compilation) => {
137139
this.serverManifest = {};
140+
const clientReferences = [...this.clientReferencesMap.keys()];
141+
const serverReferences = [...this.serverReferencesMap.keys()];
142+
const referencesBefore = [...clientReferences, ...serverReferences];
138143

139144
await Promise.all([
140-
...Array.from(this.clientReferencesMap.keys()).map(
141-
async (resource) => {
142-
try {
143-
await includeModule(compilation, resource);
144-
} catch (error) {
145-
this.clientReferencesMap.delete(resource);
146-
}
147-
},
148-
),
149-
...Array.from(this.serverReferencesMap.keys()).map(
150-
async (resource) => {
151-
try {
152-
await includeModule(compilation, resource, webpackRscLayerName);
153-
} catch (error) {
154-
this.serverReferencesMap.delete(resource);
155-
}
156-
},
157-
),
145+
...clientReferences.map(async (resource) => {
146+
try {
147+
await includeModule(compilation, resource);
148+
} catch (error) {
149+
this.clientReferencesMap.delete(resource);
150+
}
151+
}),
152+
...serverReferences.map(async (resource) => {
153+
try {
154+
await includeModule(compilation, resource, webpackRscLayerName);
155+
} catch (error) {
156+
this.serverReferencesMap.delete(resource);
157+
}
158+
}),
158159
]);
160+
161+
const referencesAfter = [
162+
...this.clientReferencesMap.keys(),
163+
...this.serverReferencesMap.keys(),
164+
];
165+
166+
if (
167+
referencesBefore.length !== referencesAfter.length ||
168+
!referencesAfter.every((reference) =>
169+
referencesBefore.includes(reference),
170+
)
171+
) {
172+
needsAdditionalPass = true;
173+
}
159174
},
160175
);
161176

@@ -191,16 +206,12 @@ export class WebpackRscServerPlugin {
191206
return;
192207
}
193208

194-
if (module.layer === webpackRscLayerName) {
195-
if (isClientModule) {
196-
void includeModule(compilation, resource).catch(() => {
197-
this.clientReferencesMap.delete(resource);
198-
});
199-
}
200-
201-
if (isServerModule && !hasServerReferenceDependency(module)) {
202-
module.addDependency(new ServerReferenceDependency());
203-
}
209+
if (
210+
module.layer === webpackRscLayerName &&
211+
isServerModule &&
212+
!hasServerReferenceDependency(module)
213+
) {
214+
module.addDependency(new ServerReferenceDependency());
204215
}
205216
});
206217

@@ -226,6 +237,11 @@ export class WebpackRscServerPlugin {
226237
.for(`javascript/esm`)
227238
.tap(`HarmonyModulesPlugin`, onNormalModuleFactoryParser);
228239

240+
compilation.hooks.needAdditionalPass.tap(
241+
WebpackRscServerPlugin.name,
242+
() => !(needsAdditionalPass = !needsAdditionalPass),
243+
);
244+
229245
compilation.hooks.afterOptimizeModuleIds.tap(
230246
WebpackRscServerPlugin.name,
231247
(modules) => {

0 commit comments

Comments
 (0)