Skip to content

fix(deconflict): rename CJS-wrapped locals that shadow chunk-root bindings#9921

Merged
graphite-app[bot] merged 1 commit into
mainfrom
fix/9882-cjs-wrapped-esm-shadowing
Jun 29, 2026
Merged

fix(deconflict): rename CJS-wrapped locals that shadow chunk-root bindings#9921
graphite-app[bot] merged 1 commit into
mainfrom
fix/9882-cjs-wrapped-esm-shadowing

Conversation

@IWANABETHATGUY

@IWANABETHATGUY IWANABETHATGUY commented Jun 22, 2026

Copy link
Copy Markdown
Member

What this PR solves

Fixes #9882.

A CJS-wrapped module's author-local var declared inside the generated __commonJS closure could shadow a same-named chunk-root binding imported from a peer ESM module. Because var declarations are hoisted to the top of the closure, the local shadowed the captured outer binding for the whole closure body, so references read the (still-undefined) local instead of the initialized import — producing a runtime TypeError (e.g. Cannot read properties of undefined (reading 'EventMatch')).

Example shape: an entry is CJS-wrapped (typeof exports/typeof module probing), declares var sharedValue = …, and also imports { SharedEnum } from a peer ESM module whose hoisted var sharedValue; is the chunk-root binding. The local shadows the import.

Fix

Adds a post-deconfliction pass NestedScopeRenamer::rename_cjs_locals_shadowing_referenced_chunk_bindings (in renamer.rs), run from rename_shadowing_symbols_in_nested_scopes after all final names are assigned. For WrapKind::Cjs modules only, for each referenced named import / star-import member-expression it takes the import's final canonical name, looks up the module's root scope, and if a different module-owned binding shadows that name it renames only the shadowing local (never the chunk-root binding) via Renamer::override_root_scope_binding.

The override picks the next $N suffix skipping both resolver-reserved names and every binding in the module, so it cannot collide with a sibling local (covers the second-order case where the entry already has sharedValue and sharedValue$1). It is order-independent, so it also covers the reverse-ordering case (non-entry CJS module).

Alternatives explored

  • Widen chunk_scope_captured_names to include peer ESM/None chunk-root bindings, and/or reserve names on the non-deconflict path in renamer.rs. Both worked but over-approximated, producing harmless-but-noisy snapshot churn across unrelated fixtures. The reference-precise post-pass renames only genuine shadows, with zero snapshot churn beyond the new fixtures.

