Skip to content

fix(code-splitting): retain initialization paths through re-exported namespaces - #11037

Merged
graphite-app[bot] merged 1 commit into
mainfrom
fix/issue-11033-namespace-init
Sep 30, 2026
Merged

graphite-app[bot] merged 1 commit into
mainfrom
fix/issue-11033-namespace-init

Conversation

@hyfdev

@hyfdev hyfdev commented Sep 30, 2026 •

Copy link
Copy Markdown
Member

With strictExecutionOrder: true, re-exported namespace members can remain undefined because their module initializers are never called. This fix preserves their initialization paths so the members are ready when consumers read them.

Before:

[typeof Reorder.Group, typeof Reorder.Item]; // ["undefined", "undefined"]

After:

[typeof Reorder.Group, typeof Reorder.Item]; // ["object", "object"]

The failing shape combines an outer export * with a retained local export, and an inner namespace import that is re-exported. When Reorder.Group is folded into a direct binding reference, the recorded initialization path loses the forwarding steps leading to the namespace. The outer module's initializer then fails to reach the leaf modules.

Linking records the forwarding prefix and resolved member hops as one retained path, keyed by the final binding. The path also includes the re-exported namespace import's own record, allowing the outer wrapper to reach the leaf initializers.

Validation:

  • The new regression fixture fails on the base commit in wrap-all mode. Fixed output passes wrap-all and on-demand wrapping, each with and without minification.
  • The original Motion reproduction passes with both strict modes, minification on/off, and all six story load orders.
  • cargo test -p rolldown, Clippy, formatting checks, and just build-rolldown pass.

Fixes #11033

@netlify

netlify Bot commented Sep 30, 2026 •

Copy link
Copy Markdown

✅ Deploy Preview for rolldown-rs canceled.

Name Link
🔨 Latest commit f87cf80
🔍 Latest deploy log https://app.netlify.com/projects/rolldown-rs/deploys/6abc9b0a2ec10900086e79ca

@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Sep 30, 2026 •

Copy link
Copy Markdown

🚀 Deploying Preview to Cloudflare 🚀

Preview URL: https://fix-issue-11033-namespace-init-rolldown-rs.voidzero-docs.workers.dev (commit f87cf80)

This URL reflects your latest Preview deployment

Preview Deployments by commit

Status Deployment URL Commit Updated (UTC) See this deployment's details
  • Build: Success ✅
  • Deployment: Success ✅

View logs ↗
https://f730e3b5-rolldown-rs.voidzero-docs.workers.dev f87cf80 2026-09-30T05:18:55.978Z Visit the dashboard ↗
  • Build: Success ✅
  • Deployment: Success ✅

View logs ↗
https://b5934fb7-rolldown-rs.voidzero-docs.workers.dev e8b835f 2026-09-30T03:19:46.074Z Visit the dashboard ↗

@hyfdev
hyfdev marked this pull request as ready for review September 30, 2026 03:32
Copilot AI balanced review requested due to automatic review settings September 30, 2026 03:32

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@codspeed

codspeed Bot commented Sep 30, 2026

Copy link
Copy Markdown

Merging this PR will not alter performance

✅ 7 untouched benchmarks
⏩ 10 skipped benchmarks1


Comparing fix/issue-11033-namespace-init (e8b835f) with main (b082026)

Open in CodSpeed

Footnotes

  1. 10 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports. ↩

shulaoda commented Sep 30, 2026 •

Copy link
Copy Markdown
Member

Merge activity

  • Sep 30, 5:15 AM UTC: The merge label 'graphite: merge-when-ready' was detected. This PR will be added to the Graphite merge queue once it meets the requirements.
  • Sep 30, 5:15 AM UTC: shulaoda added this pull request to the Graphite merge queue.
  • Sep 30, 5:20 AM UTC: Merged by the Graphite merge queue.

