Repository navigation
fix(cjs): build a CommonJS re-export of an ES module inside a cycle - #23090
Conversation
Since webpack#22276 the re-export declares a nested `__esModule`, so its export owns a nested exports info that redirects to the required module's. In a cycle, merging it through the redirect marked the target as providing `__esModule`, and two such infos made `setHasUseInfo` recurse forever. Merge a spec's names into the nested info it owns, and stop `setHasUseInfo` at a redirect, as `_resetUsedExports` does.
|
|
🦋 Changeset detectedLatest commit: 07c80d6 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
|
No actionable comments were generated in the recent review.
|
| Layer / File(s) | Summary |
|---|---|
Namespace re-export cycle handling lib/graph/ExportsInfo.js, test/configCases/cjs-tree-shaking/namespace-reexport-cycle/* |
setHasUseInfo no longer follows a redirect when initializing use information. Regression cases check direct and binding-mediated namespace cycles, including exported keys and the back-reference. |
ES module export merge handling lib/optimize/FlagDependencyExportsPlugin.js, test/configCases/cjs-tree-shaking/reexport-esm-cycle/*, .changeset/050-commonjs-reexport-esm-cycle.md |
mergeExports now uses the module’s own export info for each export name. The regression case checks the exported value and the CommonJS re-export’s __esModule flag. A patch changeset describes the cycle build failure. |
Suggested labels: area: optimization, regression
Suggested reviewers: alexander-akait
Change: Bug fix · Severity of issue fixed: Medium
Merge Risk: 
Minimal · up to 07c80
-
The change fixes production-build failures for cyclic CommonJS and ES module re-exports, and adds regression tests for both reported cases. No remaining concrete risk was identified in the supplied context.
Pre-merge checks: 
3 · 
1
-
Failed checks: 1 inconclusive Passed checks: 3 passed-
Full details: Linked Issues check
-
Explanation
For
#23088,ExportsInfo.setHasUseInfonow stops before_redirectTowhen a redirect exists, which prevents recursive use-info initialization in redirect cycles.FlagDependencyExportsPluginnow callsgetOwnExportInfo(name), which prevents nested export analysis from marking the redirected target as providing__esModule. The new production config cases cover both cyclic patterns. They assert the namespace identity and__esModule === true, and assert the1:truere-export result.
Full details: Out of Scope Changes check
-
Explanation
The changes remain within
#23088. The two library changes address the reported export-info and redirect-cycle failures. The added config cases reproduce both issue patterns. The changeset documents the fix and does not add unrelated behavior.
-
Full details: Title check
-
Explanation
The title uses the required Conventional Commit form,
fix(cjs): subject, and accurately describes the CommonJS/ES module cycle fix. The branch prefix is not provided, so the required type-to-branch-prefix match cannot be verified.Resolution
Provide the branch name or confirm that its prefix is
fix.
-
- Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.
|
Reported by Module Loading #95 for 07c80d6, computed by this pull request's own code. Module loadingHow many files a fresh Node.js process loads (
|
|
Reported by Types Coverage #2851 for 07c80d6, computed by this pull request's own code. Types CoverageTyped lines: 99.50% (167113 of 167945)
Escape hatches count the raw types they stand for too: This pull request adds or removes no escape-hatch type or inferred 107 file(s) in
|
| File | Typed lines | EXPECTED_ANY |
EXPECTED_OBJECT |
EXPECTED_FUNCTION |
unknown |
inferred any |
|---|---|---|---|---|---|---|
declarations/WebpackOptions.ts |
99.94% | 15 | ||||
lib/javascript/syntax-parser.js |
99.96% | 14 | ||||
lib/hmr/JavascriptHotModuleReplacement.runtime.js |
100.00% | 2 | 7 | |||
lib/util/cleverMerge.js |
100.00% | 1 | 8 | |||
lib/javascript/syntax-printer.js |
99.99% | 1 | 6 | 1 | ||
lib/serialization/ObjectMiddleware.js |
99.79% | 3 | 4 | |||
lib/Compiler.js |
100.00% | 2 | 4 | |||
lib/hmr/HotModuleReplacement.runtime.js |
100.00% | 1 | 5 | |||
lib/serialization/SerializerMiddleware.js |
100.00% | 3 | 3 | |||
lib/util/SourceProcessor.js |
100.00% | 6 | ||||
lib/Compilation.js |
99.77% | 5 | ||||
lib/define/DefinePlugin.js |
100.00% | 1 | 4 | |||
lib/loaders/LoaderOptionsPlugin.js |
90.63% | 5 | ||||
lib/module/NormalModule.js |
99.54% | 4 | 1 | |||
lib/resolve/getResolveOptionsKey.js |
100.00% | 1 | 4 | |||
lib/config/normalization.js |
99.14% | 4 | ||||
lib/debug/ProfilingPlugin.js |
100.00% | 4 | ||||
lib/module/Module.js |
99.51% | 4 | ||||
lib/performance/HotspotsPlugin.js |
100.00% | 4 | ||||
lib/util/SortableSet.js |
100.00% | 4 | ||||
lib/css/syntax-parser.js |
99.90% | 3 | ||||
lib/html/syntax-parser.js |
99.98% | 3 | ||||
lib/stats/StatsFactory.js |
96.99% | 2 | 1 | |||
lib/util/WeakTupleMap.js |
100.00% | 3 | ||||
lib/config/defineConfig.js |
100.00% | 2 | ||||
lib/css/syntax.js |
100.00% | 2 | ||||
lib/graph/ModuleGraph.js |
100.00% | 1 | 1 | |||
lib/html/syntax.js |
100.00% | 2 | ||||
lib/loaders/LoaderRunner.js |
97.70% | 2 | ||||
lib/module/Parser.js |
100.00% | 2 | ||||
lib/node/nodeConsole.js |
100.00% | 2 | ||||
lib/config/cli.js |
99.73% | 1 | ||||
lib/dependencies/import/ImportParserPlugin.js |
100.00% | 1 | ||||
lib/dll/DllReferencePlugin.js |
100.00% | 1 | ||||
lib/errors/NonErrorEmittedError.js |
100.00% | 1 | ||||
lib/errors/WebpackError.js |
100.00% | 1 | ||||
lib/hmr/HotModuleReplacementPlugin.js |
100.00% | 1 | ||||
lib/index.js |
100.00% | 1 | ||||
lib/javascript/JavascriptParser.js |
100.00% | 1 | ||||
lib/javascript/syntax.js |
100.00% | 1 | ||||
lib/logging/Logger.js |
100.00% | 1 | ||||
lib/optimize/TupleQueue.js |
100.00% | 1 | ||||
lib/output/CopyPlugin.js |
100.00% | 1 | ||||
lib/output/ManifestPlugin.js |
100.00% | 1 | ||||
lib/rules/BasicEffectRulePlugin.js |
100.00% | 1 | ||||
lib/rules/RuleSetCompiler.js |
99.73% | 1 | ||||
lib/serialization/types.js |
100.00% | 1 | ||||
lib/stats/DefaultStatsFactoryPlugin.js |
99.87% | 1 | ||||
lib/stats/StatsPrinter.js |
99.11% | 1 | ||||
lib/template/Template.js |
100.00% | 1 | ||||
lib/util/TupleSet.js |
100.00% | 1 | ||||
lib/util/identifier.js |
100.00% | 1 | ||||
lib/util/magicComment.js |
100.00% | 1 | ||||
lib/util/makeSerializable.js |
100.00% | 1 | ||||
lib/util/terminalColors.js |
100.00% | 1 | ||||
lib/util/validateSchema.js |
100.00% | 1 | ||||
lib/MultiCompiler.js |
99.74% | |||||
lib/asset/AssetBytesParser.js |
91.67% | |||||
lib/asset/AssetModulesPlugin.js |
99.38% | |||||
lib/asset/AssetParser.js |
96.15% | |||||
lib/asset/AssetSourceParser.js |
91.67% | |||||
lib/cache/PackFileCacheStrategy.js |
99.23% | |||||
lib/config/validateSchema.js |
94.67% | |||||
lib/css/CssGenerator.js |
99.65% | |||||
lib/css/conventions.js |
98.68% | |||||
lib/css/syntax-printer.js |
99.73% | |||||
lib/dependencies/amd/AMDPlugin.js |
99.31% | |||||
lib/dependencies/amd/AMDRuntimeModules.js |
95.45% | |||||
lib/dependencies/commonjs/CommonJsExportsParserPlugin.js |
99.79% | |||||
lib/dependencies/esm/ESMExportInitFragment.js |
99.35% | |||||
lib/dependencies/html/HtmlEntryDependency.js |
99.83% | |||||
lib/dependencies/import-meta/ImportMetaPlugin.js |
99.63% | |||||
lib/devtool/ModuleFilenameHelpers.js |
99.47% | |||||
lib/devtool/SourceMapDevToolPlugin.js |
99.78% | |||||
lib/errors/CacheEffectivenessWarning.js |
93.75% | |||||
lib/externals/ExternalModule.js |
99.87% | |||||
lib/fs/FileSystemInfo.js |
99.96% | |||||
lib/hmr/HotModuleReplacementChunkVersionCheckRuntimeModule.js |
87.50% | |||||
lib/hmr/HotModuleReplacementRuntimeModule.js |
77.78% | |||||
lib/hmr/JavascriptHotModuleReplacementHelper.js |
91.30% | |||||
lib/hmr/lazyCompilationBackend.js |
99.07% | |||||
lib/html/HtmlGenerator.js |
99.87% | |||||
lib/html/HtmlModulesPlugin.js |
99.51% | |||||
lib/javascript/JavascriptMetaInfoPlugin.js |
98.44% | |||||
lib/json/JsonParser.js |
96.88% | |||||
lib/loaders/LoaderPlugin.js |
99.42% | |||||
lib/logging/createConsoleLogger.js |
99.00% | |||||
lib/module/NormalModuleFactory.js |
98.34% | |||||
lib/optimize/ConcatenatedModule.js |
99.89% | |||||
lib/optimize/LazyBucketSortedSet.js |
96.85% | |||||
lib/optimize/SideEffectsFlagPlugin.js |
99.84% | |||||
lib/performance/UnusedDefinesPlugin.js |
96.97% | |||||
lib/performance/UnusedExternalsPlugin.js |
95.35% | |||||
lib/runtime/MakeDeferredNamespaceObjectRuntime.js |
99.65% | |||||
lib/schemes/HttpUriPlugin.js |
99.87% | |||||
lib/serialization/BinaryMiddleware.js |
99.27% | |||||
lib/sharing/semver.js |
99.55% | |||||
lib/stats/DefaultStatsPrinterPlugin.js |
99.88% | |||||
lib/template/RuntimeTemplate.js |
99.95% | |||||
lib/util/async.js |
97.62% | |||||
lib/util/createMappings.js |
98.45% | |||||
lib/util/globUtils.js |
99.83% | |||||
lib/util/registerExternalSerializer.js |
98.31% | |||||
lib/util/serialization.js |
98.68% | |||||
lib/wasm-sync/WebAssemblyParser.js |
98.94% | |||||
lib/wasm/AsyncWebAssemblyParser.js |
97.83% | |||||
lib/webpack.js |
98.62% |
|
Reported by Code Size #6461 for 07c80d6, computed by this pull request's own code. Generated code sizeComparing base (
Read Sample appsNo sample app changed size. 26 unchanged app(s)
No asset that both runs emit changed size — everything below is new or deleted. 2 asset(s) this pull request adds
No runtime that both runs build changed which runtime modules it carries. 2 runtime(s) this pull request adds or no longer builds
Built |
Merging this PR will not alter performance1 warning, 1 note
Comparing |
|
This PR is packaged and the instant preview of its latest commit is available. Install it locally:
npm i -D webpack@https://pkg.pr.new/webpack@23090
yarn add -D webpack@https://pkg.pr.new/webpack@23090
pnpm add -D webpack@https://pkg.pr.new/webpack@23090 |
Summary
Fixes #23088.
Since #22276 (5.112.0), a CommonJS re-export of an ES module owns a nested exports info (for
__esModule) that also redirects to the required module's. In a cycle this breaks production builds:export * asof a CommonJS module re-exporting the namespaceRangeError: Maximum call stack size exceededCannot get final name for export '__esModule'FlagDependencyExportsPluginmerged nested names through the redirect, marking__esModuleprovided on the target module. It now usesgetOwnExportInfo.ExportsInfo#setHasUseInfofollowed redirects into each other's module forever. It now stops at a redirect, as_resetUsedExportsdoes.What kind of change does this PR introduce?
fix
Did you add tests for your changes?
Yes: the
namespace-reexport-cycleandreexport-esm-cyclecases undercjs-tree-shaking. Each fails in both config suites without its part of the fix.Does this PR introduce a breaking change?
No.
If relevant, what needs to be documented once your changes are merged or what have you already documented?
n/a
Use of AI
No.
Summary by CodeRabbit