fix(dev/lazy): fix exports of lazy requests in lazy chunks#9249
Conversation
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. |
e7bd6bc to
739a535
Compare
0b49d58 to
35914c4
Compare
35914c4 to
852f962
Compare
d4233fa to
98e5569
Compare
852f962 to
7e39c60
Compare
3c07aa1 to
663a25f
Compare
7e39c60 to
817d34b
Compare
663a25f to
2a1a1bd
Compare
817d34b to
11bdba7
Compare
731e03d to
872b05f
Compare
2a1a1bd to
d32c3bc
Compare
872b05f to
db8a48f
Compare
d32c3bc to
e8e212e
Compare
e8e212e to
30cde67
Compare
db8a48f to
565a66a
Compare
65d51b3 to
ec35a9a
Compare
30cde67 to
4ce2b61
Compare
5ebe23c to
f544df9
Compare
b43e44f to
a3ce294
Compare
a3ce294 to
d0da050
Compare
639b2d7 to
e20e568
Compare
Merging this PR will not alter performance
Comparing Footnotes
|
e20e568 to
6bb09e0
Compare
d0da050 to
07da851
Compare
6bb09e0 to
f2ff2a6
Compare
❌ Deploy Preview for rolldown-rs failed.
|
Merge activity
|
## Summary
This PR fixes a case where dynamic imported chunks in lazy chunks are not able to fetch the correct exports.
Before:
```js
import(`/@vite/lazy?id=…&clientId=…`)
```
After:
```js
import(`/@vite/lazy?id=…&clientId=…`)
.then(() => __rolldown_runtime__.loadExports("<stable_proxy_id>"))
```
When a lazy chunk's body contains `import('./another-lazy.js')`, the HMR partial
bundle returned the raw chunk namespace (raw lazy chunk) instead of the registered proxy exports,
so `inner.foo` came back `undefined`.
In this PR, we intentionally skip loading the raw lazy chunk, instead,
we use `__rolldown_runtime__.loadExports(...)` to load real module exports.
## Test plan
- [x] `pnpm test:browser` — all 7 tests pass with the fix in place
- [x] New playground: `packages/test-dev-server/tests/playground/lazy-nested-dynamic-import/`
- [x] Reverted the fix locally → `pnpm test:browser -t 'lazy-nested-dynamic-import'` fails with
`inner.foo = UNDEFINED` / `inner.bar = UNDEFINED`
- [x] Restored the fix → test passes on first try (~135 ms, no retry)
- [x] `pnpm run lint-knip` clean for the new playground
f2ff2a6 to
4ab16d1
Compare
## [1.0.1] - 2026-05-13 ### 🚀 Features - experimental/lazy-barrel: advice on oversized barrel modules (#9236) by @shulaoda - rolldown: inline optional-chain enum access (#9379) by @Dunqing - chunk-optimization: dedupe already-loaded dynamic deps (#9305) by @IWANABETHATGUY - binding: call moduleParsed hook in ParallelJsPlugin (#9318) by @jaehafe ### 🐛 Bug Fixes - transform: enable `enum_eval` for `transformSync` and vite TS transform (#9325) by @Dunqing - error: remove severity prefix from diagnostic messages (#9262) by @Kyujenius - deps: pin pnpm to 10.23.0 to work around catalog mismatch on Netlify (#9364) by @shulaoda - ci: pin mimalloc-safe to 0.1.58 (#9361) by @shulaoda - dev/lazy: fix exports of lazy requests in lazy chunks (#9249) by @h-a-n-a - rolldown_plugin_vite_resolve: handle errors in `resolveSubpathImports` callback (#9355) by @sapphi-red - rolldown_plugin_lazy_compilation: use loadExports for fetched proxy to preserve original export names (#9132) by @h-a-n-a - common: include offending index in HybridIndexVec panic message (#9296) by @SAY-5 ### 🚜 Refactor - ecmascript: extract semantic_builder_for_transform helper (#9326) by @Dunqing - test: extract reusable static-import-cycle helper (#9332) by @IWANABETHATGUY ### 📚 Documentation - clarify scope of `topLevelVar` (#9380) by @IWANABETHATGUY - meta/design: add ast-mutation design doc (#9338) by @hyf0 - feat: add ai policy in contribution guide (#9315) by @mdong1909 ### ⚡ Performance - binding: enable mimalloc v3 to reduce idle memory (#9349) by @shulaoda ### 🧪 Testing - mcs: cover require() in `$initial` group (#9376) by @hyf0 - add regression for CJS facade chunk merge into entry (#9351) by @IWANABETHATGUY ### ⚙️ Miscellaneous Tasks - switch prepare-release to manual dispatch with version input (#9383) by @shulaoda - migrate `@rolldown/pluginutils` to `rolldown/plugins` (#9317) by @shulaoda - deps: pin libmimalloc-sys2 to 0.1.54 (#9372) by @shulaoda - replace `igorskyflyer/action-readfile` with `cat` (#9369) by @sapphi-red - deps: update test262 submodule for tests (#9371) by @rolldown-guard[bot] - use app token for test dep update PRs (#9368) by @sapphi-red - replace some actions with gh commands (#9367) by @sapphi-red - replace action-semantic-pull-request with inline regex (#9366) by @sapphi-red - remove pull_request_target workflows (#9188) by @Boshen - deps: upgrade oxc to 0.130.0 (#9360) by @shulaoda - deps: update github actions (major) (#9348) by @renovate[bot] - deps: update github actions (#9341) by @renovate[bot] - deps: update rust crates (#9344) by @renovate[bot] - deps: update crate-ci/typos action to v1.46.1 (#9357) by @renovate[bot] - deps: update npm packages (#9343) by @renovate[bot] - deps: update pnpm to v10.33.4 (#9347) by @renovate[bot] - deps: update dependency rolldown-plugin-dts to ^0.25.0 (#9346) by @renovate[bot] - .claude: add rolldown-repl encoder, rename decode skill (#9352) by @IWANABETHATGUY - deps: update crate-ci/typos action to v1.46.0 (#9345) by @renovate[bot] - deps: update napi to v3.8.6 (#9342) by @renovate[bot] - deps: update dependency vite-plus to v0.1.20 (#9340) by @renovate[bot] - enable rollup chunking-form test (#9335) by @IWANABETHATGUY - typo: fix typo in watcher options comment (#9324) by @thescripted ### ❤️ New Contributors * @Kyujenius made their first contribution in [#9262](#9262) * @SAY-5 made their first contribution in [#9296](#9296) * @thescripted made their first contribution in [#9324](#9324) Co-authored-by: shulaoda <[email protected]>
## Summary
This PR fixes a case where dynamic imported chunks in lazy chunks are not able to fetch the correct exports.
Before:
```js
import(`/@vite/lazy?id=…&clientId=…`)
```
After:
```js
import(`/@vite/lazy?id=…&clientId=…`)
.then(() => __rolldown_runtime__.loadExports("<stable_proxy_id>"))
```
When a lazy chunk's body contains `import('./another-lazy.js')`, the HMR partial
bundle returned the raw chunk namespace (raw lazy chunk) instead of the registered proxy exports,
so `inner.foo` came back `undefined`.
In this PR, we intentionally skip loading the raw lazy chunk, instead,
we use `__rolldown_runtime__.loadExports(...)` to load real module exports.
## Test plan
- [x] `pnpm test:browser` — all 7 tests pass with the fix in place
- [x] New playground: `packages/test-dev-server/tests/playground/lazy-nested-dynamic-import/`
- [x] Reverted the fix locally → `pnpm test:browser -t 'lazy-nested-dynamic-import'` fails with
`inner.foo = UNDEFINED` / `inner.bar = UNDEFINED`
- [x] Restored the fix → test passes on first try (~135 ms, no retry)
- [x] `pnpm run lint-knip` clean for the new playground
## [1.0.1] - 2026-05-13 ### 🚀 Features - experimental/lazy-barrel: advice on oversized barrel modules (#9236) by @shulaoda - rolldown: inline optional-chain enum access (#9379) by @Dunqing - chunk-optimization: dedupe already-loaded dynamic deps (#9305) by @IWANABETHATGUY - binding: call moduleParsed hook in ParallelJsPlugin (#9318) by @jaehafe ### 🐛 Bug Fixes - transform: enable `enum_eval` for `transformSync` and vite TS transform (#9325) by @Dunqing - error: remove severity prefix from diagnostic messages (#9262) by @Kyujenius - deps: pin pnpm to 10.23.0 to work around catalog mismatch on Netlify (#9364) by @shulaoda - ci: pin mimalloc-safe to 0.1.58 (#9361) by @shulaoda - dev/lazy: fix exports of lazy requests in lazy chunks (#9249) by @h-a-n-a - rolldown_plugin_vite_resolve: handle errors in `resolveSubpathImports` callback (#9355) by @sapphi-red - rolldown_plugin_lazy_compilation: use loadExports for fetched proxy to preserve original export names (#9132) by @h-a-n-a - common: include offending index in HybridIndexVec panic message (#9296) by @SAY-5 ### 🚜 Refactor - ecmascript: extract semantic_builder_for_transform helper (#9326) by @Dunqing - test: extract reusable static-import-cycle helper (#9332) by @IWANABETHATGUY ### 📚 Documentation - clarify scope of `topLevelVar` (#9380) by @IWANABETHATGUY - meta/design: add ast-mutation design doc (#9338) by @hyf0 - feat: add ai policy in contribution guide (#9315) by @mdong1909 ### ⚡ Performance - binding: enable mimalloc v3 to reduce idle memory (#9349) by @shulaoda ### 🧪 Testing - mcs: cover require() in `$initial` group (#9376) by @hyf0 - add regression for CJS facade chunk merge into entry (#9351) by @IWANABETHATGUY ### ⚙️ Miscellaneous Tasks - switch prepare-release to manual dispatch with version input (#9383) by @shulaoda - migrate `@rolldown/pluginutils` to `rolldown/plugins` (#9317) by @shulaoda - deps: pin libmimalloc-sys2 to 0.1.54 (#9372) by @shulaoda - replace `igorskyflyer/action-readfile` with `cat` (#9369) by @sapphi-red - deps: update test262 submodule for tests (#9371) by @rolldown-guard[bot] - use app token for test dep update PRs (#9368) by @sapphi-red - replace some actions with gh commands (#9367) by @sapphi-red - replace action-semantic-pull-request with inline regex (#9366) by @sapphi-red - remove pull_request_target workflows (#9188) by @Boshen - deps: upgrade oxc to 0.130.0 (#9360) by @shulaoda - deps: update github actions (major) (#9348) by @renovate[bot] - deps: update github actions (#9341) by @renovate[bot] - deps: update rust crates (#9344) by @renovate[bot] - deps: update crate-ci/typos action to v1.46.1 (#9357) by @renovate[bot] - deps: update npm packages (#9343) by @renovate[bot] - deps: update pnpm to v10.33.4 (#9347) by @renovate[bot] - deps: update dependency rolldown-plugin-dts to ^0.25.0 (#9346) by @renovate[bot] - .claude: add rolldown-repl encoder, rename decode skill (#9352) by @IWANABETHATGUY - deps: update crate-ci/typos action to v1.46.0 (#9345) by @renovate[bot] - deps: update napi to v3.8.6 (#9342) by @renovate[bot] - deps: update dependency vite-plus to v0.1.20 (#9340) by @renovate[bot] - enable rollup chunking-form test (#9335) by @IWANABETHATGUY - typo: fix typo in watcher options comment (#9324) by @thescripted ### ❤️ New Contributors * @Kyujenius made their first contribution in [#9262](#9262) * @SAY-5 made their first contribution in [#9296](#9296) * @thescripted made their first contribution in [#9324](#9324) Co-authored-by: shulaoda <[email protected]>

Summary
This PR fixes a case where dynamic imported chunks in lazy chunks are not able to fetch the correct exports.
Before:
After:
When a lazy chunk's body contains
import('./another-lazy.js'), the HMR partialbundle returned the raw chunk namespace (raw lazy chunk) instead of the registered proxy exports,
so
inner.foocame backundefined.In this PR, we intentionally skip loading the raw lazy chunk, instead,
we use
__rolldown_runtime__.loadExports(...)to load real module exports.Test plan
pnpm test:browser— all 7 tests pass with the fix in placepackages/test-dev-server/tests/playground/lazy-nested-dynamic-import/pnpm test:browser -t 'lazy-nested-dynamic-import'fails withinner.foo = UNDEFINED/inner.bar = UNDEFINEDpnpm run lint-knipclean for the new playground