Skip to content

Commit d771607

Browse files
committed
update
1 parent 0ec9199 commit d771607

File tree

5 files changed

+80
-51
lines changed

5 files changed

+80
-51
lines changed

lib/AsyncDependenciesBlock.js

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ const makeSerializable = require("./util/makeSerializable");
1616
/** @typedef {import("./serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
1717
/** @typedef {import("./util/Hash")} Hash */
1818

19-
/** @typedef {(ChunkGroupOptions & { entryOptions?: EntryOptions }) | string} GroupOptions */
19+
/** @typedef {(ChunkGroupOptions & { entryOptions?: EntryOptions } & { key?: string | boolean }) | string} GroupOptions */
2020

2121
class AsyncDependenciesBlock extends DependenciesBlock {
2222
/**
@@ -56,6 +56,33 @@ class AsyncDependenciesBlock extends DependenciesBlock {
5656
}
5757
}
5858

59+
/**
60+
* @returns {boolean} Whether to deduplicate to avoid circular references
61+
*/
62+
get circular() {
63+
if (this.groupOptions.key) {
64+
return false;
65+
}
66+
return true;
67+
}
68+
69+
/**
70+
* @returns {string} the identifier of the block
71+
*/
72+
identifier() {
73+
let identifier = `entry-${Boolean(this.groupOptions.entryOptions)}`;
74+
if (this.groupOptions.name) {
75+
identifier += `|${this.groupOptions.name}`;
76+
}
77+
if (this.request) {
78+
identifier += `|${this.request}`;
79+
}
80+
if (typeof this.groupOptions.key === "string") {
81+
identifier += `|${this.groupOptions.key}`;
82+
}
83+
return identifier;
84+
}
85+
5986
/**
6087
* @param {Hash} hash the hash used to track dependencies
6188
* @param {UpdateHashContext} context context

lib/ChunkGroup.js

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -364,11 +364,6 @@ class ChunkGroup {
364364
* @returns {boolean} returns true if entrypoint was added
365365
*/
366366
addAsyncEntrypoint(entrypoint) {
367-
// TODO: Should we handle self-import? e.g. new Worker(import.meta.url)
368-
// Handling it would cause a circular dependency warning
369-
if (entrypoint === /** @type {unknown} */ (this)) {
370-
return false;
371-
}
372367
const size = this._asyncEntrypoints.size;
373368
this._asyncEntrypoints.add(entrypoint);
374369
return size !== this._asyncEntrypoints.size;

lib/buildChunkGraph.js

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@ const { getEntryRuntime, mergeRuntime } = require("./util/runtime");
5050
* @property {number} postOrderIndex next post order index
5151
* @property {boolean} chunkLoading has a chunk loading mechanism
5252
* @property {boolean} asyncChunks create async chunks
53+
* @property {string} blockId is the block key
54+
* @property {boolean} circular Whether to deduplicate to avoid circular references
5355
*/
5456

5557
/**
@@ -361,6 +363,9 @@ const visitModules = (
361363
/** @type {NamedChunkGroup} */
362364
const namedAsyncEntrypoints = new Map();
363365

366+
/** @type {Map<string, ChunkGroupInfo>} */
367+
const idAsyncEntrypoints = new Map();
368+
364369
/** @type {Set<ChunkGroupInfo>} */
365370
const outdatedOrderIndexChunkGroups = new Set();
366371

@@ -390,6 +395,8 @@ const visitModules = (
390395
);
391396
/** @type {ChunkGroupInfo} */
392397
const chunkGroupInfo = {
398+
blockId: "",
399+
circular: false,
393400
initialized: false,
394401
chunkGroup,
395402
runtime,
@@ -502,7 +509,9 @@ const visitModules = (
502509
if (cgi === undefined) {
503510
const chunkName = (b.groupOptions && b.groupOptions.name) || b.chunkName;
504511
if (entryOptions) {
505-
cgi = namedAsyncEntrypoints.get(/** @type {string} */ (chunkName));
512+
cgi =
513+
namedAsyncEntrypoints.get(/** @type {string} */ (chunkName)) ||
514+
idAsyncEntrypoints.get(/** @type {string} */ (b.identifier()));
506515
if (!cgi) {
507516
entrypoint = compilation.addAsyncEntrypoint(
508517
entryOptions,
@@ -513,6 +522,8 @@ const visitModules = (
513522
maskByChunk.set(entrypoint.chunks[0], ZERO_BIGINT);
514523
entrypoint.index = nextChunkGroupIndex++;
515524
cgi = {
525+
blockId: b.identifier(),
526+
circular: b.circular,
516527
chunkGroup: entrypoint,
517528
initialized: false,
518529
runtime:
@@ -550,6 +561,12 @@ const visitModules = (
550561
(cgi)
551562
);
552563
}
564+
if (b.circular) {
565+
idAsyncEntrypoints.set(
566+
b.identifier(),
567+
/** @type {ChunkGroupInfo} */ (cgi)
568+
);
569+
}
553570
} else {
554571
entrypoint = /** @type {Entrypoint} */ (cgi.chunkGroup);
555572
// TODO merge entryOptions
@@ -592,6 +609,8 @@ const visitModules = (
592609
maskByChunk.set(c.chunks[0], ZERO_BIGINT);
593610
c.index = nextChunkGroupIndex++;
594611
cgi = {
612+
blockId: b.identifier(),
613+
circular: b.circular,
595614
initialized: false,
596615
chunkGroup: c,
597616
runtime: chunkGroupInfo.runtime,
@@ -668,7 +687,10 @@ const visitModules = (
668687
chunkGroupInfo: /** @type {ChunkGroupInfo} */ (cgi)
669688
}
670689
]);
671-
} else if (entrypoint !== undefined) {
690+
} else if (
691+
entrypoint !== undefined &&
692+
(chunkGroupInfo.circular || chunkGroupInfo.blockId !== b.identifier())
693+
) {
672694
chunkGroupInfo.chunkGroup.addAsyncEntrypoint(entrypoint);
673695
}
674696
};

lib/dependencies/WorkerPlugin.js

Lines changed: 24 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,6 @@ const WorkerDependency = require("./WorkerDependency");
4141
/** @typedef {import("../Dependency").DependencyLocation} DependencyLocation */
4242
/** @typedef {import("../Entrypoint").EntryOptions} EntryOptions */
4343
/** @typedef {import("../NormalModule")} NormalModule */
44-
/** @typedef {import("../Module")} Module */
4544
/** @typedef {import("../javascript/JavascriptParser")} JavascriptParser */
4645
/** @typedef {import("../javascript/JavascriptParser")} Parser */
4746
/** @typedef {import("../javascript/JavascriptParser").JavascriptParserState} JavascriptParserState */
@@ -114,9 +113,6 @@ class WorkerPlugin {
114113
new CreateScriptUrlDependency.Template()
115114
);
116115

117-
/** @type {WeakMap<Module, Record<string, AsyncDependenciesBlock>>} */
118-
const modBlockMap = new WeakMap();
119-
120116
/**
121117
* @param {JavascriptParser} parser the parser
122118
* @param {Expression} expr expression
@@ -374,51 +370,38 @@ class WorkerPlugin {
374370
entryOptions.name = options.name;
375371
}
376372

377-
if (!modBlockMap.has(parser.state.module)) {
378-
modBlockMap.set(parser.state.module, {});
379-
}
380-
// For the same URL, we try to reuse the same AsyncDependenciesBlock
381-
const key = `name(${entryOptions.name}), url(${url})`;
382-
const cache =
383-
/** @type {Record<string, AsyncDependenciesBlock>} */ (
384-
modBlockMap.get(parser.state.module)
373+
if (entryOptions.runtime === undefined) {
374+
const i = workerIndexMap.get(parser.state) || 0;
375+
workerIndexMap.set(parser.state, i + 1);
376+
const name = `${cachedContextify(
377+
parser.state.module.identifier()
378+
)}|${i}`;
379+
const hash = createHash(compilation.outputOptions.hashFunction);
380+
hash.update(name);
381+
const digest = hash.digest(compilation.outputOptions.hashDigest);
382+
entryOptions.runtime = digest.slice(
383+
0,
384+
compilation.outputOptions.hashDigestLength
385385
);
386-
if (!cache[key]) {
387-
if (entryOptions.runtime === undefined) {
388-
const i = workerIndexMap.get(parser.state) || 0;
389-
workerIndexMap.set(parser.state, i + 1);
390-
const name = `${cachedContextify(
391-
parser.state.module.identifier()
392-
)}|${i}`;
393-
const hash = createHash(compilation.outputOptions.hashFunction);
394-
hash.update(name);
395-
const digest = hash.digest(
396-
compilation.outputOptions.hashDigest
397-
);
398-
entryOptions.runtime = digest.slice(
399-
0,
400-
compilation.outputOptions.hashDigestLength
401-
);
402-
}
403-
const block = new AsyncDependenciesBlock({
404-
name: entryOptions.name,
405-
entryOptions: {
406-
chunkLoading: this._chunkLoading,
407-
wasmLoading: this._wasmLoading,
408-
...entryOptions
409-
}
410-
});
411-
block.loc = expr.loc;
412-
parser.state.module.addBlock(block);
413-
cache[key] = block;
414386
}
415-
const block = cache[key];
387+
388+
const block = new AsyncDependenciesBlock({
389+
name: entryOptions.name,
390+
key: url,
391+
entryOptions: {
392+
chunkLoading: this._chunkLoading,
393+
wasmLoading: this._wasmLoading,
394+
...entryOptions
395+
}
396+
});
397+
block.loc = expr.loc;
416398
const dep = new WorkerDependency(url, range, {
417399
publicPath: this._workerPublicPath,
418400
needNewUrl
419401
});
420402
dep.loc = /** @type {DependencyLocation} */ (expr.loc);
421403
block.addDependency(dep);
404+
parser.state.module.addBlock(block);
422405

423406
if (compilation.outputOptions.trustedTypes) {
424407
const dep = new CreateScriptUrlDependency(

types.d.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -461,16 +461,18 @@ declare class AsyncDependenciesBlock extends DependenciesBlock {
461461
| string
462462
| (RawChunkGroupOptions & { name?: null | string } & {
463463
entryOptions?: EntryOptions;
464-
}),
464+
} & { key?: string | boolean }),
465465
loc?: null | SyntheticDependencyLocation | RealDependencyLocation,
466466
request?: null | string
467467
);
468468
groupOptions: RawChunkGroupOptions & { name?: null | string } & {
469469
entryOptions?: EntryOptions;
470-
};
470+
} & { key?: string | boolean };
471471
loc?: null | SyntheticDependencyLocation | RealDependencyLocation;
472472
request?: null | string;
473473
chunkName?: null | string;
474+
get circular(): boolean;
475+
identifier(): string;
474476
module: any;
475477
}
476478
declare abstract class AsyncQueue<T, K, R> {

0 commit comments

Comments
 (0)