Skip to content

Comments

fix(cjs): prevent duplicate require declarations for external modules with preserveModules#7234

Merged
IWANABETHATGUY merged 6 commits intorolldown:mainfrom
logaretm:awad/duplicate-cjs-export-vars
Nov 27, 2025
Merged

fix(cjs): prevent duplicate require declarations for external modules with preserveModules#7234
IWANABETHATGUY merged 6 commits intorolldown:mainfrom
logaretm:awad/duplicate-cjs-export-vars

Conversation

@logaretm
Copy link
Contributor

When using CJS format with preserveModules, files that do both named exports AND star exports from the same external module would generate duplicate require() statements: one as let and one as var. breaking the bundle with a redeclaration error.

The deduplication logic was only checking direct_imports_from_external_modules but missing import_symbol_from_external_modules.

I added a .chain() call to check both lists so it actually knows the module was already imported and skips the duplicate declaration.

Feel free to close this PR if the approach is incorrect, just figured to give it a go.

closes #7233

Copilot AI review requested due to automatic review settings November 27, 2025 00:14
@graphite-app
Copy link
Contributor

graphite-app bot commented Nov 27, 2025

How to use the Graphite Merge Queue

Add the label graphite: merge 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.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR fixes issue #7233 where CJS bundles with preserveModules would generate duplicate require() declarations (one with let and one with var) when a file has both named exports and star exports from the same external module, causing a redeclaration error.

  • Adds .chain() call in deduplication logic to check both direct_imports_from_external_modules and import_symbol_from_external_modules
  • Adds comprehensive test coverage for both direct and chained re-export scenarios

Reviewed changes

Copilot reviewed 13 out of 13 changed files in this pull request and generated no comments.

