You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Follow-up ledger for the strictExecutionOrder / onDemandWrapping work after #10104. This body is the single tracking surface, ordered by priority; the two older comments are superseded and minimized (their full audit details remain expandable).
P0 — correctness, likely to hit real projects
export * barrel leaves a pure ESM definer uninitialized (Family A). An inferred-pure or callable-own-state definer reached through an export * barrel by a split namespace consumer is never initialized. The only confirmed strict-SEO-specific correctness root; RED in both wrap modes, clean with strictExecutionOrder: false; highest random-sweep hit rate (mixed 22/100, pure ESM 24/100). Witnesses: fuzzer Family-A cases, pure-ESM seed 200004, shadcn transplant overlay (rolldown-order-fuzzer@77f196b). fix(code-splitting): initialize pure definers behind star re-export barrels under strict execution order #10409
Fold the runtime chunk back after order lowering.ensure_runtime_module_for_order_wraps unconditionally evicts a co-hosted runtime; re-run the merge proof with the post-lowering consumer set (OrderWrapState already carries each wrap's helper demand). Acceptance: issues/9463 inlines the runtime into common~a~b~shared in both cells. Anchors: issues/9463, issues/9463_plain_group, issues/9463_three_entries, strict_execution_order/concatenate_basic. fix(code-splitting): fold the runtime chunk back after order lowering #10414
Avoid the dynamic-entry facade when the same-chunk collapse can carry the trigger.create_order_wrap_entry_facades splits unconditionally; either emit the init through the shared esm_init_target view or skip the facade when the entry init is a noop with no transitive targets. Acceptance: issues/9463 wrap-all loses the shared.js facade chunk. Anchors: manual_group_phantom_dynamic, mixed_static_dynamic_same_target, issues/9463, issues/9463_plain_group, chunk_merging/dynamic_entry_merged_in_user_defined_entry. fix(code-splitting): avoid the dynamic-entry facade when the same-chunk collapse carries the trigger #10433
dynamicImports metadata records module_to_chunk[importee] while the finalizer rewrites via entry_module_to_entry_chunk (compute_cross_chunk_links.rs:358) — after a facade split, modulepreload-style consumers and devtools get the wrong direct edge. Verify whether Vite modulepreload is affected; if yes, promote to P0. Fix: record entry_module_to_entry_chunk with a module_to_chunk fallback. fix(code-splitting): align dynamicImports metadata with the rewritten import() specifier #10430
Add single-chunk strict coverage for a dynamic import of a wrapped module, e.g. strict_execution_order/single_chunk_dynamic_import_wrapped_module with IIFE and UMD variants.
Reference regression case: crates/rolldown/tests/rolldown/issues/9463 (cargo test -p rolldown --test integration -- 9463); pre-rewrite 3-chunk baseline fb81314, post-#10104 topology at 220783a (4/5 chunks). The full 94/94 snapshot audit trail lives in the minimized comments.
P2 — quick wins
Strict-gate the add_wrapped_esm_init_targets_for_static_member_reads Emit call site (esm_init_obligations.rs:359) — flag-off builds currently pay it for ns.x-only bindings of cross-chunk importees. The per-module member-read index can come later.
Warn when experimental.onDemandWrapping is set without output.strictExecutionOrder (silent no-op today), and reconcile the @hidden marker with the two public docs recommending the option by name.
Regenerate topics/generated_code/symbols_ns2/artifacts.snap in an environment that resolves assert, or pin the fixture's resolution — currently causes spurious local snapshot drift.
P3 — machinery follow-ups (opportunistic)
Correctness-adjacent corners:
restore_order_wrap_entry_facades un-tombstones every matching facade but wires only the first (order_wrapping.rs:389); two emitFile calls for one module break — only un-tombstone the facade actually re-pointed.
required_runtime_helpers() folds all overlays while live_symbols() gates on live importers (order_wrap_state.rs:33) — can define a __reExport nobody calls (bloat-only today); gate the fold the same way.
Perf (strict-only):
Gate TopLevelImportReadDetector (ast_scanner/impl_visit.rs:98) on onDemandWrapping too — wrap-all pays a per-module walk for a bit only on-demand analysis reads.
Skip building dynamic_target_modules_by_chunk in create_order_wrap_entry_facades under wrap-all.
Deduplicate: the export-star WrapKind::Esm arm vs wrapped_esm_init_call_expr (module_finalizers/mod.rs:1753); runtime-chunk minting and the "rolldown-runtime" literal (three sites, one naming warning); the duplicated 16-line order_live_symbols block (keep the second recompute — merge_cjs_namespace links canonical refs between the two).
Sweep the dormant concatenation model: ConcatenateWrappedModuleKind, Chunk::module_groups, the unreachable format/esm.rs:225 arm, and the dead disabled-splitting overlay arm (order_wrap_state.rs:536).
Unify the plan-member filters between real lowering (order_wrapping.rs:558) and the fixpoint probe (order_analysis.rs:553).
Comment in ast_scanner/impl_visit.rs that the scanner reads an output option — a footgun once scan caching across outputs lands.
Nits: use chunk_is_live() at detect_ineffective_dynamic_imports.rs:18 / order_wrapping.rs:272; ReexportRetentionEvidence → bool; drop write-only OrderSyntheticStmt.chunk/.owner; restore the internal-docs comment above trace_action_chunks_infos.
Moved out / resolved
manualPureFunctions deletion also removes eager child effects (make()[effect()], make(effect()).value, new (make()[effect()].Box)()) — ordinary tree-shaking bug, not strict-order; should move to its own tree-shaking issue (reduced cases in the minimized fuzzer comment).
CJS-output entry facade / grouped chunk calls an uninitialized wrapper export — won't fix for now (deliberate): only a fuzzer-generated configuration; full analysis, executed fixtures, and the long-term fix direction in fix(code-splitting): keep eager entries out of group chunks in cjs output #10401 (closed). Reopen only with a real-world report.
Follow-up ledger for the
strictExecutionOrder/onDemandWrappingwork after #10104. This body is the single tracking surface, ordered by priority; the two older comments are superseded and minimized (their full audit details remain expandable).P0 — correctness, likely to hit real projects
export *barrel leaves a pure ESM definer uninitialized (Family A). An inferred-pure or callable-own-state definer reached through anexport *barrel by a split namespace consumer is never initialized. The only confirmed strict-SEO-specific correctness root; RED in both wrap modes, clean withstrictExecutionOrder: false; highest random-sweep hit rate (mixed 22/100, pure ESM 24/100). Witnesses: fuzzer Family-A cases, pure-ESM seed200004, shadcn transplant overlay (rolldown-order-fuzzer@77f196b). fix(code-splitting): initialize pure definers behind star re-export barrels under strict execution order #10409P1 — output shape (this issue's original scope)
ensure_runtime_module_for_order_wrapsunconditionally evicts a co-hosted runtime; re-run the merge proof with the post-lowering consumer set (OrderWrapStatealready carries each wrap's helper demand). Acceptance:issues/9463inlines the runtime intocommon~a~b~sharedin both cells. Anchors:issues/9463,issues/9463_plain_group,issues/9463_three_entries,strict_execution_order/concatenate_basic. fix(code-splitting): fold the runtime chunk back after order lowering #10414create_order_wrap_entry_facadessplits unconditionally; either emit the init through the sharedesm_init_targetview or skip the facade when the entry init is a noop with no transitive targets. Acceptance:issues/9463wrap-all loses theshared.jsfacade chunk. Anchors:manual_group_phantom_dynamic,mixed_static_dynamic_same_target,issues/9463,issues/9463_plain_group,chunk_merging/dynamic_entry_merged_in_user_defined_entry. fix(code-splitting): avoid the dynamic-entry facade when the same-chunk collapse carries the trigger #10433dynamicImportsmetadata recordsmodule_to_chunk[importee]while the finalizer rewrites viaentry_module_to_entry_chunk(compute_cross_chunk_links.rs:358) — after a facade split, modulepreload-style consumers and devtools get the wrong direct edge. Verify whether Vite modulepreload is affected; if yes, promote to P0. Fix: recordentry_module_to_entry_chunkwith amodule_to_chunkfallback. fix(code-splitting): align dynamicImports metadata with the rewritten import() specifier #10430strict_execution_order/single_chunk_dynamic_import_wrapped_modulewith IIFE and UMD variants.Reference regression case:
crates/rolldown/tests/rolldown/issues/9463(cargo test -p rolldown --test integration -- 9463); pre-rewrite 3-chunk baselinefb81314, post-#10104 topology at220783a(4/5 chunks). The full 94/94 snapshot audit trail lives in the minimized comments.P2 — quick wins
add_wrapped_esm_init_targets_for_static_member_readsEmit call site (esm_init_obligations.rs:359) — flag-off builds currently pay it forns.x-only bindings of cross-chunk importees. The per-module member-read index can come later.experimental.onDemandWrappingis set withoutoutput.strictExecutionOrder(silent no-op today), and reconcile the@hiddenmarker with the two public docs recommending the option by name.topics/generated_code/symbols_ns2/artifacts.snapin an environment that resolvesassert, or pin the fixture's resolution — currently causes spurious local snapshot drift.P3 — machinery follow-ups (opportunistic)
Correctness-adjacent corners:
restore_order_wrap_entry_facadesun-tombstones every matching facade but wires only the first (order_wrapping.rs:389); twoemitFilecalls for one module break — only un-tombstone the facade actually re-pointed.required_runtime_helpers()folds all overlays whilelive_symbols()gates on live importers (order_wrap_state.rs:33) — can define a__reExportnobody calls (bloat-only today); gate the fold the same way.Perf (strict-only):
TopLevelImportReadDetector(ast_scanner/impl_visit.rs:98) ononDemandWrappingtoo — wrap-all pays a per-module walk for a bit only on-demand analysis reads.dynamic_target_modules_by_chunkincreate_order_wrap_entry_facadesunder wrap-all.Maintainability:
stmt_info_includedORforces_runtime_stmt) — the fix(code-splitting): deconflict force-included runtime helper statements #10336 deconflict miss is the failure mode this prevents.WrapKind::Esmarm vswrapped_esm_init_call_expr(module_finalizers/mod.rs:1753); runtime-chunk minting and the"rolldown-runtime"literal (three sites, one naming warning); the duplicated 16-lineorder_live_symbolsblock (keep the second recompute —merge_cjs_namespacelinks canonical refs between the two).ConcatenateWrappedModuleKind,Chunk::module_groups, the unreachableformat/esm.rs:225arm, and the dead disabled-splitting overlay arm (order_wrap_state.rs:536).order_wrapping.rs:558) and the fixpoint probe (order_analysis.rs:553).ast_scanner/impl_visit.rsthat the scanner reads an output option — a footgun once scan caching across outputs lands.chunk_is_live()atdetect_ineffective_dynamic_imports.rs:18/order_wrapping.rs:272;ReexportRetentionEvidence→ bool; drop write-onlyOrderSyntheticStmt.chunk/.owner; restore the internal-docs comment abovetrace_action_chunks_infos.Moved out / resolved
manualPureFunctionsdeletion also removes eager child effects (make()[effect()],make(effect()).value,new (make()[effect()].Box)()) — ordinary tree-shaking bug, not strict-order; should move to its own tree-shaking issue (reduced cases in the minimized fuzzer comment).strictExecutionOrder: true— the existing Manual codeSplitting groups leak cross-entry execution without strictExecutionOrder (#9463 follow-up) #9998 root; the strict CJS-output arm belongs to that ledger (reduction details in the minimized comment).