docs(meta/design): introduce module tags#9017
Merged
graphite-app[bot] merged 1 commit intomainfrom Apr 9, 2026
Merged
Conversation
✅ Deploy Preview for rolldown-rs canceled.
|
Contributor
There was a problem hiding this comment.
Pull request overview
Adds a new design document describing a proposed “Module Tags” mechanism to label modules (e.g. $initial, $async) and use those labels for filtering within manual code splitting group rules.
Changes:
- Introduces
meta/design/module-tags.mddescribing the feature, motivation, and a proposed config surface (matchTags). - Defines proposed built-in tags (
$initial,$async) and outlines an implementation plan/phasing. - Captures future extension ideas (per-entry tags, user-defined tags, magic comments, plugin exposure).
0bef25b to
0110dc1
Compare
cpojer
reviewed
Apr 9, 2026
cpojer
reviewed
Apr 9, 2026
sapphi-red
approved these changes
Apr 9, 2026
cpojer
reviewed
Apr 9, 2026
cpojer
reviewed
Apr 9, 2026
Member
Author
How to use the Graphite Merge QueueAdd 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. |
5 tasks
8be3c9f to
06ead2c
Compare
Member
Author
Merge activity
|
## Summary
Design doc for module tags — a mechanism to attach string labels to modules based on their loading context, enabling smarter manual code splitting.
## Key design decisions
- **Built-in tags**: `$initial` (statically imported by user-defined entries or part of their dependency chain) and `$lazy` (reachable only via `import()`) — `$` prefix distinguishes built-in from user-defined tags
- **Mutually exclusive**: a module imported both statically and dynamically gets `$initial` only — it's already a dependency of an initial entry
- **`tags` filter**: AND semantics, `string[]` for Phase 1, extensible to `{ include, exclude }` object form in the future
- **Reserved names**: names starting with `$` are reserved for built-in tags
## Implementation phases
- **Phase 1**: `$initial` tag + `tags` filter in manual code splitting groups
- **Phase 2**: `$lazy` tag
- **Future**: per-entry tags (`$entry:<name>`), user-defined tags, magic comments, plugin API, `tags` object form
## Test plan
- [ ] Review design doc for completeness and correctness
🤖 Generated with [Claude Code](https://claude.com/claude-code)
06ead2c to
806e1a0
Compare
graphite-app Bot
pushed a commit
that referenced
this pull request
Apr 9, 2026
## Summary Implements Phase 1 of the module tags design ([#9017](#9017)): - **`$initial` tag** — automatically computed during the entry BFS. Modules statically imported by user-defined entries (or in their dependency chain) are tagged `$initial`. - **`tags` filter** — manual code splitting groups can filter by tags with AND semantics. Only modules with all specified tags are captured. ## Implementation - `ModuleTagBitSet` — `u64`-based bitset (`Copy`, single AND+CMP for `contains_all`). Supports up to 64 tags. - `ModuleTagRegistry` — sealed registry mapping tag names (`$initial`, future `$lazy`) to bit indices. All registration happens in `new()`. - `$initial` tag is computed inside `determine_reachable_modules_for_entry` BFS — no separate pass needed. - Built-in tags use `$` prefix to distinguish from user-defined tags. ## Test plan - [x] Integration test `tags_initial` — entry with static + dynamic imports, verifies `tags: ['$initial']` captures only statically reachable modules - [x] `cargo check` compiles - [x] `just lint-rust` passes - [x] `just build-rolldown` regenerates bindings - [x] TypeScript types check 🤖 Generated with [Claude Code](https://claude.com/claude-code)
This was referenced Apr 15, 2026
Closed
Merged
shulaoda
added a commit
that referenced
this pull request
Apr 16, 2026
## [1.0.0-rc.16] - 2026-04-16 ### 🚀 Features - const enum cross-module inlining support (#8796) by @Dunqing - implement module tagging system for code splitting (#9045) by @hyf0 ### 🐛 Bug Fixes - rolldown_plugin_vite_manifest: handle duplicate chunk names for CSS entries (#9059) by @sapphi-red - improve error message for invalid return values in function options (#9125) by @shulaoda - await async export-star init wrappers (#9101) by @thezzisu - never panic during diagnostic emission (#9091) by @IWANABETHATGUY - include array rest pattern in binding_identifiers (#9112) by @IWANABETHATGUY - rolldown: set worker thread count with ROLLDOWN_WORKER_THREADS (#9086) by @fpotter - rolldown_plugin_lazy_compilation: escape request ID in proxy modules (#9102) by @h-a-n-a - treat namespace member access as side-effect-free (#9099) by @IWANABETHATGUY - relax overly conservative side-effect leak check in chunk optimizer (#9085) by @IWANABETHATGUY - runtime: release `cb` reference after `__commonJS` factory initialization (#9067) by @hyf0-agent - `@__NO_SIDE_EFFECTS__` wrapper should not remove dynamic imports (#9075) by @IWANABETHATGUY - rolldown_plugin_vite_import_glob: use POSIX path join/normalize for glob resolution (#9077) by @shulaoda - emit REQUIRE_TLA error when require() loads a module with top-level await (#9071) by @jaehafe - emit namespace declaration for empty modules in manual chunks (#8993) by @privatenumber - rolldown_plugin_vite_import_glob: keep common base on path segment boundary (#9070) by @shulaoda - prevent circular runtime helper imports during facade elimination (#8989) (#9057) by @IWANABETHATGUY - correct circular dependency check in facade elimination (#9047) by @h-a-n-a - docs: correct dead link in CodeSplittingGroup.tags JSDoc (#9051) by @hyf0 - emit DUPLICATE_SHEBANG warning when banner contains shebang (#9026) by @IWANABETHATGUY ### 🚜 Refactor - use semantic reference flags for member write detection (#9060) by @Dunqing - extract UsedSymbolRefs newtype wrapper (#9130) by @IWANABETHATGUY - dedupe await wrapping in export-star init emit (#9119) by @IWANABETHATGUY - calculate side-effect-free function symbols on demand (#9120) by @IWANABETHATGUY - extract duplicated top-level await handling into shared helper (#9087) by @IWANABETHATGUY - rolldown_plugin_vite_import_glob: use split_first for get_common_base (#9069) by @shulaoda - simplify ESM init deduplication with idiomatic insert check (#9044) by @IWANABETHATGUY ### 📚 Documentation - document runtime module placement strategy in code-splitting design (#9062) by @IWANABETHATGUY - clarify `options` hook behavior difference with Rollup in watch mode (#9053) by @sapphi-red - meta/design: introduce module tags (#9017) by @hyf0 ### ⚡ Performance - convert `generate_transitive_esm_init` to iterative (#9046) by @IWANABETHATGUY ### 🧪 Testing - merge strict/non_strict test variants using configVariants (#9089) by @IWANABETHATGUY ### ⚙️ Miscellaneous Tasks - disable Renovate auto-updates for oxc packages (#9129) by @IWANABETHATGUY - upgrade oxc@0.126.0 (#9127) by @Dunqing - deps: update napi to v3.8.5 (#9126) by @renovate[bot] - deps: update dependency @napi-rs/cli to v3.6.2 (#9123) by @renovate[bot] - move lazy-compilation design doc (#9117) by @h-a-n-a - deps: update dependency vite-plus to v0.1.18 (#9118) by @renovate[bot] - deps: update dependency vite-plus to v0.1.17 (#9113) by @renovate[bot] - deps: update oxc to v0.125.0 (#9094) by @renovate[bot] - deps: update dependency follow-redirects to v1.16.0 [security] (#9103) by @renovate[bot] - deps: update test262 submodule for tests (#9097) by @sapphi-red - deps: update crate-ci/typos action to v1.45.1 (#9096) by @renovate[bot] - deps: update rust crates (#9081) by @renovate[bot] - deps: update npm packages (#9080) by @renovate[bot] - remove outdated TODO in determine_module_exports_kind (#9072) by @jaehafe - rust/test: support `extendedTests: false` shorthand in test config (#9050) by @hyf0 - ci: extract shared infra-changes anchor in path filters (#9054) by @hyf0 - add docs build check to catch dead links in PRs (#9052) by @hyf0 ### ❤️ New Contributors * @thezzisu made their first contribution in [#9101](#9101) * @fpotter made their first contribution in [#9086](#9086) * @jaehafe made their first contribution in [#9071](#9071) * @privatenumber made their first contribution in [#8993](#8993) Co-authored-by: shulaoda <165626830+shulaoda@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

Summary
Design doc for module tags — a mechanism to attach string labels to modules based on their loading context, enabling smarter manual code splitting.
Key design decisions
$initial(statically imported by user-defined entries or part of their dependency chain) and$lazy(reachable only viaimport()) —$prefix distinguishes built-in from user-defined tags$initialonly — it's already a dependency of an initial entrytagsfilter: AND semantics,string[]for Phase 1, extensible to{ include, exclude }object form in the future$are reserved for built-in tagsImplementation phases
$initialtag +tagsfilter in manual code splitting groups$lazytag$entry:<name>), user-defined tags, magic comments, plugin API,tagsobject formTest plan
🤖 Generated with Claude Code