Skip to content

Comments

perf(renamer): optimize symbol renaming by eliminating rename_non_root_symbol pass#7867

Merged
shulaoda merged 24 commits intorolldown:mainfrom
Dunqing:optimize-renamer
Jan 14, 2026
Merged

perf(renamer): optimize symbol renaming by eliminating rename_non_root_symbol pass#7867
shulaoda merged 24 commits intorolldown:mainfrom
Dunqing:optimize-renamer

Conversation

@Dunqing
Copy link
Collaborator

@Dunqing Dunqing commented Jan 13, 2026

Summary

This PR optimizes the symbol renamer by eliminating the expensive rename_non_root_symbol pass and fixes a bug that could generate duplicate declarations.

Background

This is a rework of #4014, split into atomic commits for easier review. The original PR was rejected due to too many changes at once. Issue #6586 has since been fixed by #7859, but the performance optimization approach from #4014 still provides significant gains.

Key Changes

1. Eliminate rename_non_root_symbol pass

  • During root scope renaming, check against nested scopes upfront via is_name_available()
  • Most nested scope symbols keep their original names
  • Only handle edge cases (cross-module shadowing, CJS params) in lightweight register_nested_scope_symbols()

2. Skip storing original-named nested symbols

  • Add canonical_name_for_or_original() method that falls back to original name
  • Only store symbols in canonical_names when actually renamed
  • Reduces HashMap insertions for ~80-90% of nested symbols

3. Fix duplicate declaration bug

  • When renaming nested symbols (e.g., aa$1), check if the candidate name already exists in the same module
  • Prevents generating invalid code like function test(a$1, a$1) when both a and a$1 exist as parameters

How It Works

Old algorithm:

  1. Rename all root scope symbols
  2. Iterate through ALL nested scope symbols to check for conflicts
  3. Rename nested symbols that conflict with renamed root symbols

New algorithm:

  1. During root scope renaming, pick names that don't conflict with nested scopes upfront
  2. Most nested scope symbols keep original names (no storage needed)
  3. Only rename nested symbols that shadow cross-module or renamed top-level symbols
  4. Check for duplicate declarations when generating renamed names
 ┌─────────────────────────────────────────────────────────────────┐
 │ Phase 1: Root Scope Renaming                                    │
 ├─────────────────────────────────────────────────────────────────┤
 │  for each top-level symbol:                                     │
 │    → Check: used_canonical_names (top-level conflicts)          │
 │    → Check: entry module nested scopes (avoid capture)          │
 │    → Check: own module nested scopes (avoid capture)            │
 │    → Pick name that avoids ALL conflicts upfront                │
 └─────────────────────────────────────────────────────────────────┘
                               ↓
 ┌─────────────────────────────────────────────────────────────────┐
 │ Phase 2: Nested Scope Renaming (lightweight)                    │
 ├─────────────────────────────────────────────────────────────────┤
 │  for each nested symbol:                                        │
 │    ├─ shadows cross-module top-level? ──→ rename                │
 │    ├─ shadows renamed top-level?      ──→ rename                │
 │    ├─ is CJS `exports`/`module`?      ──→ rename                │
 │    └─ otherwise ──→ keep original (no storage needed)           │
 │                                                                 │
 │  When renaming, check candidate doesn't exist in same module    │
 │  to prevent duplicate declarations:                             │
 │                                                                 │
 │    Input: function test(a, a$1) { ... }                         │
 │           where `a` shadows top-level from another module       │
 │                                                                 │
 │    Rename `a`:                                                  │
 │      try `a$1` → exists in module scope → skip                  │
 │      try `a$2` → available → use it ✓                           │
 │                                                                 │
 │    Result: function test(a$2, a$1) { ... }                      │
 └─────────────────────────────────────────────────────────────────┘

Test Case

Added nested_scope_rename_counter test to verify the duplicate declaration fix:

// other.js
export const a = 'from-other';

// module_with_nested.js - has both `a` and `a$1` as parameters
export function test(a, a$1) { return [a, a$1]; }

