Skip to content

Commit 0b8ef22

Browse files
authored
Merge pull request #10344 from webpack/bugfix/hang-circular-reexport
fix hanging build when using circular export *
2 parents 627510d + 614ea54 commit 0b8ef22

File tree

6 files changed

+55
-8
lines changed

6 files changed

+55
-8
lines changed

lib/FlagDependencyExportsPlugin.js

Lines changed: 33 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,9 @@
77
const Queue = require("./util/Queue");
88

99
const addToSet = (a, b) => {
10-
const size = a.size;
1110
for (const item of b) {
1211
a.add(item);
1312
}
14-
return a.size !== size;
1513
};
1614

1715
class FlagDependencyExportsPlugin {
@@ -58,14 +56,11 @@ class FlagDependencyExportsPlugin {
5856
// break if it should move to the worst state
5957
if (exports === true) {
6058
module.buildMeta.providedExports = true;
61-
notifyDependencies();
6259
return true;
6360
}
6461
// merge in new exports
6562
if (Array.isArray(exports)) {
66-
if (addToSet(moduleProvidedExports, exports)) {
67-
notifyDependencies();
68-
}
63+
addToSet(moduleProvidedExports, exports);
6964
}
7065
// store dependencies
7166
const exportDeps = exportDesc.dependencies;
@@ -93,6 +88,26 @@ class FlagDependencyExportsPlugin {
9388
}
9489
};
9590

91+
const notifyDependenciesIfDifferent = (set, array) => {
92+
const deps = dependencies.get(module);
93+
if (deps !== undefined) {
94+
if (set.size === array.length) {
95+
let i = 0;
96+
let different = false;
97+
for (const item of set) {
98+
if (item !== array[i++]) {
99+
different = true;
100+
break;
101+
}
102+
}
103+
if (!different) return;
104+
}
105+
for (const dep of deps) {
106+
queue.enqueue(dep);
107+
}
108+
}
109+
};
110+
96111
// Start with all modules without provided exports
97112
for (const module of modules) {
98113
if (module.buildInfo.temporaryProvidedExports) {
@@ -116,9 +131,20 @@ class FlagDependencyExportsPlugin {
116131
processDependenciesBlock(module);
117132
module.buildInfo.temporaryProvidedExports = providedExportsAreTemporary;
118133
if (!moduleWithExports) {
134+
notifyDependencies();
119135
module.buildMeta.providedExports = true;
136+
} else if (module.buildMeta.providedExports === true) {
137+
notifyDependencies();
138+
} else if (!module.buildMeta.providedExports) {
120139
notifyDependencies();
121-
} else if (module.buildMeta.providedExports !== true) {
140+
module.buildMeta.providedExports = Array.from(
141+
moduleProvidedExports
142+
);
143+
} else {
144+
notifyDependenciesIfDifferent(
145+
moduleProvidedExports,
146+
module.buildMeta.providedExports
147+
);
122148
module.buildMeta.providedExports = Array.from(
123149
moduleProvidedExports
124150
);

lib/dependencies/HarmonyExportImportedSpecifierDependency.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -304,9 +304,13 @@ class HarmonyExportImportedSpecifierDependency extends HarmonyImportDependency {
304304
}
305305

306306
if (Array.isArray(importedModule.buildMeta.providedExports)) {
307+
const activeFromOtherStarExports = this._discoverActiveExportsFromOtherStartExports();
307308
return {
308309
exports: importedModule.buildMeta.providedExports.filter(
309-
id => id !== "default"
310+
id =>
311+
id !== "default" &&
312+
!activeFromOtherStarExports.has(id) &&
313+
!this.activeExports.has(id)
310314
),
311315
dependencies: [importedModule]
312316
};
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
export * from "./c";
2+
export const a = "a";
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
export * from "./a";
2+
export const b = "b";
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
export * from "./b";
2+
export const c = "c";
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import * as all from "./c";
2+
3+
it("should contain all exports", () => {
4+
expect(all).toEqual(
5+
nsObj({
6+
a: "a",
7+
b: "b",
8+
c: "c"
9+
})
10+
);
11+
});

0 commit comments

Comments
 (0)