File Description
crates/rolldown/src/utils/chunk/render_chunk_exports.rs Fixed deduplication logic to check both external module collections when tracking imported modules
crates/rolldown/tests/rolldown/issues/mod.rs Added test module declarations for issue #7233 and its chain variant
crates/rolldown/tests/rolldown/issues/7233/* Test case for basic scenario: file with both named and star exports from same external module
crates/rolldown/tests/rolldown/issues/7233_chain/* Test case for chained re-exports scenario through multiple modules

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@IWANABETHATGUY
Copy link
Member

You don't need to write mod.rs since those tests can be written with a static JSON config.

@IWANABETHATGUY IWANABETHATGUY self-assigned this Nov 27, 2025
Copilot AI review requested due to automatic review settings November 27, 2025 10:00
@logaretm
Copy link
Contributor Author

Got it, I reverted the mod.rs changes 👍

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 11 out of 11 changed files in this pull request and generated no new comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@IWANABETHATGUY IWANABETHATGUY enabled auto-merge (squash) November 27, 2025 10:07
@netlify
Copy link

netlify bot commented Nov 27, 2025

Deploy Preview for rolldown-rs canceled.

Name Link
🔨 Latest commit 224bc0e
🔍 Latest deploy log https://app.netlify.com/projects/rolldown-rs/deploys/69282300168ee8000838a161

@IWANABETHATGUY IWANABETHATGUY merged commit ba60fcc into rolldown:main Nov 27, 2025
27 checks passed
This was referenced Dec 3, 2025
shulaoda added a commit that referenced this pull request Dec 3, 2025
## [1.0.0-beta.53] - 2025-12-03

💥 Breaking Changes
- Drop `i686-pc-windows-msvc` target support

🚀 Chunk Merging Optimization
- Rolldown now automatically merges shared chunks when entries import each other (when `preserveEntrySignature` is not `strict`)
```shell
Before:
entry.js   → imports → shared.js (common chunk)
entry2.js  → imports → shared.js
Output: 3 chunks (entry.js, entry2.js, shared.js)

After:
entry.js   → contains shared code
entry2.js  → imports → entry.js
Output: 2 chunks (entry.js, entry2.js)
```

### 💥 BREAKING CHANGES

- drop `i686-pc-windows-msvc` target support (#7230) by @sapphi-red

### 🚀 Features

- rolldown_plugin_vite_manifest: pass normalized options to `isLegacy` callback (#7321) by @shulaoda
- plugin/vite-resolve: add `disableCache` option (#6763) by @sapphi-red
- rolldown: export `createTokioRuntime` for tsdown (#7264) by @shulaoda
- rolldown_plugin_vite_html: sync `moduleSideEffects` for already loaded modules (#7254) by @shulaoda
- rolldown_plugin_vite_html: load module scripts with side effects to prevent tree-shaking (#7244) by @shulaoda
- rolldown_plugin_vite_css_post: implement `cssScopeTo` for scoped CSS tree-shaking (#7240) by @shulaoda

### 🐛 Bug Fixes

- export default class decl __name runtime insertion (#7316) by @IWANABETHATGUY
- chunk side effects calculation (#7273) by @IWANABETHATGUY
- node: `output.generateCode.preset: 'es2015'` should set `output.generateCode.symbols: true` by default (#7314) by @sapphi-red
- skip name helper for classes with static name property (#7312) by @IWANABETHATGUY
- preserve chunk imports relationship after chunk merging (#7303) by @shulaoda
- dev: make `register_modules` async (#7289) by @hyf0
- preserve computed property in object destructuring (#7288) by @IWANABETHATGUY
- support dynamic imports with shared dependencies (#7261) by @IWANABETHATGUY
- call `defer_sync_scan_data` in non-incremental build mode (#7255) by @shulaoda
- optimize chunk merging for shared entry points (#7194) by @IWANABETHATGUY
- add indentation for UMD format output (#7263) by @IWANABETHATGUY
- rolldown_plugin_vite_css_post: pass options to `isLegacy` callback for proper legacy detection (#7260) by @shulaoda
- rolldown_plugin_vite_css_post: also detect `?inline=true` query for inlined CSS (#7245) by @shulaoda
- rolldown_plugin_vite_css_post: distinguish empty CSS from no CSS (#7241) by @shulaoda
- add Windows support for t-run command (#7242) by @IWANABETHATGUY
- cjs: prevent duplicate require declarations for external modules with preserveModules (#7234) by @logaretm
- rolldown_plugin_vite_resolve: resolve from root for virtual modules (#7236) by @sapphi-red
- include entry level external modules in chunk exports (#7218) by @IWANABETHATGUY

### 🚜 Refactor

- dev: make `removeClient` async (#7313) by @hyf0
- move chunk merging code out of code_splitting.rs (#7285) by @IWANABETHATGUY
- extract common function util for chunk merging (#7271) by @IWANABETHATGUY
- use iterative method to merge chunks (#7256) by @IWANABETHATGUY
- use concat_string! instead of string replace for generating chunk level exports (#7247) by @IWANABETHATGUY

### 📚 Documentation

- add warning to experimental.resolveNewUrlToAsset about JS/TS files (#7300) by @Copilot
- add sequential hook execution difference in plugin-api.md (#7308) by @Copilot
- add migration example from onwarn to onLog (#7299) by @Copilot
- add migration example for manualChunks to advancedChunks (#7298) by @Copilot
- deps: bump vitepress to fix build (#7307) by @sapphi-red
- examples & text for experimental.resolveNewUrlToAsset (#7259) by @TheAlexLichter

### ⚡ Performance

- rolldown_plugin_vite_css_post: lazily load `cssScopeTo` from JS module options (#7253) by @shulaoda
- rolldown_plugin_vite_css_post: avoid unnecessary string clones in `resolve_asset_urls_in_css` (#7250) by @shulaoda

### 🧪 Testing

- generate relative path like name in advanced chunks (#7267) by @IWANABETHATGUY
- add test case for preserveEntrySignatures with re-exports (#7279) by @IWANABETHATGUY
- add test262 integration tests (#7196) by @sapphi-red

### ⚙️ Miscellaneous Tasks

- deps: update dependency rolldown-plugin-dts to v0.18.1 (#7304) by @renovate[bot]
- enable tracing feature for napi (#7322) by @sapphi-red
- deps: update napi (#7320) by @renovate[bot]
- deps: update oxc (#7318) by @renovate[bot]
- deps: update napi (#7317) by @renovate[bot]
- deps: update oxc to v0.100.0 (#7301) by @renovate[bot]
- deps: downgrade pnpm to 10.23.0 to fix Netlify build (#7306) by @shulaoda
- add `trustPolicyExclude` for chokidar and semver (#7302) by @sapphi-red
- update pnpm lockfile (#7291) by @IWANABETHATGUY
- deps: update npm packages (#7272) by @renovate[bot]
- deps: update rust crates (#7270) by @renovate[bot]
- deps: update oxc (#7262) by @renovate[bot]
- deps: update github-actions (#7269) by @renovate[bot]
- deps: update dependency dprint-typescript to v0.95.13 (#7268) by @renovate[bot]
- deps: update `html5gum` to 0.8.1 (#7265) by @shulaoda
- rolldown: remove unused `getModuleOptions` from `PluginContext` (#7266) by @shulaoda
- remove unnecessary justfile ignore (#7243) by @IWANABETHATGUY
- deps: update oxc apps (#7238) by @renovate[bot]
- add `nul` to workaround https://github.com/anthropics/claude-c… (#7237) by @IWANABETHATGUY
- deps: update dependency valibot to v1.2.0 [security] (#7231) by @renovate[bot]
- deps: update crate-ci/typos action to v1.40.0 (#7232) by @renovate[bot]

### ❤️ New Contributors

* @logaretm made their first contribution in [#7234](#7234)

Co-authored-by: shulaoda <[email protected]>
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] CJS Bundles redeclaring duplicate variable names

2 participants