From 4dd7d6f688d40a2df5dcd4c0ff730a28eaf59bdf Mon Sep 17 00:00:00 2001 From: Daniel Nalborczyk Date: Fri, 18 Feb 2022 20:07:51 -0500 Subject: [PATCH 1/6] refactor: use map for namespace reexports by name --- src/Module.ts | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/src/Module.ts b/src/Module.ts index f36ef51d5a3..a99d2937587 100644 --- a/src/Module.ts +++ b/src/Module.ts @@ -235,10 +235,10 @@ export default class Module { private readonly exportShimVariable: ExportShimVariable = new ExportShimVariable(this); private readonly exports = new Map(); private declare magicString: MagicString; - private namespaceReexportsByName: Record< + private readonly namespaceReexportsByName = new Map< string, [variable: Variable | null, indirectExternal?: boolean] - > = Object.create(null); + >(); private readonly reexportDescriptions = new Map(); private relevantDependencies: Set | null = null; private readonly syntheticExports = new Map(); @@ -580,14 +580,13 @@ export default class Module { if (name !== 'default') { const foundNamespaceReexport = - name in this.namespaceReexportsByName - ? this.namespaceReexportsByName[name] - : this.getVariableFromNamespaceReexports( - name, - importerForSideEffects, - searchedNamesAndModules - ); - this.namespaceReexportsByName[name] = foundNamespaceReexport; + this.namespaceReexportsByName.get(name) ?? + this.getVariableFromNamespaceReexports( + name, + importerForSideEffects, + searchedNamesAndModules + ); + this.namespaceReexportsByName.set(name, foundNamespaceReexport); if (foundNamespaceReexport[0]) { return foundNamespaceReexport; } From ca62cb37b8373bfa6461f734afecc6487cca46cc Mon Sep 17 00:00:00 2001 From: Daniel Nalborczyk Date: Fri, 18 Feb 2022 20:11:45 -0500 Subject: [PATCH 2/6] remove explicit type assignment --- src/Module.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Module.ts b/src/Module.ts index a99d2937587..1425558656d 100644 --- a/src/Module.ts +++ b/src/Module.ts @@ -232,7 +232,7 @@ export default class Module { private readonly exportAllModules: (Module | ExternalModule)[] = []; private readonly exportAllSources = new Set(); private exportNamesByVariable: Map | null = null; - private readonly exportShimVariable: ExportShimVariable = new ExportShimVariable(this); + private readonly exportShimVariable = new ExportShimVariable(this); private readonly exports = new Map(); private declare magicString: MagicString; private readonly namespaceReexportsByName = new Map< From 8619e1cb9d1d7e4e4a0ea184caa21b2b8d2fb6f3 Mon Sep 17 00:00:00 2001 From: Daniel Nalborczyk Date: Fri, 18 Feb 2022 20:18:22 -0500 Subject: [PATCH 3/6] refactor: remove variable, use context property directly --- src/Module.ts | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/Module.ts b/src/Module.ts index 1425558656d..765e187fde4 100644 --- a/src/Module.ts +++ b/src/Module.ts @@ -380,7 +380,8 @@ export default class Module { getDependenciesToBeIncluded(): Set { if (this.relevantDependencies) return this.relevantDependencies; - const relevantDependencies = new Set(); + + this.relevantDependencies = new Set(); const necessaryDependencies = new Set(); const alwaysCheckedDependencies = new Set(); const dependencyVariables = new Set(this.imports); @@ -414,19 +415,19 @@ export default class Module { } if (!this.options.treeshake || this.info.moduleSideEffects === 'no-treeshake') { for (const dependency of this.dependencies) { - relevantDependencies.add(dependency); + this.relevantDependencies.add(dependency); } } else { this.addRelevantSideEffectDependencies( - relevantDependencies, + this.relevantDependencies, necessaryDependencies, alwaysCheckedDependencies ); } for (const dependency of necessaryDependencies) { - relevantDependencies.add(dependency); + this.relevantDependencies.add(dependency); } - return (this.relevantDependencies = relevantDependencies); + return this.relevantDependencies; } getExportNamesByVariable(): Map { From f7434c3453969463d600ca56ed974fc930764888 Mon Sep 17 00:00:00 2001 From: Daniel Nalborczyk Date: Fri, 18 Feb 2022 20:23:28 -0500 Subject: [PATCH 4/6] refactor: remove unnecessary array assignment --- src/Module.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/Module.ts b/src/Module.ts index 765e187fde4..2b0ca3bc5d6 100644 --- a/src/Module.ts +++ b/src/Module.ts @@ -464,8 +464,6 @@ export default class Module { if (this.transitiveReexports) { return this.transitiveReexports; } - // to avoid infinite recursion when using circular `export * from X` - this.transitiveReexports = []; const reexports = new Set(this.reexportDescriptions.keys()); From 81f03a6ce838a31e84bc739dfa09a3108fcb3dcd Mon Sep 17 00:00:00 2001 From: Lukas Taegert-Atkinson Date: Mon, 21 Feb 2022 11:38:12 +0100 Subject: [PATCH 5/6] Add test for recursive reexports --- .../samples/recursive-reexports/_config.js | 15 +++++++++++++++ test/function/samples/recursive-reexports/main.js | 2 ++ .../function/samples/recursive-reexports/other.js | 2 ++ 3 files changed, 19 insertions(+) create mode 100644 test/function/samples/recursive-reexports/_config.js create mode 100644 test/function/samples/recursive-reexports/main.js create mode 100644 test/function/samples/recursive-reexports/other.js diff --git a/test/function/samples/recursive-reexports/_config.js b/test/function/samples/recursive-reexports/_config.js new file mode 100644 index 00000000000..1e1ce84b159 --- /dev/null +++ b/test/function/samples/recursive-reexports/_config.js @@ -0,0 +1,15 @@ +const assert = require('assert'); +module.exports = { + description: 'handles recursive namespace reexports', + exports(exports) { + assert.deepStrictEqual(exports, { main: 'main', other: 'other' }); + }, + warnings: [ + { + code: 'CIRCULAR_DEPENDENCY', + cycle: ['main.js', 'other.js', 'main.js'], + importer: 'main.js', + message: 'Circular dependency: main.js -> other.js -> main.js' + } + ] +}; diff --git a/test/function/samples/recursive-reexports/main.js b/test/function/samples/recursive-reexports/main.js new file mode 100644 index 00000000000..aa89b491fd7 --- /dev/null +++ b/test/function/samples/recursive-reexports/main.js @@ -0,0 +1,2 @@ +export * from './other.js'; +export const main = 'main'; diff --git a/test/function/samples/recursive-reexports/other.js b/test/function/samples/recursive-reexports/other.js new file mode 100644 index 00000000000..3c111285103 --- /dev/null +++ b/test/function/samples/recursive-reexports/other.js @@ -0,0 +1,2 @@ +export * from './main.js'; +export const other = 'other'; From a3dca3e2cc8b66a180161b13c4715cc5874363f4 Mon Sep 17 00:00:00 2001 From: Daniel Nalborczyk Date: Mon, 21 Feb 2022 20:53:54 -0500 Subject: [PATCH 6/6] Revert "refactor: remove unnecessary array assignment" This reverts commit f7434c3453969463d600ca56ed974fc930764888. --- src/Module.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Module.ts b/src/Module.ts index dcc94b6dc34..0ce3ef4e39b 100644 --- a/src/Module.ts +++ b/src/Module.ts @@ -464,6 +464,8 @@ export default class Module { if (this.transitiveReexports) { return this.transitiveReexports; } + // to avoid infinite recursion when using circular `export * from X` + this.transitiveReexports = []; const reexports = new Set(this.reexportDescriptions.keys());