// main.js
import { a } from './other.js';
import { test } from './module_with_nested.js';

Before fix: function test(a$1, a$1) - duplicate declarations!

After fix: function test(a$2, a$1) - correctly skips a$1 since it already exists

Snapshot Changes

The optimization produces slightly different (but equally correct) variable names:

  • Avoids ugly $1$1 double-suffix patterns
  • Names are chosen to avoid nested scope conflicts upfront

Copilot AI review requested due to automatic review settings January 13, 2026 14:22
@Dunqing Dunqing marked this pull request as draft January 13, 2026 14:22
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 optimizes the symbol renaming algorithm by eliminating the expensive rename_non_root_symbol pass that previously iterated through all nested scope symbols in parallel. The optimization achieves ~5-7% performance improvement on representative benchmarks (threejs, rome_ts).

Changes:

  • Rewrites add_symbol_in_root_scope to check for conflicts with nested scope symbols upfront during root scope renaming
  • Adds entry module tracking and name availability checks to avoid conflicts
  • Replaces expensive parallel rename_non_root_symbol iteration with lightweight register_nested_scope_symbols for edge cases only
  • Removes with_scope_tree_child_ids parameter from semantic analysis as it's no longer needed

Reviewed changes

Copilot reviewed 57 out of 57 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
crates/rolldown/src/utils/renamer.rs Core algorithm rewrite - adds entry module tracking, name availability checks, rewrites add_symbol_in_root_scope, replaces rename_non_root_symbol with register_nested_scope_symbols
crates/rolldown/src/utils/pre_process_ecma_ast.rs Removes with_scope_tree_child_ids parameter from recreate_scoping calls
crates/rolldown/src/utils/chunk/deconflict_chunk_symbols.rs Updates to use new renamer API, adds nested scope symbol registration loop
crates/rolldown/src/stages/generate_stage/mod.rs Removes pre-computation of module_scope_symbol_id_map
Test snapshots Hash and variable name changes reflecting the new naming algorithm

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

@IWANABETHATGUY
Copy link
Member

IWANABETHATGUY commented Jan 13, 2026

I found some test cases regressed(It was not renamed before, but it has been renamed in this pr). Can you double-check it?

@Dunqing
Copy link
Collaborator Author

Dunqing commented Jan 13, 2026

I found some test cases regressed(It was not renamed before, but it has been renamed in this pr). Can you double-check it?

Thank you for reviewing this PR quickly! I just let Claude code to make a POC for #4014 to see if it still has any performance improvements at this time, and I'm not deciding whether to continue or not.

@Dunqing Dunqing marked this pull request as ready for review January 13, 2026 14:43
@Dunqing
Copy link
Collaborator Author

Dunqing commented Jan 13, 2026

Open it to trigger the benchmark.

@IWANABETHATGUY
Copy link
Member

I found some test cases regressed(It was not renamed before, but it has been renamed in this pr). Can you double-check it?

Thank you for reviewing this PR quickly! I just let Claude code to make a POC for #4014 to see if it still has any performance improvements at this time, and I'm not deciding whether to continue or not.

No worries! Thanks for exploring this

@codspeed-hq
Copy link

codspeed-hq bot commented Jan 13, 2026

Merging this PR will improve performance by 3.9%

⚡ 2 improved benchmarks
✅ 6 untouched benchmarks

Performance Changes

Benchmark BASE HEAD Efficiency
bundle@threejs-sourcemap 229.2 ms 221.2 ms +3.59%
bundle@threejs 193.3 ms 186 ms +3.9%

Comparing Dunqing:optimize-renamer (135ba92) with main (08cfac8)

Open in CodSpeed

@Dunqing
Copy link
Collaborator Author

Dunqing commented Jan 13, 2026

Response to Copilot Review

After careful analysis, all three of Copilot's suggestions are based on misunderstandings of the code logic:

Comment 1 (Reserved name check at line 257)

The current logic is correct. The condition !is_reserved && self.is_entry_root_binding(...) already correctly handles reserved names:

  • If is_reserved == true: the entire condition evaluates to false, and we fall through to the rename logic (line 257-265)
  • If is_reserved == false AND is_entry_root_binding: we use the name directly

Copilot's suggestion is a structural refactoring that doesn't change the behavior - it's just a style preference.

Comment 2 (Inconsistency at line 193)

The "inconsistency" is intentional and documented. See lines 81-82:

// For entry module, pre-cache all symbol names (both root and non-root)
// to ensure we don't rename other symbols to names that exist in the entry module

Additionally, get_or_create_module_used_names is never called for the entry module - see line 230:

if self.entry_module_idx.is_none_or(|entry_idx| canonical_ref.owner != entry_idx) {
  let _ = self.get_or_create_module_used_names(canonical_ref.owner);
}

This explicitly guards against calling it for the entry module.

Comment 3 (RUNTIME_MODULE_INDEX at line 172)

Using a named constant RUNTIME_MODULE_INDEX is better than Copilot's suggestion of module_idx.as_u32() == 0:

  1. Named constants are more self-documenting than magic numbers
  2. from_usize_unchecked is a const fn, not actually unsafe in the Rust sense - it just creates the index value at compile time
  3. If the runtime module index ever changes, we only need to update one place

@IWANABETHATGUY
Copy link
Member

FYI, we have a criterion-based benchmark (this requires you to clone the repo directly rather than from a forked repo; IIRC, this is a security concern).

@shulaoda
Copy link
Member

Great! I’ve been waiting for the PR to come back. It feels like this isn’t just a performance improvement — the naming strategy also seems closer to Rollup now (i.e. without unnecessary or redundant renaming).

Copilot AI review requested due to automatic review settings January 13, 2026 15:38
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.

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

Copilot AI review requested due to automatic review settings January 13, 2026 15:52
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 38 out of 38 changed files in this pull request and generated 1 comment.


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

Copilot AI review requested due to automatic review settings January 13, 2026 16:40
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 32 out of 32 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.

Copilot AI review requested due to automatic review settings January 13, 2026 16:57
@Dunqing Dunqing force-pushed the optimize-renamer branch 2 times, most recently from 5e918bf to f5f77b3 Compare January 13, 2026 17:02
@hyf0 hyf0 enabled auto-merge (squash) January 14, 2026 11:49
@hyf0 hyf0 disabled auto-merge January 14, 2026 11:50
@graphite-app
Copy link
Contributor

graphite-app bot commented Jan 14, 2026

Merge activity

  • Jan 14, 11:50 AM UTC: @Dunqing we removed the merge queue label because we could not find a Graphite account associated with your GitHub profile.

You must have a Graphite account in order to use the merge queue. Create an account and try again using this link

@hyf0 hyf0 enabled auto-merge (squash) January 14, 2026 11:50
Copilot AI review requested due to automatic review settings January 14, 2026 11:50
@netlify
Copy link

netlify bot commented Jan 14, 2026

Deploy Preview for rolldown-rs canceled.

Name Link
🔨 Latest commit 135ba92
🔍 Latest deploy log https://app.netlify.com/projects/rolldown-rs/deploys/696795452a3f0200080a90b2

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 39 out of 39 changed files in this pull request and generated 5 comments.


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

Copilot AI review requested due to automatic review settings January 14, 2026 12:56
auto-merge was automatically disabled January 14, 2026 12:56

Head branch was pushed to by a user without write access

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 39 out of 39 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.

@shulaoda shulaoda merged commit 870f69e into rolldown:main Jan 14, 2026
35 checks passed
shulaoda added a commit that referenced this pull request Jan 16, 2026
## Summary

Optimize the nested scope symbol renaming pass by only processing
symbols whose names match a top-level canonical name in the same module.

- Collect canonical names of top-level symbols into a HashSet
- Only call `register_nested_scope_symbols` for nested symbols whose
names match a canonical name (or for CJS wrapped modules)
- Nested symbols that don't match any canonical name can safely shadow
cross-module top-level symbols via JavaScript's natural scoping rules

This is a follow-up optimization to #7867.

Also partially fixes
#6586 (comment)

## Test plan

- [x] Added new test case `nested_scope_same_module_conflict` to verify
the optimization behavior
- [x] Updated `nested_scope_rename_counter` test with improved comments
- [x] All existing tests pass

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Signed-off-by: Dunqing <[email protected]>
Co-authored-by: Claude Opus 4.5 <[email protected]>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Copilot <[email protected]>
Co-authored-by: Yunfei He <[email protected]>
Co-authored-by: dalaoshu <[email protected]>
hyf0 pushed a commit that referenced this pull request Jan 20, 2026
Note: waiting for oxc-project/oxc#18053 to merge
to unblock this (Edit: merged, and already released)

## Summary

Fixes: #6586


This PR refines the symbol renaming (deconflict) logic to correctly
handle both **top-level symbol conflicts** and **nested scope
shadowing**. The key insight is that these are two distinct problems
requiring different solutions.

Related fixes:

- #7859
- #7867 
- #7899 

This PR essentially reverts all the logic implemented in the previous
fixes while preserving the performance improvements introduced in #7867
(4%).

---

## 1. Top-Level Symbol Renaming

When bundling multiple modules into a single chunk, symbols with the
same name need unique identifiers.

**Example:**
```js
// lib.js
export const value = 1;

// other.js
export const value = 2;

// main.js
import { value } from './lib.js';
import { value as otherValue } from './other.js';
console.log(value, otherValue);
```

**Output:**
```js
const value = 1;      // lib.js - keeps original name (entry module priority)
const value$1 = 2;    // other.js - renamed to avoid conflict
console.log(value, value$1);
```

**Rules:**
- Entry module symbols get naming priority
- Subsequent conflicting symbols get suffixed: `$1`, `$2`, etc.
- Reserved names (keywords, globals like `Object`, `Promise`) are always
avoided

---

## 2. Nested Scope Symbol Renaming

This handles cases where a nested binding (function parameter, catch
clause, block-scoped variable) interacts with top-level symbols.

### Case A: NO renaming needed - Intentional shadowing

When a nested binding shadows an import that **kept its original name**,
no renaming is needed because JavaScript's scoping rules handle it
correctly.

**Example (`preserve_shadowing_param_name`):**

```js
// lib.js
export const Client = [];

// main.js
import { Client } from './lib.js';

// This param shadows the imported `Client`, but should NOT be renamed
// since shadowing is intentional and doesn't cause conflicts at runtime.
const Config = (Client) => {
  console.log(Client);   // → refers to parameter
};
console.log(Client);     // → refers to import
```

**Output:**
```js
const Client = [];
const Config = (Client) => {  // Parameter keeps its name ✓
  console.log(Client);
};
console.log(Client);
```

---

### Case B: Star import member references - Renaming needed

When a namespace import member (like `ns.foo`) is referenced inside a
function, and a nested binding would capture that reference, the nested
binding must be renamed.

**Example (`argument-treeshaking-parameter-conflict`):**

```js
// dep.js
export let value = 0;
export const mutate = () => value++;

// main.js
import * as dep from './dep';

function test(mutate) {       // Parameter named 'mutate'
  dep.mutate('hello');        // Reference to dep.mutate (top-level)
}

test();
assert.strictEqual(dep.value, 1);
```

**Output:**
```js
let value = 0;
const mutate = () => value++;

function test(mutate$1) {     // Parameter renamed to mutate$1
  mutate("hello");            // Correctly calls top-level mutate
}
test();
assert.strictEqual(value, 1);
```

**Why renaming is needed:**
1. The namespace import `dep.mutate` resolves to the top-level `mutate`
function
2. Inside `test`, the parameter `mutate` would shadow the top-level
`mutate`
3. The reference `dep.mutate('hello')` becomes just `mutate("hello")`
after bundling
4. Without renaming the parameter, this call would incorrectly invoke
the parameter instead of the top-level function
5. Solution: Rename the parameter to `mutate$1` so the reference
correctly resolves to the top-level `mutate`

---

### Case C: Named imports - Renaming needed

When a named import is renamed due to a top-level conflict, and a nested
binding has the same name as the **renamed** import, that nested binding
must be renamed to avoid capturing references.

**Example (`basic_scoped`):**

```js
// a.js
const a = 'a.js';
export { a };

// main.js
import { a as aJs } from './a';
const a = 'main.js';              // Local 'a' takes priority (entry module)

function foo(a$1) {               // Parameter named 'a$1'
  return [a$1, a, aJs];           // References: param, local, import
}

assert.deepEqual(foo('foo'), ['foo', 'main.js', 'a.js']);
```

**Output:**
```js
const a$1 = "a.js";               // Import renamed (conflicts with local 'a')
const a = "main.js";              // Local keeps name (entry module priority)

function foo(a$1$1) {             // Parameter renamed to a$1$1
  return [a$1$1, a, a$1];         // Correctly resolves all three references
}

assert.deepEqual(foo("foo"), ["foo", "main.js", "a.js"]);
```

**Why renaming is needed:**
1. `a` from `a.js` is renamed to `a$1` (conflicts with local `a` in
entry module)
2. The alias `aJs` resolves to the renamed `a$1`
3. Inside `foo`, the parameter `a$1` would capture the reference to
`aJs`
4. Solution: Rename the parameter to `a$1$1` so `aJs` correctly resolves
to the top-level `a$1`

---

> **Technical Note:** Cases B and C use the same underlying mechanism to
detect shadowing:
> 
> 1. Get the `reference_id` from the reference site (where the symbol is
used)
> 2. Use `scoping.scope_ancestors(reference.scope_id())` to walk up the
scope chain
> 3. Check if any ancestor scope has a binding with the same name as the
renamed symbol
> 4. If found, rename that nested binding to avoid capture
>
> This detection relies on oxc-project/oxc#18053
which added `scope_id` to `Reference`, enabling us to locate the exact
scope where the reference occurs.

---

### Case D: CJS wrapper parameters - Renaming needed

For CommonJS wrapped modules, nested scopes must avoid shadowing the
synthetic `exports` and `module` parameters injected by the CJS wrapper.

**Example:**
```js
// cjs-module.js (detected as CommonJS)
function helper() {
  const exports = {};  // Would shadow CJS wrapper's exports parameter
  return exports;
}
module.exports = helper;
```

**Output:**
```js
var require_cjs_module = __commonJS((exports, module) => {
  function helper() {
    const exports$1 = {};  // Renamed to avoid shadowing
    return exports$1;
  }
  module.exports = helper;
});
```

---

## Implementation Details

The renaming happens in two phases:

1. **`add_symbol_in_root_scope`** - Assigns canonical names to top-level
symbols, checking:
   - Is the name already used by another top-level symbol?
- For facade symbols (external module namespaces): would it conflict
with nested scopes in the entry module?

2. **`NestedScopeRenamer`** - Renames nested bindings that would capture
references:
- **`rename_bindings_shadowing_star_imports`** (Case B): Star import
member references (`ns.foo`)
- **`rename_bindings_shadowing_named_imports`** (Case C): Named imports
that were renamed
- **`rename_bindings_shadowing_cjs_params`** (Case D): CJS wrapper
parameter shadowing (`exports`, `module`)

---

## Test Cases

| Test | Case | Description |
|------|------|-------------|
| `preserve_shadowing_param_name` | A | Parameter shadows import, keeps
its name (intentional) |
| `argument-treeshaking-parameter-conflict` | B | Namespace member ref,
parameter renamed |
| `basic_scoped` | C | Named import renamed, nested binding renamed |
| `cjs` | D | CJS wrapper parameter shadowing |
| Rollup: `preserves-catch-argument` | A | Catch parameter shadows
import, keeps its name |
| Rollup: `class-name-conflict-2` | A | Class in block scope, keeps its
name |

> Note for reviewer: Code comments and PR description are almost
generated by Claude Code, but with careful self-review.
hyf0 pushed a commit that referenced this pull request Jan 21, 2026
@github-actions github-actions bot mentioned this pull request Jan 22, 2026
shulaoda pushed a commit that referenced this pull request Jan 22, 2026
## [1.0.0-rc.1] - 2026-01-22

### 🚀 Features

- debug_info: add facade chunk elimination reason (#7980) by @IWANABETHATGUY
- support lazy barrel optimization (#7933) by @shulaoda
- add `experimental.lazyBarrel` option (#7908) by @shulaoda
- skip unused external modules from IIFE parameter list (#7978) by @sapphi-red
- add custom panic hook for better crash reporting (#7752) by @shulaoda
- treeshake: add `invalidImportSideEffects` option (#7958) by @shulaoda
- merge allow-extension emitted chunks (#7940) by @IWANABETHATGUY
- nativeMagicString generateMap (#7944) by @IWANABETHATGUY
- Include meta.magicString in RenderChunkMeta (#7943) by @IWANABETHATGUY
- debug_info: add debug info for eliminated facade chunks (#7946) by @IWANABETHATGUY
- stablize `strictExecutionOrder` and move to `output.strictExecutionOrder` from `experimental.strictExecutionOrder` (#7901) by @sapphi-red
- add documentation link to require() error message (#7898) by @Copilot
- add `codeSplitting: boolean` and deprecate `inlineDynamicImports` (#7870) by @hyf0
- dev: change lazy module URL to `/@vite/lazy` from `/lazy` (#7884) by @sapphi-red

### 🐛 Bug Fixes

- transform JS files containing `</script>` to escape template literals (#7987) by @IWANABETHATGUY
- apply avoid-breaking-exported-api = false to clippy.toml and fix clippy errors (#7982) by @Boshen
- pass `kind` from `this.resolve` (#7981) by @sapphi-red
- rolldown_plugin_vite_resolve: ignore yarn resolution errors and fallback to other resolvers (#7968) by @sapphi-red
- renamer: prevent renaming symbols when there no conflicts (#7936) by @Dunqing
- correct minifyInterExports when emitted chunk got merged (#7941) by @IWANABETHATGUY
- deduplicate entry points when module is both emitted and dynamically imported (#7885) by @IWANABETHATGUY
- dev: add `@vite-ignore` to lazy compilation proxy module import (#7883) by @sapphi-red

### 🚜 Refactor

- rust: enable clippy nursery lint group (#8002) by @Boshen
- rust: fix inconsistent_struct_constructor clippy lint (#7999) by @Boshen
- rust: fix needless_pass_by_ref_mut clippy lint (#7994) by @Boshen
- rust: fix unnecessary_wraps clippy lint (#7993) by @Boshen
- rust: fix enum_variant_names clippy lint (#7992) by @Boshen
- fix single_match clippy lint (#7997) by @Boshen
- rust: fix redundant_clone clippy lint (#7996) by @Boshen
- rust: rename CJS to Cjs to follow upper_case_acronyms lint (#7991) by @Boshen
- rust: remove unnecessary Box wrapper around Vec in MemberExprRef (#7990) by @Boshen
- import_record: make resolved_module optional (#7907) by @shulaoda
- remove unnecessary `.parse` (#7966) by @sapphi-red
- remove unused `ImportRecordMeta::IsPlainImport` (#7948) by @shulaoda
- proper set chunk meta (#7939) by @IWANABETHATGUY
- module_loader: remove `try_spawn_with_cache` (#7920) by @shulaoda
- link_stage: simplify `ImportStatus::NoMatch` to unit variant (#7909) by @shulaoda
- improve global scope symbol reservation in chunk deconfliction (#7906) by @IWANABETHATGUY
- simplify ast unwrapping in generate stage (#7900) by @IWANABETHATGUY
- generate_stage: optimize cross-chunk imports computation (#7889) by @shulaoda
- link_stage: move runtime require logic into match branch (#7892) by @shulaoda
- link_stage: simplify runtime require reference conditions (#7891) by @shulaoda
- link_stage: inline and simplify external dynamic import check (#7890) by @shulaoda
- generate_stage: simplify external module import collection logic (#7887) by @shulaoda
- avoid redundant module lookup in TLA computation (#7886) by @shulaoda
- dev: `devEngine.compileEntry` does not return null (#7882) by @sapphi-red
- dev: fix type errors for test HMR runtime (#7881) by @sapphi-red
- dev: move `clientId` property to `DevRuntime` base class (#7880) by @sapphi-red
- dev: generate client id in browser (#7878) by @hyf0

### 📚 Documentation

- apis: organize hook filters documentation and add composable filters section (#8003) by @sapphi-red
- update `vitepress-plugin-group-icons` (#7947) by @yuyinws
- add in-depth documentation for lazy barrel optimization (#7969) by @shulaoda
- bump theme & update activeMatch for reference (#7963) by @mdong1909
- mark `build()` API as experimental (#7954) by @sapphi-red
- enhance search functionality with improved scoring and filtering logic (#7935) by @hyf0
- add minor comments to multiple types (#7930) by @sapphi-red
- refactor advanedChunks related content to adapt manual code splitting concept (#7925) by @hyf0
- apis: add content to Bundler API page (#7926) by @sapphi-red
- apis: restructure plugin API related docs (#7924) by @sapphi-red
- add plugin API docs (#7923) by @sapphi-red
- apis: add docs to important APIs (#7913) by @sapphi-red
- move the important APIs to the top of the sidebar (#7912) by @sapphi-red
- apis: add more content to CLI documentation (#7911) by @sapphi-red
- apis: generate CLI docs from --help output (#7910) by @sapphi-red
- add fathom analytics (#7896) by @mdong1909

### ⚡ Performance

- use u32 for string indices in string_wizard and rolldown to reduce memory usage (#7989) by @IWANABETHATGUY
- rust: remove all usages of `with_scope_tree_child_ids(true)` for `SemanticBuilder` (#7995) by @Dunqing
- renamer: skip unnecessary nested scope symbol processing (#7899) by @Dunqing
- module_loader: use ArcStr for importer_id to avoid string copy (#7922) by @shulaoda
- module_loader: defer `ModuleTaskOwner` construction until needed (#7921) by @shulaoda
- renamer: optimize symbol renaming by eliminating `rename_non_root_symbol` pass (#7867) by @Dunqing

### 🧪 Testing

- add lazy barrel optimization test cases (#7967) by @shulaoda

### ⚙️ Miscellaneous Tasks

- remove lazy barrel option (#8010) by @shulaoda
- mark watch API as experimental (#8004) by @sapphi-red
- deps: update dependency lodash-es to v4.17.23 [security] (#8001) by @renovate[bot]
- git ignore zed local config (#7988) by @IWANABETHATGUY
- setup publint for published packages (#7972) by @Copilot
- enable `tagged_template_transform ` uncondionally (#7975) by @IWANABETHATGUY
- deps: update oxc to v0.110.0 (#7964) by @renovate[bot]
- deps: update oxc apps (#7962) by @renovate[bot]
- ai: add upgrade-oxc Claude skill (#7957) by @Boshen
- deps: update rollup submodule for tests to v4.55.2 (#7959) by @sapphi-red
- deps: update test262 submodule for tests (#7960) by @sapphi-red
- deps: update crate-ci/typos action to v1.42.1 (#7961) by @renovate[bot]
- deps: update rust crates (#7951) by @renovate[bot]
- deps: update npm packages (#7953) by @renovate[bot]
- deps: update github-actions (#7952) by @renovate[bot]
- deps: update npm packages (#7950) by @renovate[bot]
- format magic-string test before write to disk (#7945) by @IWANABETHATGUY
- deps: update dependency rolldown-plugin-dts to ^0.21.0 (#7915) by @renovate[bot]
- deps: update dependency oxlint-tsgolint to v0.11.1 (#7914) by @renovate[bot]
- deps: update dependency diff to v8.0.3 [security] (#7904) by @renovate[bot]
- remove outdated TODO comment in `collect_depended_symbols` (#7888) by @shulaoda
- deps: update oxc resolver to v11.16.3 (#7876) by @renovate[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

test: vite-tests Trigger Vite tests workflow on this PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants