Skip to content

Conversation

@schiller-manuel
Copy link
Contributor

@schiller-manuel schiller-manuel commented Oct 31, 2025

Summary by CodeRabbit

  • Bug Fixes
    • Improved dead code elimination in code-splitting transformation to better track imported identifiers and remove unused dependencies from generated code.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Oct 31, 2025

Walkthrough

The core logic change refactors import declaration handling in the code-splitting compiler to construct import declarations separately from their usage, then collect and track imported identifiers via traversal for dead code elimination purposes. Approximately 200+ test snapshots are updated to remove unused Route imports, reflecting the outcome of the compiler logic modification.

Changes

Cohort / File(s) Change Summary
Source Logic
packages/router-plugin/src/core/code-splitter/compilers.ts
Refactors import declaration construction by separating the inline creation into a dedicated constant and adding traversal logic to collect ImportSpecifier node identifiers, recording them in refIdents for dead code elimination tracking.
Test Snapshots (React 1-default)
packages/router-plugin/tests/code-splitter/snapshots/react/1-default/*.tsx
Removes unused import { Route } statements from 70+ snapshot files across component, errorComponent, and notFoundComponent variants.
Test Snapshots (React 2-combined)
packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/*.tsx
Removes unused import { Route } and related unused imports from 60+ snapshot files across combined loader/component configurations.
Test Snapshots (React 3-errorComponent)
packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/*.tsx
Removes unused import { Route } statements from 70+ snapshot files in combined errorComponent-separate configuration.
Test Snapshots (Solid)
packages/router-plugin/tests/code-splitter/snapshots/solid/*/
Removes unused import { Route } statements from 6 snapshot files in Solid framework test variants.

Sequence Diagram

sequenceDiagram
    participant Compiler as Code Splitter Compiler
    participant ImportNode as ImportDeclaration Node
    participant DCE as Dead Code Elimination
    
    rect rgb(200, 230, 255)
    Note over Compiler: Old Flow: Inline Construction
    Compiler->>ImportNode: Create & Replace Inline
    ImportNode-->>Compiler: (no tracking)
    end
    
    rect rgb(200, 255, 220)
    Note over Compiler: New Flow: Separate + Track
    Compiler->>ImportNode: Construct importDecl
    Compiler->>Compiler: Traverse ImportSpecifiers
    Compiler->>DCE: Collect & Record refIdents
    Compiler->>ImportNode: Replace with importDecl
    DCE-->>Compiler: Identifiers Tracked
    end
Loading

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10–15 minutes

Rationale: The core logic change is focused and contained within one file; however, it requires understanding the code-splitting transformation pipeline and how identifier tracking integrates with dead code elimination. The ~200+ snapshot changes are highly homogeneous (repetitive import removals), which significantly reduces review complexity—verify the pattern is consistent and snapshots reflect the expected output. No public API changes detected.

Areas requiring attention:

  • Verify that the traversal logic correctly captures all ImportSpecifier identifiers from the newly created import node
  • Confirm refIdents recording integrates properly with existing DCE logic and doesn't create duplicate entries
  • Spot-check a few snapshots across different snapshot categories (react variants and solid) to ensure consistent Route import removal behavior

Possibly related PRs

Suggested labels

package: router-plugin

Suggested reviewers

  • Sheraff

Poem

🐰 A rabbit hops through splitting code,
Where imports now are better traced,
Dead code flees down the dusted road,
As identifiers find their place.
Routes removed, the snapshots sing—
Clean trails emerge from refactoring! 🌿

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The pull request title "fix: enable dead code elimination in split-route to remove unused imports" directly and accurately reflects the primary change in the codebase. The main modification is in packages/router-plugin/src/core/code-splitter/compilers.ts, which implements dead code elimination tracking by collecting local identifiers from newly created ImportSpecifier nodes and recording them in refIdents. All the remaining changes are test snapshot updates that reflect this core functionality change—they show Route imports being removed across test files, which is the expected outcome of enabling dead code elimination. The title is specific, concise, and clearly communicates both what is being enabled and the purpose of the change.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch dce-split