Notes for reviewers

  • The binding != reference guard is load-bearing: without it an import * as m whose member expr is m.default would rename m onto itself (regression risk for [Bug]: Duplicate import binding names when external imports share the same local identifier #7444). The existing star/named-import passes use the same guard.
  • Why a separate pass: the shadow is a module-root-scope binding already named by the main loop, and register_nested_scope_symbols bails on already-named symbols — so the existing rename_bindings_shadowing_named_imports can't reach it.

Tests

Two regression fixtures, both executing the built bundle via _test.mjs:

  • crates/rolldown/tests/rolldown/issues/9882/ — the original report.
  • crates/rolldown/tests/rolldown/topics/deconflict/cjs_shadowing_renamed_chunk_binding/ — second-order variant (entry already has sharedValue + sharedValue$1).

Full rolldown integration suite passes; clippy clean.

@netlify

netlify Bot commented Jun 22, 2026

Copy link
Copy Markdown

Deploy Preview for rolldown-rs ready!

Name Link
🔨 Latest commit 6345ddf
🔍 Latest deploy log https://app.netlify.com/projects/rolldown-rs/deploys/6a420bca71df2e00084150df
😎 Deploy Preview https://deploy-preview-9921--rolldown-rs.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
🤖 Make changes Run an agent on this branch

To edit notification comments on pull requests, go to your Netlify project configuration.

@IWANABETHATGUY IWANABETHATGUY changed the title fix(deconflict): rename CJS locals shadowing chunk bindings fix(deconflict): rename CJS-wrapped locals that shadow chunk-root bindings Jun 22, 2026
@jimsimon

Copy link
Copy Markdown

👋 Hello and thank you for tackling this! I'm happy to help test this against the originally reported issue if there's a way to do so. I extracted the reproduction code from a much larger codebase (Reddit's frontend repo).

@pkg-pr-new

pkg-pr-new Bot commented Jun 24, 2026

Copy link
Copy Markdown

Open in StackBlitz

@rolldown/browser

pnpm add https://pkg.pr.new/rolldown/rolldown/@rolldown/browser@9921 -D
npm i https://pkg.pr.new/rolldown/rolldown/@rolldown/browser@9921 -D
yarn add https://pkg.pr.new/rolldown/rolldown/@rolldown/browser@9921.tgz -D

@rolldown/debug

pnpm add https://pkg.pr.new/rolldown/rolldown/@rolldown/debug@9921 -D
npm i https://pkg.pr.new/rolldown/rolldown/@rolldown/debug@9921 -D
yarn add https://pkg.pr.new/rolldown/rolldown/@rolldown/debug@9921.tgz -D

rolldown

pnpm add https://pkg.pr.new/rolldown/rolldown@9921 -D
npm i https://pkg.pr.new/rolldown/rolldown@9921 -D
yarn add https://pkg.pr.new/rolldown/rolldown@9921.tgz -D

@rolldown/binding-android-arm64

pnpm add https://pkg.pr.new/rolldown/rolldown/@rolldown/binding-android-arm64@9921 -D
npm i https://pkg.pr.new/rolldown/rolldown/@rolldown/binding-android-arm64@9921 -D
yarn add https://pkg.pr.new/rolldown/rolldown/@rolldown/binding-android-arm64@9921.tgz -D

@rolldown/binding-darwin-arm64

pnpm add https://pkg.pr.new/rolldown/rolldown/@rolldown/binding-darwin-arm64@9921 -D
npm i https://pkg.pr.new/rolldown/rolldown/@rolldown/binding-darwin-arm64@9921 -D
yarn add https://pkg.pr.new/rolldown/rolldown/@rolldown/binding-darwin-arm64@9921.tgz -D

@rolldown/binding-darwin-x64

pnpm add https://pkg.pr.new/rolldown/rolldown/@rolldown/binding-darwin-x64@9921 -D
npm i https://pkg.pr.new/rolldown/rolldown/@rolldown/binding-darwin-x64@9921 -D
yarn add https://pkg.pr.new/rolldown/rolldown/@rolldown/binding-darwin-x64@9921.tgz -D

@rolldown/binding-freebsd-x64

pnpm add https://pkg.pr.new/rolldown/rolldown/@rolldown/binding-freebsd-x64@9921 -D
npm i https://pkg.pr.new/rolldown/rolldown/@rolldown/binding-freebsd-x64@9921 -D
yarn add https://pkg.pr.new/rolldown/rolldown/@rolldown/binding-freebsd-x64@9921.tgz -D

@rolldown/binding-linux-arm-gnueabihf

pnpm add https://pkg.pr.new/rolldown/rolldown/@rolldown/binding-linux-arm-gnueabihf@9921 -D
npm i https://pkg.pr.new/rolldown/rolldown/@rolldown/binding-linux-arm-gnueabihf@9921 -D
yarn add https://pkg.pr.new/rolldown/rolldown/@rolldown/binding-linux-arm-gnueabihf@9921.tgz -D

@rolldown/binding-linux-arm64-gnu

pnpm add https://pkg.pr.new/rolldown/rolldown/@rolldown/binding-linux-arm64-gnu@9921 -D
npm i https://pkg.pr.new/rolldown/rolldown/@rolldown/binding-linux-arm64-gnu@9921 -D
yarn add https://pkg.pr.new/rolldown/rolldown/@rolldown/binding-linux-arm64-gnu@9921.tgz -D

@rolldown/binding-linux-arm64-musl

pnpm add https://pkg.pr.new/rolldown/rolldown/@rolldown/binding-linux-arm64-musl@9921 -D
npm i https://pkg.pr.new/rolldown/rolldown/@rolldown/binding-linux-arm64-musl@9921 -D
yarn add https://pkg.pr.new/rolldown/rolldown/@rolldown/binding-linux-arm64-musl@9921.tgz -D

@rolldown/binding-linux-ppc64-gnu

pnpm add https://pkg.pr.new/rolldown/rolldown/@rolldown/binding-linux-ppc64-gnu@9921 -D
npm i https://pkg.pr.new/rolldown/rolldown/@rolldown/binding-linux-ppc64-gnu@9921 -D
yarn add https://pkg.pr.new/rolldown/rolldown/@rolldown/binding-linux-ppc64-gnu@9921.tgz -D

@rolldown/binding-linux-s390x-gnu

pnpm add https://pkg.pr.new/rolldown/rolldown/@rolldown/binding-linux-s390x-gnu@9921 -D
npm i https://pkg.pr.new/rolldown/rolldown/@rolldown/binding-linux-s390x-gnu@9921 -D
yarn add https://pkg.pr.new/rolldown/rolldown/@rolldown/binding-linux-s390x-gnu@9921.tgz -D

@rolldown/binding-linux-x64-gnu

pnpm add https://pkg.pr.new/rolldown/rolldown/@rolldown/binding-linux-x64-gnu@9921 -D
npm i https://pkg.pr.new/rolldown/rolldown/@rolldown/binding-linux-x64-gnu@9921 -D
yarn add https://pkg.pr.new/rolldown/rolldown/@rolldown/binding-linux-x64-gnu@9921.tgz -D

@rolldown/binding-linux-x64-musl

pnpm add https://pkg.pr.new/rolldown/rolldown/@rolldown/binding-linux-x64-musl@9921 -D
npm i https://pkg.pr.new/rolldown/rolldown/@rolldown/binding-linux-x64-musl@9921 -D
yarn add https://pkg.pr.new/rolldown/rolldown/@rolldown/binding-linux-x64-musl@9921.tgz -D

@rolldown/binding-openharmony-arm64

pnpm add https://pkg.pr.new/rolldown/rolldown/@rolldown/binding-openharmony-arm64@9921 -D
npm i https://pkg.pr.new/rolldown/rolldown/@rolldown/binding-openharmony-arm64@9921 -D
yarn add https://pkg.pr.new/rolldown/rolldown/@rolldown/binding-openharmony-arm64@9921.tgz -D

@rolldown/binding-wasm32-wasi

pnpm add https://pkg.pr.new/rolldown/rolldown/@rolldown/binding-wasm32-wasi@9921 -D
npm i https://pkg.pr.new/rolldown/rolldown/@rolldown/binding-wasm32-wasi@9921 -D
yarn add https://pkg.pr.new/rolldown/rolldown/@rolldown/binding-wasm32-wasi@9921.tgz -D

@rolldown/binding-win32-arm64-msvc

pnpm add https://pkg.pr.new/rolldown/rolldown/@rolldown/binding-win32-arm64-msvc@9921 -D
npm i https://pkg.pr.new/rolldown/rolldown/@rolldown/binding-win32-arm64-msvc@9921 -D
yarn add https://pkg.pr.new/rolldown/rolldown/@rolldown/binding-win32-arm64-msvc@9921.tgz -D

@rolldown/binding-win32-x64-msvc

pnpm add https://pkg.pr.new/rolldown/rolldown/@rolldown/binding-win32-x64-msvc@9921 -D
npm i https://pkg.pr.new/rolldown/rolldown/@rolldown/binding-win32-x64-msvc@9921 -D
yarn add https://pkg.pr.new/rolldown/rolldown/@rolldown/binding-win32-x64-msvc@9921.tgz -D

commit: 89d1a08

@IWANABETHATGUY

Copy link
Copy Markdown
Member Author

👋 Hello and thank you for tackling this! I'm happy to help test this against the originally reported issue if there's a way to do so. I extracted the reproduction code from a much larger codebase (Reddit's frontend repo).

You can try overriding rolldown with pkg.pr version.

@jimsimon

Copy link
Copy Markdown

This change has fixed the original issue. Thank you!

@IWANABETHATGUY IWANABETHATGUY force-pushed the fix/9882-cjs-wrapped-esm-shadowing branch 2 times, most recently from 0acfd6b to 89d1a08 Compare June 25, 2026 11:02
@IWANABETHATGUY IWANABETHATGUY marked this pull request as ready for review June 29, 2026 03:37
@IWANABETHATGUY IWANABETHATGUY force-pushed the fix/9882-cjs-wrapped-esm-shadowing branch from 89d1a08 to c3968fa Compare June 29, 2026 03:41
@codspeed-hq

codspeed-hq Bot commented Jun 29, 2026

Copy link
Copy Markdown

Merging this PR will not alter performance

✅ 7 untouched benchmarks
⏩ 10 skipped benchmarks1


Comparing fix/9882-cjs-wrapped-esm-shadowing (239c39f) with main (9570c95)2

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.

  2. No successful run was found on main (50db1f3) during the generation of this report, so 9570c95 was used instead as the comparison base. There might be some changes unrelated to this pull request in this report.

IWANABETHATGUY commented Jun 29, 2026

Copy link
Copy Markdown
Member Author

How to use the Graphite Merge Queue

Add 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.

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.

Pull request overview

Fixes a deconfliction bug where CJS-wrapped module locals (var hoisted inside the __commonJS closure) could shadow referenced chunk-root bindings, causing runtime failures like Cannot read properties of undefined.

Changes:

  • Add a CJS-specific post-pass (rename_cjs_locals_shadowing_referenced_chunk_bindings) that detects root-scope locals shadowing referenced chunk-root bindings and renames only the shadowing local.
  • Add Renamer::override_root_scope_binding to safely override already-assigned root-scope names while avoiding reserved names and any existing module binding names (including sibling locals like foo$1).
  • Add two integration regression fixtures (issue repro + second-order suffix-skipping variant) that execute the built bundle.

Reviewed changes

Copilot reviewed 12 out of 12 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
crates/rolldown/src/utils/renamer.rs Adds the override helper and a CJS-only pass to rename shadowing root-scope locals based on actual referenced chunk-root bindings.
crates/rolldown/src/utils/chunk/deconflict_chunk_symbols.rs Runs the new CJS post-pass as part of nested-scope shadowing renames.
crates/rolldown/tests/rolldown/issues/9882/main.js Source fixture reproducing the original shadowing bug scenario.
crates/rolldown/tests/rolldown/issues/9882/dependency.js Dependency module whose binding is hoisted to chunk root and referenced by the CJS-wrapped entry.
crates/rolldown/tests/rolldown/issues/9882/artifacts.snap Snapshot asserting the generated output no longer shadows the chunk-root binding.
crates/rolldown/tests/rolldown/issues/9882/_test.mjs Executes the built bundle to ensure no runtime throw.
crates/rolldown/tests/rolldown/issues/9882/_config.json Integration test configuration for the #9882 fixture.
crates/rolldown/tests/rolldown/topics/deconflict/cjs_shadowing_renamed_chunk_binding/main.js Second-order fixture ensuring the shadowing-local rename skips existing sibling suffixes.
crates/rolldown/tests/rolldown/topics/deconflict/cjs_shadowing_renamed_chunk_binding/dependency.js Dependency module used by the second-order deconfliction fixture.
crates/rolldown/tests/rolldown/topics/deconflict/cjs_shadowing_renamed_chunk_binding/artifacts.snap Snapshot validating the correct deconfliction result for the second-order case.
crates/rolldown/tests/rolldown/topics/deconflict/cjs_shadowing_renamed_chunk_binding/_test.mjs Executes the built bundle to ensure no runtime throw for the second-order variant.
crates/rolldown/tests/rolldown/topics/deconflict/cjs_shadowing_renamed_chunk_binding/_config.json Integration test configuration for the second-order fixture.

Comment thread crates/rolldown/tests/rolldown/issues/9882/artifacts.snap
@IWANABETHATGUY IWANABETHATGUY force-pushed the fix/9882-cjs-wrapped-esm-shadowing branch 2 times, most recently from c04f207 to 239c39f Compare June 29, 2026 05:33

IWANABETHATGUY commented Jun 29, 2026

Copy link
Copy Markdown
Member Author

Merge activity

  • Jun 29, 6:03 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.
  • Jun 29, 6:07 AM UTC: IWANABETHATGUY added this pull request to the Graphite merge queue.
  • Jun 29, 6:12 AM UTC: Merged by the Graphite merge queue.

…dings (#9921)

### What this PR solves

Fixes #9882.

A CJS-wrapped module's author-local `var` declared inside the generated `__commonJS` closure could shadow a same-named **chunk-root binding** imported from a peer ESM module. Because `var` declarations are hoisted to the top of the closure, the local shadowed the captured outer binding for the whole closure body, so references read the (still-`undefined`) local instead of the initialized import — producing a runtime `TypeError` (e.g. `Cannot read properties of undefined (reading 'EventMatch')`).

Example shape: an entry is CJS-wrapped (`typeof exports`/`typeof module` probing), declares `var sharedValue = …`, and also imports `{ SharedEnum }` from a peer ESM module whose hoisted `var sharedValue;` is the chunk-root binding. The local shadows the import.

### Fix

Adds a post-deconfliction pass `NestedScopeRenamer::rename_cjs_locals_shadowing_referenced_chunk_bindings` (in `renamer.rs`), run from `rename_shadowing_symbols_in_nested_scopes` **after** all final names are assigned. For `WrapKind::Cjs` modules only, for each *referenced* named import / star-import member-expression it takes the import's final canonical name, looks up the module's root scope, and if a *different* module-owned binding shadows that name it renames **only the shadowing local** (never the chunk-root binding) via `Renamer::override_root_scope_binding`.

The override picks the next `$N` suffix skipping both resolver-reserved names and every binding in the module, so it cannot collide with a sibling local (covers the second-order case where the entry already has `sharedValue` *and* `sharedValue$1`). It is order-independent, so it also covers the reverse-ordering case (non-entry CJS module).

### Alternatives explored

- **Widen `chunk_scope_captured_names`** to include peer ESM/None chunk-root bindings, and/or reserve names on the non-deconflict path in `renamer.rs`. Both worked but over-approximated, producing harmless-but-noisy snapshot churn across unrelated fixtures. The reference-precise post-pass renames only genuine shadows, with **zero** snapshot churn beyond the new fixtures.

### Notes for reviewers

- The `binding != reference` guard is load-bearing: without it an `import * as m` whose member expr is `m.default` would rename `m` onto itself (regression risk for #7444). The existing star/named-import passes use the same guard.
- Why a separate pass: the shadow is a module-root-scope binding already named by the main loop, and `register_nested_scope_symbols` bails on already-named symbols — so the existing `rename_bindings_shadowing_named_imports` can't reach it.

### Tests

Two regression fixtures, both executing the built bundle via `_test.mjs`:

- `crates/rolldown/tests/rolldown/issues/9882/` — the original report.
- `crates/rolldown/tests/rolldown/topics/deconflict/cjs_shadowing_renamed_chunk_binding/` — second-order variant (entry already has `sharedValue` + `sharedValue$1`).

Full `rolldown` integration suite passes; clippy clean.
@graphite-app graphite-app Bot force-pushed the fix/9882-cjs-wrapped-esm-shadowing branch from 239c39f to 6345ddf Compare June 29, 2026 06:08
graphite-app Bot pushed a commit that referenced this pull request Jun 29, 2026
)

Pure no-op refactor, split out of the #9882 follow-up work — **stacked on #9921**.

Extracts the inline "chunk-scope captured names" collection block out of `deconflict_chunk_symbols` into a dedicated `collect_chunk_scope_captured_names` helper. No behavior change.

### Why

The follow-up fix #9970 adds wrapped-ESM namespace-object capture lines to this block, which pushes `deconflict_chunk_symbols` past clippy's `too_many_lines` (200) ceiling. Extracting the helper first keeps #9970 focused purely on the actual fix.

### Changes

- Move the captured-names collection into `collect_chunk_scope_captured_names(chunk, link_output, format, &renamer)` — verbatim logic, just relocated.

### Tests

No new behavior → no new fixtures. Verified as a no-op: all `topics/deconflict` + `issues/9882` snapshot tests pass unchanged.
@graphite-app graphite-app Bot merged commit 6345ddf into main Jun 29, 2026
33 of 34 checks passed
@graphite-app graphite-app Bot deleted the fix/9882-cjs-wrapped-esm-shadowing branch June 29, 2026 06:12
IWANABETHATGUY added a commit that referenced this pull request Jun 29, 2026
…jects

A CJS-wrapped module that `require()`s a wrapped-ESM module reads the importee's
chunk-root namespace object via `(init_x(), __toCommonJS(xxx_exports))`. An
author-local sharing that namespace object's final name shadows the read,
producing the self-referential `var xxx_exports = (init_x(), __toCommonJS(xxx_exports))`
-> `__toCommonJS(undefined)` -> TypeError at module-eval (issue #9882,
require()/namespace channel).

Handle this in the precise `rename_cjs_locals_shadowing_referenced_chunk_bindings`
post-pass (the same mechanism #9921 uses for named-import and star-member
shadowing): for each `require()` of a non-CommonJS importee, rename a root-scope
local sharing the importee namespace object''s *final* name. The post-pass runs
after root-scope names are assigned, so it sees the namespace''s real name and
only touches modules that actually reference it -- renaming the shadowing local,
never the namespace.

Adds regression fixtures: cjs_shadowing_require_namespace_object (the base case)
and cjs_unrelated_wrapper_reserves_namespace_suffix (an unrelated CJS local must
not push the namespace onto a suffix shadowed by another module).
IWANABETHATGUY added a commit that referenced this pull request Jun 29, 2026
…jects

A CJS-wrapped module that `require()`s a wrapped-ESM module reads the importee's
chunk-root namespace object via `(init_x(), __toCommonJS(xxx_exports))`. An
author-local sharing that namespace object's final name shadows the read,
producing the self-referential `var xxx_exports = (init_x(), __toCommonJS(xxx_exports))`
-> `__toCommonJS(undefined)` -> TypeError at module-eval (issue #9882,
require()/namespace channel).

Handle this in the precise `rename_cjs_locals_shadowing_referenced_chunk_bindings`
post-pass (the same mechanism #9921 uses for named-import and star-member
shadowing): for each `require()` of a non-CommonJS importee, rename a root-scope
local sharing the importee namespace object''s *final* name. The post-pass runs
after root-scope names are assigned, so it sees the namespace''s real name and
only touches modules that actually reference it -- renaming the shadowing local,
never the namespace.

Adds the regression fixture cjs_shadowing_require_namespace_object: it throws
`__toCommonJS(undefined)` on the base and passes with the fix.
@rolldown-guard rolldown-guard Bot mentioned this pull request Jul 1, 2026
shulaoda added a commit that referenced this pull request Jul 1, 2026
## [1.1.4] - 2026-07-01

### 🚀 Features

- disable `experimental.lazyBarrel` by default (#10071) by @shulaoda

### 🐛 Bug Fixes

- dev: disable lazy barrel in dev mode (#10060) by @shulaoda
- generate: keep full JSON interface under preserveModules namespa… (#10056) by @IWANABETHATGUY
- check finalize_other_specifiers in its own Debug attribute (#10032) by @shulaoda
- serialize the KeepAssign unused minify option as "keep_assign" (#10031) by @shulaoda
- keep fragments after the newline fragment in MagicString::last_line (#10023) by @shulaoda
- generate: undeclared JSON named exports under preserveModules (#10020) (#10027) by @IWANABETHATGUY
- deconflict: rename CJS-wrapped locals that shadow chunk-root bindings (#9921) by @IWANABETHATGUY
- rolldown: keep entry facade when a shared chunk holds another entry's module (#9997) by @hyf0
- treeshake: also bail JSON default split when the object escapes (#9996) by @IWANABETHATGUY
- don't classify await in a strict-mode function as top-level await (#9987) by @shulaoda
- avoid spurious leading newline in addon hooks (banner/footer/intro/outro) (#9989) by @shulaoda
- handle JSON default mutation bailouts (#9972) by @TheAlexLichter
- plugin: make lazy hook metadata enumerable (#9991) by @TheAlexLichter
- dev: make init errors in lazy-compiled modules catchable (#9981) by @h-a-n-a
- treeshake: keep computed-key side effects on namespace member access (#9986) by @shulaoda
- binding: validate replace plugin delimiters length instead of panicking (#9984) by @shulaoda
- reconstruct nested rest patterns in into_expression (#9980) by @IWANABETHATGUY
- reconstruct rest patterns as spread in into_expression (#9976) by @shulaoda
- preserve export keyword on multi-declarator exports under keepNames (#9974) by @shulaoda
- deterministically keep the shortest name for deduplicated assets (#9948) by @x1024
- treeshake: apply @__NO_SIDE_EFFECTS__ to cross-chunk namespace calls (#9960) by @IWANABETHATGUY

### 🚜 Refactor

- drop redundant program scope enter/leave in finalizer (#10049) by @shulaoda
- deconflict: extract collect_chunk_scope_captured_names (#10006) by @IWANABETHATGUY
- unify pre-scan multi-declarator split into one decision site (#9982) by @IWANABETHATGUY
- common: return bool from SymbolRef::is_not_reassigned (#9962) by @IWANABETHATGUY

### 📚 Documentation

- rolldown: remove outdated comment for removing parenthesized expression (#10062) by @Dunqing
- use GitHub-flavored alert for Etiquette note in contribution guide (#10012) by @IWANABETHATGUY
- replace: explain the delimiters left and right boundaries (#9985) by @shulaoda
- ast-mutation: remove stale Address Use section after pre-scan refactor (#9983) by @IWANABETHATGUY
- remove fathom (#9968) by @mdong1909
- contribution-guide: code-format main branch references (#9966) by @IWANABETHATGUY
- contribution-guide: fix stale REPL note and tidy wording (#9957) by @hyf0
- contribution-guide: clarify when to discuss before opening a PR (#9955) by @hyf0

### ⚡ Performance

- disable preserve_parens across all parse paths (#10057) by @Dunqing
- common: inline declared_symbols with SmallVec (#9920) by @IWANABETHATGUY
- common: pack TaggedSymbolRef into 8 bytes (#9919) by @IWANABETHATGUY
- sourcemap: skip newline scan on the no-sourcemap join fast path (#9936) by @Boshen

### 🧪 Testing

- dev: error in lazy module should be catchable (#9975) by @sapphi-red
- dev: reject unknown lazy compile modules (#9969) by @sapphi-red

### ⚙️ Miscellaneous Tasks

- deps: update actions/cache action to v6 (#10001) by @renovate[bot]
- trigger vite ecosystem-ci from PR comments (#10058) by @shulaoda
- deps: update napi to v3.10.0 (#10063) by @renovate[bot]
- remove unused From impl for RolldownLabelSpan (#10055) by @shulaoda
- remove dead Diagnostic::with_kind method (#10054) by @shulaoda
- remove unused StatementExt methods (#10053) by @shulaoda
- remove unused ExpressionExt methods (#10052) by @shulaoda
- remove commented-out re_export_all_names field (#10051) by @shulaoda
- deps: update pnpm to v11.9.0 (#10047) by @renovate[bot]
- remove the unused BindingGenerateHmrPatchReturn napi type (#10034) by @shulaoda
- remove the dead inline_entry_chunk_wrapping scaffolding (#10037) by @shulaoda
- deps: bump oxc_resolver to 11.22.0 (#10045) by @Boshen
- remove never-constructed MatchImportKind::_Ignore variant (#10041) by @shulaoda
- remove the unused ScheduledBuild napi struct (#10033) by @shulaoda
- remove dead compute_hmr_update_single method (#10040) by @shulaoda
- drop the redundant visited.insert in manual code splitting (#10038) by @shulaoda
- remove the dead output_assets vector in render_chunk_to_assets (#10036) by @shulaoda
- remove the unused From<String>/Display impls for BindingLogLevel (#10035) by @shulaoda
- deps: upgrade oxc to 0.138.0 and migrate to per-type AST construction (#10018) by @shulaoda
- deps: update rust crates (#9911) by @renovate[bot]
- deps: update test262 submodule for tests (#10016) by @rolldown-guard[bot]
- deps: update github actions (#9999) by @renovate[bot]
- deps: update npm packages (#10000) by @renovate[bot]

### ◀️ Revert

- "fix(plugin): make lazy hook metadata enumerable (#9991)" (#10005) by @shulaoda

### ❤️ New Contributors

* @x1024 made their first contribution in [#9948](#9948)

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Imported binding is shadowed inside CommonJS-wrapped ESM entry, causing runtime TypeError

4 participants