…namespaces (#11037)

With `strictExecutionOrder: true`, re-exported namespace members can remain `undefined` because their module initializers are never called. This fix preserves their initialization paths so the members are ready when consumers read them.

Before:
```js
[typeof Reorder.Group, typeof Reorder.Item]; // ["undefined", "undefined"]
```

After:
```js
[typeof Reorder.Group, typeof Reorder.Item]; // ["object", "object"]
```

The failing shape combines an outer `export *` with a retained local export, and an inner namespace import that is re-exported. When `Reorder.Group` is folded into a direct binding reference, the recorded initialization path loses the forwarding steps leading to the namespace. The outer module's initializer then fails to reach the leaf modules.

Linking records the forwarding prefix and resolved member hops as one retained path, keyed by the final binding. The path also includes the re-exported namespace import's own record, allowing the outer wrapper to reach the leaf initializers.

Validation:

- The new regression fixture fails on the base commit in wrap-all mode. Fixed output passes wrap-all and on-demand wrapping, each with and without minification.
- The original Motion reproduction passes with both strict modes, minification on/off, and all six story load orders.
- `cargo test -p rolldown`, Clippy, formatting checks, and `just build-rolldown` pass.

Fixes #11033
@graphite-app
graphite-app Bot force-pushed the fix/issue-11033-namespace-init branch from e8b835f to f87cf80 Compare September 30, 2026 05:15
@graphite-app
graphite-app Bot merged commit f87cf80 into main Sep 30, 2026
37 checks passed
@graphite-app
graphite-app Bot deleted the fix/issue-11033-namespace-init branch September 30, 2026 05:20
hyfdev added a commit that referenced this pull request Sep 30, 2026
Follow-up to #11037.

Add three `strictExecutionOrder` fixtures for a namespace re-exported
behind an `export *` hop:

- `export_star_reexported_namespace_opaque_read`: the consumer uses the
namespace as a value, so no member read is folded. It fails on the
commit before #11037 in wrap-all mode.
- `export_star_as_namespace_folded_member`: the barrel forwards the
namespace with `export * as`, whose import record carries
`IsReExportOnly`. It fails on the commit before #11037 in wrap-all mode.
- `issues/11033_side_effect_free_package`: the leaves live in a package
marked `sideEffects: false` and are built by top-level calls, so
on-demand wrapping wraps them as well. This is the shape of the `motion`
package in #11033. It fails on the commit before #11037 in both wrap-all
and on-demand wrapping; `issues/11033` fails there only in wrap-all
mode.

Two comments that name `record_star_reexport_path` as the sole recorder
of retained star paths are restated; the namespace-member loop in
`resolve_member_expr_refs` records them too.
hyfdev added a commit that referenced this pull request Sep 30, 2026
…ment (#11039)

Follow-up to #11037.

A statically resolved namespace-member read (`ns.member` through a
namespace-valued binding) records its forwarding hops as a
`MemberReadStarReexportPath` that carries the reading statement and the
resolved binding. `collect_frozen_reexport_usage` retains the path only
while that statement is included and the binding is used.

On `main` the path is keyed by the resolved binding alone. A direct
import of the leaf in another module marks the binding used, so the
outer wrapper's forwarding stays alive even when the module reading
`ns.member` is tree-shaken: the outer wrapper's `init_*` calls the leaf
initializer, and its chunk imports the leaf's chunk.

Before, `other.js` chunk with the reader tree-shaken and `Group`
imported directly by another dynamic entry:

```js
import { r as init_group } from "./direct.js";
// ...
function init_react() {
	return (init_react = __esmMin((() => {
		init_motion();
		init_group();
		motion = motion$1;
	})))();
}
```

After:

```js
function init_react() {
	return (init_react = __esmMin((() => {
		init_motion();
		motion = motion$1;
	})))();
}
```

`export_star_reexported_namespace_dead_reader` pins the gate: on `main`
its `other.js` chunk gains the `init_group` import above.

Validation: `cargo test -p rolldown`, Clippy, formatting checks, and
`just build-rolldown` pass. The reproduction from #11033 passes with
both wrapping modes, with and without minification, and with its three
stories loaded in every order.
@rolldown-guard rolldown-guard Bot mentioned this pull request Sep 30, 2026
shulaoda added a commit that referenced this pull request Sep 30, 2026
## [1.2.12] - 2026-09-30

### 🚀 Features

- inline common chunks containing import() and deduplicate shared code in lazy chunks (#11034) by @hyfdev
- experimental `inlineCommonChunks` support (#10899) by @hyfdev
- dev: ship imported bindings for HMR partial accept (#10856) by @h-a-n-a

### 🐛 Bug Fixes

- chunking: re-derive chunk exec orders after the runtime leaves its host chunk (#11005) by @hyfdev
- code-splitting: gate member-read init paths on the reading statement (#11039) by @hyfdev
- code-splitting: retain initialization paths through re-exported namespaces (#11037) by @hyfdev
- dev: reject non-ESM output formats in dev mode (#11038) by @h-a-n-a
- dev: align `import.meta.hot.accept` deps with Vite (#10997) by @h-a-n-a
- dev: clear the resolver cache when a file is created or deleted (#10986) by @waltuov
- error: name the resolved specifier in unresolved import diagnostics (#11014) by @linyiru
- make entries-aware chunk merging deterministic (#11002) by @hyfdev
- watch: avoid restarting macOS watcher for unchanged paths (#10992) by @sep2

### 🚜 Refactor

- dev: ship the dev runtime entry as one file (#10998) by @h-a-n-a
- binding: remove `__internalForcePanic` (#10989) by @IWANABETHATGUY

### 📚 Documentation

- fix cloudflare preview builds (#10996) by @sapphi-red
- fix build config loader warning (#10994) by @sapphi-red
- deps: use Vite 8 (#10993) by @sapphi-red

### ⚡ Performance

- dev: only ship rows with dynamic edges in registerGraph (#11019) by @h-a-n-a

### 🧪 Testing

- code-splitting: cover more re-exported namespace shapes (#11042) by @hyfdev
- webcontainer: cover the WebContainer download fallback in plain Node (#10966) by @shulaoda
- dev: pin the runtime entry file layout that Vite serves (#10983) by @h-a-n-a

### ⚙️ Miscellaneous Tasks

- pin VOID_API_URL for the docs deploy (#11041) by @shulaoda
- opt into the WebContainer smoke test for napi bumps and loader changes (#10967) by @shulaoda
- deps: upgrade oxc to 0.152.0 (#11018) by @camc314
- deps: update rust crates (#11012) by @renovate[bot]
- deps: update npm packages (#11011) by @renovate[bot]
- deps: update crate-ci/typos action to v1.50.3 (#11023) by @renovate[bot]
- deps: update test262 submodule for tests (#11022) by @rolldown-guard[bot]
- deps: update rollup submodule for tests to v4.63.5 (#11021) by @rolldown-guard[bot]
- deps: update dependency vite-plus to v1 (#11017) by @renovate[bot]
- deps: update github actions (#11010) by @renovate[bot]
- remove `CLAUDE.md` (#10925) by @iiio2
- verify release debug info by matching file IDs (#10988) by @IWANABETHATGUY
- deps: update rollup submodule for tests to v4.63.4 (#10940) by @rolldown-guard[bot]

### ❤️ New Contributors

* @waltuov made their first contribution in [#10986](#10986)
* @linyiru made their first contribution in [#11014](#11014)
* @sep2 made their first contribution in [#10992](#10992)

Co-authored-by: shulaoda <165626830+shulaoda@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: strictExecutionOrder leaves motion's Reorder.Group / Reorder.Item undefined (regression in 1.2.1, not covered by #10694)

3 participants