Skip to content

Turbopack: make available_modules an OperationVc and simplify merged module bookkeeping#94055

Merged
sokra merged 2 commits into
canaryfrom
sokra/available-modules-operation
May 26, 2026
Merged

Turbopack: make available_modules an OperationVc and simplify merged module bookkeeping#94055
sokra merged 2 commits into
canaryfrom
sokra/available-modules-operation

Conversation

@sokra
Copy link
Copy Markdown
Member

@sokra sokra commented May 22, 2026

What?

Reworks how chunk_group_content exposes available_modules for downstream chunking, and consolidates the bookkeeping for merged modules in ChunkGroup.

  • Splits ChunkGroupContent into a turbo_tasks::value ChunkGroupContentInner (carrying chunkable_items, batch_groups, async_modules, traced_modules, and available_modules) plus a thin wrapper that pairs it with the resulting AvailabilityInfo. chunk_group_content_operation now runs entirely inside turbo_tasks, allowing AvailableModules to store its set as an OperationVc<AvailableModulesSet> and .connect() it on read.
  • Replaces the separate included set and should_create_chunk_item_for method on MergedModuleInfo with an Option<ChunkableModule> value type on the replacements map. Call sites now decide all three cases (replace / skip / keep) in one match via should_replace_module.

Why?

  • AvailableModules::snapshot did not correctly derive its invalidation priority, which caused double invalidations: the snapshot was treated as a low-priority dependency even though it gated chunking work, so when its inputs changed turbo-tasks would invalidate it after dependent computations had already started, triggering them a second time. Exposing available_modules as an OperationVc makes AvailableModules inherit the correct invalidation priority from the operation that produces it, which removes the double-invalidation.
  • The previous MergedModuleInfo API had two parallel data structures (replacements and included) and a helper that combined them. Folding included into the value of replacements removes the duplication, makes the three states (replace, skip-because-merged, keep) explicit, and shrinks the call-site logic in chunk_group.rs.

How?

available_modules as an OperationVc:

  • New ChunkGroupContentInner is a turbo_tasks::value holding the chunkable items, batch groups, async/traced modules, and an OperationVc<AvailableModulesSet> for available_modules.
  • ChunkGroupContent becomes a plain struct wrapping ResolvedVc<ChunkGroupContentInner> together with the AvailabilityInfo computed for the group.
  • chunk_group_content_operation is an OperationVc-producing function so its inner available_modules can be returned as an OperationVc<AvailableModulesSet>. AvailableModules now stores that operation Vc and .connect()s it whenever the set is read, so consumers reach the set through the operation and inherit its priority.
  • Browser and Node.js chunking contexts are updated to thread the new shape through make_chunk_group and friends.

MergedModuleInfo simplification:

  • replacements changes from HashMap<ChunkableModule, ChunkableModule> to HashMap<ChunkableModule, Option<ChunkableModule>>: Some(m) means "replace with m", None means "skip — already included in another merged module", absent means "keep as-is".
  • The old included set and should_create_chunk_item_for helper are removed; should_replace_module returns the three-way outcome and consumers match on it once.
  • Call sites in chunk_group.rs are restructured around the single match so the logic is no longer split across two lookups.

Notes

  • No user-facing behavior change is intended — this is an internal refactor in turbopack-core (chunk_group_content, available_modules, chunk_group) and the browser/nodejs chunking contexts.
  • Existing chunking tests in turbopack-core exercise the new shape.

sokra added 2 commits May 22, 2026 17:09
Splits ChunkGroupContent into ChunkGroupContentInner (a turbo_tasks value
containing chunkable_items, batch_groups, async_modules, traced_modules,
and available_modules) and a thin ChunkGroupContent wrapper that pairs it
with the resulting AvailabilityInfo. chunk_group_content_operation runs
inside turbo_tasks so its available_modules can be exposed as an
OperationVc<AvailableModulesSet>, which AvailableModules now stores and
.connect()s on read.
Replaces the separate `included` set and `should_create_chunk_item_for`
method with an `Option<ChunkableModule>` value type on the `replacements`
map: present-with-`Some` means "replace", present-with-`None` means
"skip (already included in another merged module)", and absent means
"keep as-is". Call sites now decide all three cases in one match on
`should_replace_module`.
@sokra sokra requested a review from mischnic May 22, 2026 18:09
@github-actions
Copy link
Copy Markdown
Contributor

Tests Passed

Commit: 7ae6320

@sokra sokra marked this pull request as ready for review May 22, 2026 19:08
@sokra sokra requested a review from lukesandberg May 25, 2026 18:27
@sokra sokra merged commit 0070514 into canary May 26, 2026
162 of 164 checks passed
@sokra sokra deleted the sokra/available-modules-operation branch May 26, 2026 11:10
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.

2 participants