diff --git a/lib/FlagDependencyExportsPlugin.js b/lib/FlagDependencyExportsPlugin.js index c376c1c5309..72231dfd2f1 100644 --- a/lib/FlagDependencyExportsPlugin.js +++ b/lib/FlagDependencyExportsPlugin.js @@ -7,11 +7,9 @@ const Queue = require("./util/Queue"); const addToSet = (a, b) => { - const size = a.size; for (const item of b) { a.add(item); } - return a.size !== size; }; class FlagDependencyExportsPlugin { @@ -58,14 +56,11 @@ class FlagDependencyExportsPlugin { // break if it should move to the worst state if (exports === true) { module.buildMeta.providedExports = true; - notifyDependencies(); return true; } // merge in new exports if (Array.isArray(exports)) { - if (addToSet(moduleProvidedExports, exports)) { - notifyDependencies(); - } + addToSet(moduleProvidedExports, exports); } // store dependencies const exportDeps = exportDesc.dependencies; @@ -93,6 +88,26 @@ class FlagDependencyExportsPlugin { } }; + const notifyDependenciesIfDifferent = (set, array) => { + const deps = dependencies.get(module); + if (deps !== undefined) { + if (set.size === array.length) { + let i = 0; + let different = false; + for (const item of set) { + if (item !== array[i++]) { + different = true; + break; + } + } + if (!different) return; + } + for (const dep of deps) { + queue.enqueue(dep); + } + } + }; + // Start with all modules without provided exports for (const module of modules) { if (module.buildInfo.temporaryProvidedExports) { @@ -116,9 +131,20 @@ class FlagDependencyExportsPlugin { processDependenciesBlock(module); module.buildInfo.temporaryProvidedExports = providedExportsAreTemporary; if (!moduleWithExports) { + notifyDependencies(); module.buildMeta.providedExports = true; + } else if (module.buildMeta.providedExports === true) { + notifyDependencies(); + } else if (!module.buildMeta.providedExports) { notifyDependencies(); - } else if (module.buildMeta.providedExports !== true) { + module.buildMeta.providedExports = Array.from( + moduleProvidedExports + ); + } else { + notifyDependenciesIfDifferent( + moduleProvidedExports, + module.buildMeta.providedExports + ); module.buildMeta.providedExports = Array.from( moduleProvidedExports ); diff --git a/lib/dependencies/HarmonyExportImportedSpecifierDependency.js b/lib/dependencies/HarmonyExportImportedSpecifierDependency.js index 15429b6ed75..2a03b08b52b 100644 --- a/lib/dependencies/HarmonyExportImportedSpecifierDependency.js +++ b/lib/dependencies/HarmonyExportImportedSpecifierDependency.js @@ -304,9 +304,13 @@ class HarmonyExportImportedSpecifierDependency extends HarmonyImportDependency { } if (Array.isArray(importedModule.buildMeta.providedExports)) { + const activeFromOtherStarExports = this._discoverActiveExportsFromOtherStartExports(); return { exports: importedModule.buildMeta.providedExports.filter( - id => id !== "default" + id => + id !== "default" && + !activeFromOtherStarExports.has(id) && + !this.activeExports.has(id) ), dependencies: [importedModule] }; diff --git a/test/cases/parsing/harmony-circular-star-reexport/a.js b/test/cases/parsing/harmony-circular-star-reexport/a.js new file mode 100644 index 00000000000..30b80e3ad6f --- /dev/null +++ b/test/cases/parsing/harmony-circular-star-reexport/a.js @@ -0,0 +1,2 @@ +export * from "./c"; +export const a = "a"; diff --git a/test/cases/parsing/harmony-circular-star-reexport/b.js b/test/cases/parsing/harmony-circular-star-reexport/b.js new file mode 100644 index 00000000000..87071dcdfde --- /dev/null +++ b/test/cases/parsing/harmony-circular-star-reexport/b.js @@ -0,0 +1,2 @@ +export * from "./a"; +export const b = "b"; diff --git a/test/cases/parsing/harmony-circular-star-reexport/c.js b/test/cases/parsing/harmony-circular-star-reexport/c.js new file mode 100644 index 00000000000..516ea7f8834 --- /dev/null +++ b/test/cases/parsing/harmony-circular-star-reexport/c.js @@ -0,0 +1,2 @@ +export * from "./b"; +export const c = "c"; diff --git a/test/cases/parsing/harmony-circular-star-reexport/index.js b/test/cases/parsing/harmony-circular-star-reexport/index.js new file mode 100644 index 00000000000..2f8b0d40433 --- /dev/null +++ b/test/cases/parsing/harmony-circular-star-reexport/index.js @@ -0,0 +1,11 @@ +import * as all from "./c"; + +it("should contain all exports", () => { + expect(all).toEqual( + nsObj({ + a: "a", + b: "b", + c: "c" + }) + ); +});