Skip to content

Commit d86e18d

Browse files
revert back to async reduce pattern in serve lifecycle for dev server serve and intercept related resource plugin processing
1 parent 170cae6 commit d86e18d

File tree

1 file changed

+30
-21
lines changed

1 file changed

+30
-21
lines changed

packages/cli/src/lifecycles/serve.js

Lines changed: 30 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -59,13 +59,8 @@ async function getDevServer(compilation) {
5959
let response = new Response(null, { status });
6060

6161
for (const plugin of resourcePlugins) {
62-
// ignore plugins that serve pages, as those will be handled by Greenwood's standard HTML plugin
63-
if (
64-
!plugin.servePage &&
65-
plugin.shouldServe &&
66-
(await plugin.shouldServe(url, request, response.clone()))
67-
) {
68-
const current = await plugin.serve(url, request, response.clone());
62+
if (!plugin.servePage && plugin.shouldServe && (await plugin.shouldServe(url, request))) {
63+
const current = await plugin.serve(url, request);
6964
const merged = mergeResponse(response.clone(), current.clone());
7065

7166
response = merged.clone();
@@ -98,17 +93,26 @@ async function getDevServer(compilation) {
9893
headers: new Headers(header),
9994
});
10095

101-
let response = initResponse;
102-
for (const plugin of resourcePlugins) {
96+
// we explicitly use "async" reduce here to avoid race conditions / Body consumed errors
97+
// when looping through and sharing responses between plugins
98+
const response = await resourcePlugins.reduce(async (responsePromise, plugin) => {
99+
const intermediateResponse = await responsePromise;
103100
if (
104101
plugin.shouldPreIntercept &&
105-
(await plugin.shouldPreIntercept(url, request, response.clone()))
102+
(await plugin.shouldPreIntercept(url, request, intermediateResponse.clone()))
106103
) {
107-
const current = await plugin.preIntercept(url, request, response.clone());
108-
109-
response = mergeResponse(response.clone(), current.clone());
104+
const current = await plugin.preIntercept(
105+
url,
106+
request,
107+
await intermediateResponse.clone(),
108+
);
109+
const merged = mergeResponse(intermediateResponse.clone(), current);
110+
111+
return Promise.resolve(merged);
112+
} else {
113+
return Promise.resolve(await responsePromise);
110114
}
111-
}
115+
}, Promise.resolve(initResponse.clone()));
112116

113117
ctx.body = response.body ? Readable.from(response.body) : "";
114118
ctx.message = response.statusText;
@@ -135,17 +139,22 @@ async function getDevServer(compilation) {
135139
headers: new Headers(header),
136140
});
137141

138-
let response = initResponse;
139-
for (const plugin of resourcePlugins) {
142+
// we explicitly use "async" reduce here to avoid race conditions / Body consumed errors
143+
// when looping through and sharing responses between plugins
144+
const response = await resourcePlugins.reduce(async (responsePromise, plugin) => {
145+
const intermediateResponse = await responsePromise;
140146
if (
141147
plugin.shouldIntercept &&
142-
(await plugin.shouldIntercept(url, request, response.clone()))
148+
(await plugin.shouldIntercept(url, request, intermediateResponse.clone()))
143149
) {
144-
const current = await plugin.intercept(url, request, response.clone());
150+
const current = await plugin.intercept(url, request, await intermediateResponse.clone());
151+
const merged = mergeResponse(intermediateResponse.clone(), current);
145152

146-
response = mergeResponse(response.clone(), current.clone());
153+
return Promise.resolve(merged);
154+
} else {
155+
return Promise.resolve(await responsePromise);
147156
}
148-
}
157+
}, Promise.resolve(initResponse.clone()));
149158

150159
ctx.body = response.body ? Readable.from(response.body) : "";
151160
ctx.message = response.statusText;
@@ -174,7 +183,7 @@ async function getDevServer(compilation) {
174183
statusText: message,
175184
status,
176185
headers: new Headers(header),
177-
});
186+
}).clone();
178187
const splitResponse = response.clone();
179188
const contents = await splitResponse.text();
180189
const inm = ctx.headers["if-none-match"];

0 commit comments

Comments
 (0)