fix(generate): keep JSON namespace interface under preserveModules#10028
Conversation
…ce import A JSON module imported as a namespace (`import * as ns`) keeps every top-level key materialized — the finalizer only inlines keys when the module namespace object is NOT included (`need_inline_json_prop`). The #10020 filter, which dropped any key absent from `json_module_none_self_reference_included_symbol`, also removed those still-materialized keys from the preserved chunk's exports, so `import("./dist/data.js")` no longer exposed them. Mirror the finalizer's full inlining condition: only drop a key when JSON property inlining is actually active (ESM exports, and the namespace object not included). A namespace-imported JSON chunk now re-exports its complete interface.
How to use the Graphite Merge QueueAdd the label graphite: merge-when-ready to this PR to add it to the merge queue. You must have a Graphite account in order to use the merge queue. Sign up using this link. An organization admin has enabled the Graphite Merge Queue in this repository. Please do not merge from GitHub as this will restart CI on PRs being processed by the merge queue. This stack of pull requests is managed by Graphite. Learn more about stacking. |
Merging this PR will not alter performance
Comparing Footnotes
|
Merge activity
|

What
Builds on the parent PR (#10020). A JSON module imported as a namespace (
import * as ns from './x.json') keeps every top-level key materialized — the finalizer only inlines JSON keys when the module namespace object is not included (need_inline_json_prop, seefinalizer_context.rs).The reason this PR exists is purely to keep the stack consistent: the parent PR's #10020 narrowing (skip keys absent from
json_module_none_self_reference_included_symbol) is too coarse for the namespace case — those keys are absent from that set yet still materialized, so the parent PR alone would drop them:Fix
Mirror the finalizer's full inlining condition rather than the key-set alone: only drop a key when JSON property inlining is actually active — JSON, ESM exports, and the namespace object not included. The stack's net behavior then matches
mainfor the namespace case.Test
crates/rolldown/tests/rolldown/misc/preserve_modules/json_namespace_preserves_exports:import * asa JSON module under preserveModules and assert (via_test.mjs) thatimport('./dist/data.js')re-exposes every top-level key plusdefault. Verified: passes onmain, fails on the parent PR alone, passes here.