Comment @coderabbitai help to get the list of available commands and usage tips.

@nx-cloud
Copy link

nx-cloud bot commented Oct 31, 2025

View your CI Pipeline Execution ↗ for commit 60a0dda

Command Status Duration Result
nx affected --targets=test:eslint,test:unit,tes... ✅ Succeeded 9m 52s View ↗
nx run-many --target=build --exclude=examples/*... ✅ Succeeded 26s View ↗

☁️ Nx Cloud last updated this comment at 2025-10-31 19:35:13 UTC

@pkg-pr-new
Copy link

pkg-pr-new bot commented Oct 31, 2025

More templates

@tanstack/arktype-adapter

npm i https://pkg.pr.new/TanStack/router/@tanstack/arktype-adapter@5711

@tanstack/directive-functions-plugin

npm i https://pkg.pr.new/TanStack/router/@tanstack/directive-functions-plugin@5711

@tanstack/eslint-plugin-router

npm i https://pkg.pr.new/TanStack/router/@tanstack/eslint-plugin-router@5711

@tanstack/history

npm i https://pkg.pr.new/TanStack/router/@tanstack/history@5711

@tanstack/nitro-v2-vite-plugin

npm i https://pkg.pr.new/TanStack/router/@tanstack/nitro-v2-vite-plugin@5711

@tanstack/react-router

npm i https://pkg.pr.new/TanStack/router/@tanstack/react-router@5711

@tanstack/react-router-devtools

npm i https://pkg.pr.new/TanStack/router/@tanstack/react-router-devtools@5711

@tanstack/react-router-ssr-query

npm i https://pkg.pr.new/TanStack/router/@tanstack/react-router-ssr-query@5711

@tanstack/react-start

npm i https://pkg.pr.new/TanStack/router/@tanstack/react-start@5711

@tanstack/react-start-client

npm i https://pkg.pr.new/TanStack/router/@tanstack/react-start-client@5711

@tanstack/react-start-server

npm i https://pkg.pr.new/TanStack/router/@tanstack/react-start-server@5711

@tanstack/router-cli

npm i https://pkg.pr.new/TanStack/router/@tanstack/router-cli@5711

@tanstack/router-core

npm i https://pkg.pr.new/TanStack/router/@tanstack/router-core@5711

@tanstack/router-devtools

npm i https://pkg.pr.new/TanStack/router/@tanstack/router-devtools@5711

@tanstack/router-devtools-core

npm i https://pkg.pr.new/TanStack/router/@tanstack/router-devtools-core@5711

@tanstack/router-generator

npm i https://pkg.pr.new/TanStack/router/@tanstack/router-generator@5711

@tanstack/router-plugin

npm i https://pkg.pr.new/TanStack/router/@tanstack/router-plugin@5711

@tanstack/router-ssr-query-core

npm i https://pkg.pr.new/TanStack/router/@tanstack/router-ssr-query-core@5711

@tanstack/router-utils

npm i https://pkg.pr.new/TanStack/router/@tanstack/router-utils@5711

@tanstack/router-vite-plugin

npm i https://pkg.pr.new/TanStack/router/@tanstack/router-vite-plugin@5711

@tanstack/server-functions-plugin

npm i https://pkg.pr.new/TanStack/router/@tanstack/server-functions-plugin@5711

@tanstack/solid-router

npm i https://pkg.pr.new/TanStack/router/@tanstack/solid-router@5711

@tanstack/solid-router-devtools

npm i https://pkg.pr.new/TanStack/router/@tanstack/solid-router-devtools@5711

@tanstack/solid-router-ssr-query

npm i https://pkg.pr.new/TanStack/router/@tanstack/solid-router-ssr-query@5711

@tanstack/solid-start

npm i https://pkg.pr.new/TanStack/router/@tanstack/solid-start@5711

@tanstack/solid-start-client

npm i https://pkg.pr.new/TanStack/router/@tanstack/solid-start-client@5711

@tanstack/solid-start-server

npm i https://pkg.pr.new/TanStack/router/@tanstack/solid-start-server@5711

@tanstack/start-client-core

npm i https://pkg.pr.new/TanStack/router/@tanstack/start-client-core@5711

@tanstack/start-plugin-core

npm i https://pkg.pr.new/TanStack/router/@tanstack/start-plugin-core@5711

@tanstack/start-server-core

npm i https://pkg.pr.new/TanStack/router/@tanstack/start-server-core@5711

@tanstack/start-static-server-functions

npm i https://pkg.pr.new/TanStack/router/@tanstack/start-static-server-functions@5711

@tanstack/start-storage-context

npm i https://pkg.pr.new/TanStack/router/@tanstack/start-storage-context@5711

@tanstack/valibot-adapter

npm i https://pkg.pr.new/TanStack/router/@tanstack/valibot-adapter@5711

@tanstack/virtual-file-routes

npm i https://pkg.pr.new/TanStack/router/@tanstack/virtual-file-routes@5711

@tanstack/zod-adapter

npm i https://pkg.pr.new/TanStack/router/@tanstack/zod-adapter@5711

commit: 60a0dda

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Comment on lines +730 to +756
const importDecl = t.importDeclaration(
path.node.declaration.declarations.map((decl) =>
t.importSpecifier(
t.identifier((decl.id as any).name),
t.identifier((decl.id as any).name),
),
),
t.stringLiteral(
removeSplitSearchParamFromFilename(opts.filename),
),
)

path.replaceWith(importDecl)

// Track the imported identifier paths so deadCodeElimination can remove them if unused
// We need to traverse the newly created import to get the identifier paths
path.traverse({
Identifier(identPath) {
// Only track the local binding identifiers (the imported names)
if (
identPath.parentPath.isImportSpecifier() &&
identPath.key === 'local'
) {
refIdents.add(identPath)
}
},
})
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion | 🟠 Major

Good refactor for dead code elimination, but add type safety for destructured patterns.

The refactor correctly separates import declaration construction and adds traversal to track imported identifiers for dead code elimination. However, lines 733-734 use (decl.id as any).name without verifying that decl.id is actually an Identifier.

Variable declarations can have destructured patterns (e.g., export const { x, y } = obj), which would cause a runtime error since ObjectPattern doesn't have a .name property.

Apply this diff to add type safety:

                const importDecl = t.importDeclaration(
-                  path.node.declaration.declarations.map((decl) =>
-                    t.importSpecifier(
-                      t.identifier((decl.id as any).name),
-                      t.identifier((decl.id as any).name),
+                  path.node.declaration.declarations.flatMap((decl) => {
+                    if (!t.isIdentifier(decl.id)) {
+                      throw new Error(
+                        `Destructured export patterns are not supported in code-split routes. Found pattern in ${opts.filename}`
+                      )
+                    }
+                    return t.importSpecifier(
+                      t.identifier(decl.id.name),
+                      t.identifier(decl.id.name),
                    ),
-                  ),
+                  }),
                  t.stringLiteral(
                    removeSplitSearchParamFromFilename(opts.filename),
                  ),
                )
🤖 Prompt for AI Agents
In packages/router-plugin/src/core/code-splitter/compilers.ts around lines 730
to 756, the code assumes decl.id is an Identifier and accesses (decl.id as
any).name which will crash for destructured patterns; update the logic to first
check t.isIdentifier(decl.id) and use its .name for the importSpecifier, and for
non-identifiers (ObjectPattern/ArrayPattern) extract the underlying identifier
names by walking the pattern (properties/elements) and creating importSpecifiers
for each target Identifier; skip or log unsupported pattern types and ensure
only Identifier names are passed to t.identifier to avoid runtime errors.

@schiller-manuel schiller-manuel merged commit 6f744c2 into main Oct 31, 2025
6 checks passed
@schiller-manuel schiller-manuel deleted the dce-split branch October 31, 2025 19:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants