fix: eliminate unreachable dynamic entry#7356
Conversation
How to use the Graphite Merge QueueAdd 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. This stack of pull requests is managed by Graphite. Learn more about stacking. |
✅ Deploy Preview for rolldown-rs canceled.
|
✅ Deploy Preview for rolldown-rs canceled.
|
Benchmarks Rust |
9a7d1a1 to
2bc5652
Compare
There was a problem hiding this comment.
Pull request overview
This PR fixes issue #3403 by tracking dynamic import expressions that are inside "lazy paths" (e.g., inside PURE-annotated function callbacks) and preventing them from creating separate chunks during the bundling process. The fix involves tracking the AST address of dynamic import expressions and determining if they're unreachable for chunk splitting purposes when they appear inside side-effect-free function calls.
Key Changes:
- Added
DynamicImportPositionInfostruct to track both the statement index and AST address of dynamic import expressions - Extended cross-module optimization to detect when dynamic imports are inside lazy evaluation contexts (like PURE-annotated callbacks)
- Modified entry point tracking to include the AST address alongside module and statement indices
Reviewed changes
Copilot reviewed 20 out of 20 changed files in this pull request and generated 10 comments.
Show a summary per file
| File | Description |
|---|---|
| crates/rolldown_common/src/types/import_record.rs | Introduces DynamicImportPositionInfo struct and replaces related_stmt_info_idx with dynamic_import_info field in ImportRecord to track both statement index and AST address |
| crates/rolldown_common/src/types/entry_point.rs | Extends related_stmt_infos tuple to include Address for tracking import expression locations |
| crates/rolldown_common/src/lib.rs | Exports new DynamicImportPositionInfo type |
| crates/rolldown/src/stages/link_stage/cross_module_optimization.rs | Implements logic to detect unreachable dynamic imports inside lazy paths, adds visitor tracking with visit_path and is_lazy_path_from_first_lazy_node helper function |
| crates/rolldown/src/stages/link_stage/tree_shaking/include_statements.rs | Updates include_statements to accept and use unreachable import expression addresses when determining if dynamic entries are alive |
| crates/rolldown/src/stages/link_stage/mod.rs | Threads unreachable addresses from cross-module optimization to statement inclusion |
| crates/rolldown/src/types/scan_stage_cache.rs | Updates tuple destructuring to handle new Address field in related_stmt_infos |
| crates/rolldown/src/module_loader/module_loader.rs | Updates dynamic import entry tracking to use new dynamic_import_info structure instead of related_stmt_info_idx |
| crates/rolldown/src/module_finalizers/mod.rs | Adds defensive checks when rewriting import expressions to handle cases where chunks may not exist for unreachable imports |
| crates/rolldown/src/ast_scanner/mod.rs | Updates add_import_record to accept import_expression_address parameter and construct DynamicImportPositionInfo when present |
| crates/rolldown/src/ast_scanner/impl_visit.rs | Passes import expression address when scanning dynamic imports |
| crates/rolldown/src/ast_scanner/new_url.rs | Updates add_import_record call to pass None for import expression address |
| crates/rolldown/src/ast_scanner/hmr.rs | Updates add_import_record calls to pass None for import expression address |
| crates/rolldown/tests/rolldown/issues/3403/* | Adds test case demonstrating the fix - dynamic import inside PURE callback no longer creates separate chunk |
| crates/rolldown/tests/rolldown/optimization/inline_empty_function_call/basic/artifacts.snap | Updates snapshot showing that unreachable module no longer generates a chunk |
| crates/rolldown/tests/snapshots/integration_rolldown__filename_with_hash.snap | Updates hash snapshot with new test case |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
crates/rolldown/src/stages/link_stage/cross_module_optimization.rs
Outdated
Show resolved
Hide resolved
crates/rolldown/src/stages/link_stage/cross_module_optimization.rs
Outdated
Show resolved
Hide resolved
crates/rolldown/src/stages/link_stage/cross_module_optimization.rs
Outdated
Show resolved
Hide resolved
crates/rolldown/src/stages/link_stage/cross_module_optimization.rs
Outdated
Show resolved
Hide resolved
crates/rolldown/src/stages/link_stage/cross_module_optimization.rs
Outdated
Show resolved
Hide resolved
crates/rolldown/src/stages/link_stage/cross_module_optimization.rs
Outdated
Show resolved
Hide resolved
crates/rolldown/src/stages/link_stage/cross_module_optimization.rs
Outdated
Show resolved
Hide resolved
b67b6ca to
fa04a10
Compare
fa04a10 to
e9815f9
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 18 out of 18 changed files in this pull request and generated 7 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
crates/rolldown/src/stages/link_stage/cross_module_optimization.rs
Outdated
Show resolved
Hide resolved
crates/rolldown/src/stages/link_stage/cross_module_optimization.rs
Outdated
Show resolved
Hide resolved
e9815f9 to
9cf47e7
Compare
9cf47e7 to
1961c35
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 18 out of 18 changed files in this pull request and generated 4 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
crates/rolldown/src/stages/link_stage/tree_shaking/include_statements.rs
Show resolved
Hide resolved
hyf0
left a comment
There was a problem hiding this comment.
LGTM. I think we could merge it first, but still @sapphi-red cc
Merge activity
|
1961c35 to
411197a
Compare
sapphi-red
left a comment
There was a problem hiding this comment.
On second thought, this isn't safe. This will break when running the non-minified output.
Can you elaborate a little, or give an example? |
|
Ah, does this only handle the case where the function is empty? |
Also, when the function is side effects free (marked with |
## [1.0.0-beta.54] - 2025-12-11 ⏱️ Plugin Timing Analysis - Added `checks.pluginTimings` option to emit warnings when plugins significantly impact build performance - More details: https://rolldown.rs/options/checks#plugintimings <img width="834" height="119" alt="image" src="https://github.com/user-attachments/assets/e819f906-6192-4503-8d5c-854fa92ecb45" /> > [!WARNING] > For hooks using `ctx.resolve()` or `ctx.load()`, the reported time includes waiting for other plugins, which may overestimate that plugin's actual cost. > > Additionally, since plugin hooks execute concurrently, the statistics represent accumulated time rather than wall-clock time. The measured duration also includes Rust-side processing overhead, Tokio async scheduling overhead, NAPI data conversion overhead, and JavaScript event loop overhead. ### 🚀 Features - rolldown_plugin_vite_reporter: add newline after build summary for better log separation (#7458) by @shulaoda - plugin: collect plugin hook execution timings (#7364) by @shulaoda - test-dev-server: reload page when detecting hmr reload message (#7422) by @hyf0 - rolldown_plugin_vite_dynamic_import_vars: add transform-based v2 implementation (#7400) by @shulaoda - rolldown_plugin_vite_import_glob: add transform-based v2 implementation (#7394) by @shulaoda - rolldown_plugin_vite_wasm_helper: add v2 implementation (#7402) by @shulaoda - expose error location and context fields on JS API error objects (#7341) by @Copilot - add `CIRCULAR_REEXPORT` error (#7337) by @Copilot - support emit prebuilt chunk (#7277) by @Copilot ### 🐛 Bug Fixes - preserve object key order when parse json with serde_json (#7443) by @IWANABETHATGUY - improve JSON parsing with serde_json to emit proper diagnostic (#7442) by @IWANABETHATGUY - deconflict external symbols in CJS modules (#7447) by @IWANABETHATGUY - rolldown_plugin_vite_transform,rolldown_plugin_vite_resolve: enable `yarnPnp` option when pnp is detected (#5791) by @sapphi-red - skip deconflicting top-level symbols for CJS modules (#7425) by @IWANABETHATGUY - rolldown_plugin_esm_external_require: run resolveId hook before other plugins (#7426) by @shulaoda - avoid duplicate underscores in legitimized identifiers (#7418) by @IWANABETHATGUY - use `process.on('exit')` instead of `signal-exit` on webcontainers (#7421) by @sapphi-red - dev: remove `imports` when an import is removed (#7348) by @sapphi-red - bench: access latency.mean instead of mean in tinybench result (#7417) by @shulaoda - path compression in symbol linking (#7392) by @IWANABETHATGUY - rolldown_plugin_vite_resolve: add RwLock to avoid clearing cache while resolving (#7386) by @sapphi-red - handle JSON prototype properties correctly (#7383) by @IWANABETHATGUY - preserve entry signature strict chunk merging (#7343) by @IWANABETHATGUY - support eliminating multiple unused dynamic imports in a single statement (#7361) by @IWANABETHATGUY - eliminate unreachable dynamic entry (#7356) by @IWANABETHATGUY - `NormalizedInputOptions#cwd` should always exists (#7360) by @hyf0 - cli: support multiple comma-separated define arguments (#7340) by @Copilot - remove redundant symbol param in __reExport runtime helper (#7346) by @IWANABETHATGUY - always use __export for empty namespace objects when symbols enabled (#7345) by @IWANABETHATGUY - relax the restriction of preserveEntrySignatures when merging chunks (#7339) by @IWANABETHATGUY ### 🚜 Refactor - builtin-plugin: make config parameter required for vite plugins (#7451) by @shulaoda - move esbuild test related scripts to `scripts/src/esbuild-tests` (#7377) by @sapphi-red - rewrite gen-esbuild-test in TypeScript (#7376) by @sapphi-red - remove unnecessary Option in current_stmt_idx (#7359) by @IWANABETHATGUY - move more code into chunk optimizer (#7335) by @IWANABETHATGUY ### 📚 Documentation - checks: clarify pluginTimings measures CPU time due to concurrent execution (#7448) by @shulaoda - checks: add accuracy note to pluginTimings documentation (#7441) by @shulaoda - development-guide: add esbuild test description (#7439) by @sapphi-red - checks: expand `pluginTimings` documentation with detection mechanism (#7428) by @shulaoda - add checks options documentation (#7427) by @shulaoda - development-guide: add test262 integration test description (#7430) by @sapphi-red - guide: fix grammer in getting-started (#7331) by @jakeparis ### 🧪 Testing - rollup-tests: make `--grep` work and document it (#7431) by @sapphi-red - add a way to run some test262 test cases by name (#7429) by @sapphi-red - rolldown_plugin_vite_dynamic_import_vars: add test cases for v2 implementation (#7401) by @shulaoda - rolldown_plugin_vite_import_glob: add test cases for v2 implementation (#7395) by @shulaoda - triage new esbuild tests (#7405) by @sapphi-red - hmr: delete file used (#5933) by @sapphi-red - watch: add `watchChange` hook `create` / `delete` tests (#7349) by @sapphi-red - hmr: delete file not used anymore (#5932) by @sapphi-red - triage esbuild failed reasons (#7391) by @sapphi-red - change esbuild tests stats and diff generation (#7379) by @sapphi-red - dev: add `continuous generate hmr patch` and `debounce bundle` tests (#7368) by @hyf0 - add new esbuild tests (#7353) by @sapphi-red ### ⚙️ Miscellaneous Tasks - setup Node before updating snapshots for test262 update (#7435) by @sapphi-red - run tests when submodules are updated (#7455) by @sapphi-red - exclude NUL path pattern to prevent crash on Windows (#7450) by @IWANABETHATGUY - run cargo-test for esbuild script changes and update esbuild snapshot (#7440) by @sapphi-red - jsx_import_meta tests to `ignoreReasons` due to architectural limitation (#7434) by @Copilot - deps: update dependency oxlint-tsgolint to v0.8.5 (#7433) by @renovate[bot] - update test dependencies automatically (#7432) by @sapphi-red - remove unused code (#7420) by @IWANABETHATGUY - add back `just update-esbuild-diff` and add it to CI (#7404) by @sapphi-red - deps: update oxc-resolver to 11.15.0 (#7415) by @shulaoda - deps: update rust crate napi to v3.7.0 (#7393) by @renovate[bot] - fix esbuild compatibility metrics calculation (#7390) by @sapphi-red - support `tsconfig: true` in rust tests (#7389) by @sapphi-red - hide oxc runtime in snapshots (#7388) by @sapphi-red - deps: update oxc to v0.102.0 (#7385) by @camc314 - improve esbuild tests to download snapshots automatically (#7378) by @sapphi-red - deps: update dependency tinybench to v6 (#7371) by @renovate[bot] - deps: update actions/checkout action to v6 (#7370) by @renovate[bot] - deps: update rust crates (#7367) by @renovate[bot] - deps: update dependency oxlint to v1.32.0 (#7374) by @renovate[bot] - deps: update dependency oxlint-tsgolint to v0.8.4 (#7373) by @renovate[bot] - node/test-dev-server: support using custom html file (#7357) by @hyf0 - test: setup browser-based e2e test for `test-dev-server` (#7351) by @hyf0 - pin pnpm to version 10.23.0 (#7369) by @IWANABETHATGUY - deps: update dependency rolldown-plugin-dts to v0.18.3 (#7372) by @renovate[bot] - deps: update github-actions (#7365) by @renovate[bot] - deps: update npm packages (#7366) by @renovate[bot] - polish the comments about `SymbolRefFlags` (#7358) by @IWANABETHATGUY - deps: update dependency rolldown-plugin-dts to v0.18.2 (#7355) by @renovate[bot] - fix esbuild test generation script (#7352) by @sapphi-red - apply cargo shear suggestion (#7347) by @IWANABETHATGUY - deps: update oxc to v11.15.0 (#7344) by @renovate[bot] - deps: update dependency @napi-rs/cli to v3.5.0 (#7338) by @renovate[bot] - deps: update dependency oxlint to v1.31.0 (#7305) by @renovate[bot] - update rollup-tests results (#7333) by @sapphi-red - update rollup-tests Rollup version (#7332) by @sapphi-red - add ignore config for test262 submodule (#7326) by @Copilot ### ❤️ New Contributors * @jakeparis made their first contribution in [#7331](#7331) Co-authored-by: shulaoda <[email protected]>

closed #3403