next.js
c53bbe21 - Turbopack: propagate late partial namespace provenance to passthrough targets (#100444)

Commit
16 days ago
Turbopack: propagate late partial namespace provenance to passthrough targets (#100444) ### What? Namespace provenance from a late partial-namespace read now reaches the module's passthrough targets, even when that module was already processed with `All` usage or with the same names. ### Why? `compute_binding_usage_info` tracks modules read through a namespace value (`namespace_object_may_escape`). Export-name mangling uses this to keep original names. Passthrough edges such as `export * from './y'` forward that provenance to their target. Take a module that was reached first through a plain named or `All` edge, so its passthrough edge has already run. If a partial-namespace edge for it arrives later and adds no new export names, the module joins the provenance set but the visitor reports no change. It is never revisited, so its passthrough target stays out of the set. ### How? Direct partial-namespace edges now count adding the target to the provenance set as a change, the same way the passthrough branch already does. The export-usage merge still always runs. Each module can only be added to the set once, so this triggers at most one extra revisit per module and the fixed point still terminates. New `turbopack-core` graph tests build a small module graph with explicit edge usages and check the result directly. In the graph, `x` re-exports `y` through a passthrough edge, and `x` is reached by both a short path and a longer path. The tests cover: - the plain usage of `x` being `All` or an already-used name - the namespace read arriving on the longer path (the failing case) or on the shorter path (a control) Without this fix, the two late cases mark `x` but leave `y` out of the provenance set; all four pass with it. The new execution test `turbopack/exports/mangle-late-namespace-passthrough` reproduces the bug with real module analysis and codegen. A barrel (`export * from './source'`) is reached early by named imports from the entry, and later by a narrowed dynamic import (`webpackExports`) that sits a few modules deeper and uses no new names. The test disables `followReexports` so the named imports target the barrel instead of resolving straight to the source. It also disables `mangleViaMaterializedNamespaceObject` so the dynamic import reads the barrel itself, not a namespace facade. Without the fix, the source export is wrongly marked mangleable (`canMangle: true`). The values still read correctly in this fixture, so the test checks the mangling decision through `__webpack_exports_info__`. ### Verification - `cargo test -p turbopack-core --lib` - `cargo test -p turbopack-tests --test snapshot` (no snapshot changes) - `cargo test -p turbopack-tests --test execution`, including the new test, which fails without the fix - `cargo clippy -p turbopack-core --tests` <!-- NEXT_JS_LLM --> <!-- fleet c860b76b-981c-4d9b-a802-f28b0545c8a7 --> --------- Co-authored-by: vercel-fleet-prod[bot] <318278635+vercel-fleet-prod[bot]@users.noreply.github.com> Co-authored-by: Tobias Koppers <1365881+sokra@users.noreply.github.com> Co-authored-by: Niklas Mischkulnig <4586894+mischnic@users.noreply.github.com>
Author
Parents
Loading