Skip to content

Commit b3e0776

Browse files
authored
Merge pull request #331 from webpack/fix/yield-in-plugins
fix yield
2 parents b6468e0 + 06deca9 commit b3e0776

File tree

12 files changed

+472
-42
lines changed

12 files changed

+472
-42
lines changed

lib/AliasFieldPlugin.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,10 @@ module.exports = class AliasFieldPlugin {
6060
...request,
6161
path: false
6262
};
63+
if (typeof resolveContext.yield === "function") {
64+
resolveContext.yield(ignoreObj);
65+
return callback(null, null);
66+
}
6367
return callback(null, ignoreObj);
6468
}
6569
const obj = {

lib/AliasPlugin.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
const forEachBail = require("./forEachBail");
99

1010
/** @typedef {import("./Resolver")} Resolver */
11+
/** @typedef {import("./Resolver").ResolveRequest} ResolveRequest */
1112
/** @typedef {import("./Resolver").ResolveStepHook} ResolveStepHook */
1213
/** @typedef {{alias: string|Array<string>|false, name: string, onlyModule?: boolean}} AliasOption */
1314

@@ -45,10 +46,15 @@ module.exports = class AliasPlugin {
4546
const remainingRequest = innerRequest.substr(item.name.length);
4647
const resolveWithAlias = (alias, callback) => {
4748
if (alias === false) {
49+
/** @type {ResolveRequest} */
4850
const ignoreObj = {
4951
...request,
5052
path: false
5153
};
54+
if (typeof resolveContext.yield === "function") {
55+
resolveContext.yield(ignoreObj);
56+
return callback(null, null);
57+
}
5258
return callback(null, ignoreObj);
5359
}
5460
if (

lib/Resolver.js

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -275,11 +275,16 @@ class Resolver {
275275

276276
let yield_;
277277
let yieldCalled = false;
278+
let finishYield;
278279
if (typeof resolveContext.yield === "function") {
279280
const old = resolveContext.yield;
280281
yield_ = obj => {
281-
yieldCalled = true;
282282
old(obj);
283+
yieldCalled = true;
284+
};
285+
finishYield = result => {
286+
if (result) yield_(result);
287+
callback(null);
283288
};
284289
}
285290

@@ -329,8 +334,8 @@ class Resolver {
329334
(err, result) => {
330335
if (err) return callback(err);
331336

337+
if (yieldCalled || (result && yield_)) return finishYield(result);
332338
if (result) return finishResolved(result);
333-
if (yieldCalled) return callback(null);
334339

335340
return finishWithoutResolve(log);
336341
}
@@ -353,8 +358,8 @@ class Resolver {
353358
(err, result) => {
354359
if (err) return callback(err);
355360

361+
if (yieldCalled || (result && yield_)) return finishYield(result);
356362
if (result) return finishResolved(result);
357-
if (yieldCalled) return callback(null);
358363

359364
// log is missing for the error details
360365
// so we redo the resolving for the log info
@@ -372,11 +377,11 @@ class Resolver {
372377
yield: yield_,
373378
stack: resolveContext.stack
374379
},
375-
err => {
380+
(err, result) => {
376381
if (err) return callback(err);
377382

378383
// In a case that there is a race condition and yield will be called
379-
if (yieldCalled) return callback(null);
384+
if (yieldCalled || (result && yield_)) return finishYield(result);
380385

381386
return finishWithoutResolve(log);
382387
}

lib/UnsafeCachePlugin.js

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,9 @@
1010
/** @typedef {import("./Resolver").ResolveStepHook} ResolveStepHook */
1111
/** @typedef {{[k: string]: any}} Cache */
1212

13-
function getCacheId(request, withContext) {
13+
function getCacheId(type, request, withContext) {
1414
return JSON.stringify({
15+
type,
1516
context: withContext ? request.context : "",
1617
path: request.path,
1718
query: request.query,
@@ -46,18 +47,49 @@ module.exports = class UnsafeCachePlugin {
4647
.getHook(this.source)
4748
.tapAsync("UnsafeCachePlugin", (request, resolveContext, callback) => {
4849
if (!this.filterPredicate(request)) return callback();
49-
const cacheId = getCacheId(request, this.withContext);
50+
const isYield = typeof resolveContext.yield === "function";
51+
const cacheId = getCacheId(
52+
isYield ? "yield" : "default",
53+
request,
54+
this.withContext
55+
);
5056
const cacheEntry = this.cache[cacheId];
5157
if (cacheEntry) {
58+
if (isYield) {
59+
const yield_ = /** @type {Function} */ (resolveContext.yield);
60+
if (Array.isArray(cacheEntry)) {
61+
for (const result of cacheEntry) yield_(result);
62+
} else {
63+
yield_(cacheEntry);
64+
}
65+
return callback(null, null);
66+
}
5267
return callback(null, cacheEntry);
5368
}
69+
70+
let yieldFn;
71+
let yield_;
72+
const yieldResult = [];
73+
if (isYield) {
74+
yieldFn = resolveContext.yield;
75+
yield_ = result => {
76+
yieldResult.push(result);
77+
};
78+
}
79+
5480
resolver.doResolve(
5581
target,
5682
request,
5783
null,
58-
resolveContext,
84+
yield_ ? { ...resolveContext, yield: yield_ } : resolveContext,
5985
(err, result) => {
6086
if (err) return callback(err);
87+
if (isYield) {
88+
if (result) yieldResult.push(result);
89+
for (const result of yieldResult) yieldFn(result);
90+
this.cache[cacheId] = yieldResult;
91+
return callback(null, null);
92+
}
6193
if (result) return callback(null, (this.cache[cacheId] = result));
6294
callback();
6395
}

test/fixtures/yield/a/foo-2/b

Whitespace-only changes.

test/fixtures/yield/a/foo-2/c

Whitespace-only changes.

test/fixtures/yield/a/foo/a

Whitespace-only changes.

test/fixtures/yield/a/foo/b

Whitespace-only changes.

test/fixtures/yield/b/foo/a

Whitespace-only changes.

test/fixtures/yield/c/foo/a

Whitespace-only changes.

0 commit comments

Comments
 (0)