Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 24 additions & 10 deletions packages/router-plugin/src/core/code-splitter/compilers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -727,19 +727,33 @@ export function compileCodeSplitVirtualRoute(

if (path.node.declaration) {
if (t.isVariableDeclaration(path.node.declaration)) {
path.replaceWith(
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),
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)
}
},
})
Comment on lines +730 to +756
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.

}
}
},
Expand Down
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
import * as React from 'react';
import { Route } from "arrow-function.tsx";
import * as React from 'react';
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
import * as React from 'react';
import { Route } from "arrow-function.tsx";
import * as React from 'react';
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
// Test errorComponent with false literal
import { Route } from "boolean-null-literals.tsx";
const SplitComponent = () => <div>Test Component</div>;
export { SplitComponent as component };
Original file line number Diff line number Diff line change
@@ -1,2 +0,0 @@
// Test errorComponent with false literal
import { Route } from "boolean-null-literals.tsx";
Original file line number Diff line number Diff line change
@@ -1,2 +0,0 @@
// Test errorComponent with false literal
import { Route } from "boolean-null-literals.tsx";
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import * as React from 'react';
import { Route } from "chinese.tsx";
function HomeComponent() {
return <div className="p-2">
<Demo title="标题很好看,谁说不是呢?" />
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import * as React from 'react';
import { Route } from "chinese.tsx";
interface DemoProps {
title: string;
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import * as React from 'react';
import { Route } from "chinese.tsx";
interface DemoProps {
title: string;
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,4 @@ function OtherComponent() {
});
return <div>App component name is {componentName}</div>;
}
import { Route } from "circular-reference-arrow-function.tsx";
export { App as component };
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,4 @@ function OtherComponent() {
App
});
return <div>App component name is {componentName}</div>;
}
import { Route } from "circular-reference-arrow-function.tsx";
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,4 @@ function OtherComponent() {
App
});
return <div>App component name is {componentName}</div>;
}
import { Route } from "circular-reference-arrow-function.tsx";
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,4 @@ function OtherComponent() {
});
return <div>App component name is {componentName}</div>;
}
import { Route } from "circular-reference-function.tsx";
export { App as component };
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,4 @@ function OtherComponent() {
App
});
return <div>App component name is {componentName}</div>;
}
import { Route } from "circular-reference-function.tsx";
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,4 @@ function OtherComponent() {
App
});
return <div>App component name is {componentName}</div>;
}
import { Route } from "circular-reference-function.tsx";
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { isEnabled } from '@features/feature-flags';
import TrueImport from '@modules/true-component';
import { FalseComponent } from '@modules/false-component';
import { Route } from "conditional-properties.tsx";
const SplitComponent = isEnabled ? TrueImport.Component : FalseComponent;
export { SplitComponent as component };
Original file line number Diff line number Diff line change
@@ -1 +0,0 @@
import { Route } from "conditional-properties.tsx";
Original file line number Diff line number Diff line change
@@ -1 +0,0 @@
import { Route } from "conditional-properties.tsx";
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { memo } from 'react';
import { Route } from "destructured-react-memo-imported-component.tsx";
function Component() {
return <div>Component</div>;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1 +0,0 @@
import { Route } from "destructured-react-memo-imported-component.tsx";
Original file line number Diff line number Diff line change
@@ -1 +0,0 @@
import { Route } from "destructured-react-memo-imported-component.tsx";
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
import React from 'react';
import { Route } from "explicit-undefined-component.tsx";
import React from 'react';
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
import React from 'react';
import { Route } from "explicit-undefined-component.tsx";
import React from 'react';
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
import React from 'react';
import { Route } from "explicit-undefined-component.tsx";
import React from 'react';
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
import React from 'react';
import { Route } from "export-default-component-and-normal-notFound.tsx";
import React from 'react';
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
import React from 'react';
import { Route } from "export-default-component-and-normal-notFound.tsx";
import React from 'react';
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import React from 'react';
import { Route } from "export-default-component-and-normal-notFound.tsx";
function NotFoundComponent() {
return <div>Not Found</div>;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
import React from 'react';
import { Route } from "export-default-component.tsx";
import React from 'react';
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
import React from 'react';
import { Route } from "export-default-component.tsx";
import React from 'react';
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
import React from 'react';
import { Route } from "export-default-component.tsx";
import React from 'react';
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
import * as React from 'react';
import { Route } from "function-declaration.tsx";
import * as React from 'react';
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
import * as React from 'react';
import { Route } from "function-declaration.tsx";
import * as React from 'react';
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { test } from './test' with { type: 'macro' };
import { Route } from "importAttribute.tsx";
const SplitComponent = () => test;
export { SplitComponent as component };
Original file line number Diff line number Diff line change
@@ -1 +0,0 @@
import { Route } from "importAttribute.tsx";
Original file line number Diff line number Diff line change
@@ -1 +0,0 @@
import { Route } from "importAttribute.tsx";
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import importedComponent from '../../shared/imported';
import { Route } from "imported-default-component-destructured-loader.tsx";
const SplitComponent = importedComponent;
export { SplitComponent as component };
Original file line number Diff line number Diff line change
@@ -1 +0,0 @@
import { Route } from "imported-default-component-destructured-loader.tsx";
Original file line number Diff line number Diff line change
@@ -1 +0,0 @@
import { Route } from "imported-default-component-destructured-loader.tsx";
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import ImportedDefaultComponent from '../../shared/imported';
import { Route } from "imported-default-component.tsx";
const SplitComponent = ImportedDefaultComponent;
export { SplitComponent as component };
Original file line number Diff line number Diff line change
@@ -1 +0,0 @@
import { Route } from "imported-default-component.tsx";
Original file line number Diff line number Diff line change
@@ -1 +0,0 @@
import { Route } from "imported-default-component.tsx";
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import ImportedDefaultComponent from '../../shared/imported';
import { Route } from "imported-errorComponent.tsx";
const SplitComponent = ImportedDefaultComponent;
export { SplitComponent as component };
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { importedErrorComponent } from '../../shared/imported';
import { Route } from "imported-errorComponent.tsx";
const SplitErrorComponent = importedErrorComponent;
export { SplitErrorComponent as errorComponent };
Original file line number Diff line number Diff line change
@@ -1 +0,0 @@
import { Route } from "imported-errorComponent.tsx";
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import ImportedDefaultComponent from '../../shared/imported';
import { Route } from "imported-notFoundComponent.tsx";
const SplitComponent = ImportedDefaultComponent;
export { SplitComponent as component };
Original file line number Diff line number Diff line change
@@ -1 +0,0 @@
import { Route } from "imported-notFoundComponent.tsx";
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { importedNotFoundComponent } from '../../shared/imported';
import { Route } from "imported-notFoundComponent.tsx";
const SplitNotFoundComponent = importedNotFoundComponent;
export { SplitNotFoundComponent as notFoundComponent };
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import ImportedDefaultComponent from '../../shared/imported';
import { Route } from "imported-pendingComponent.tsx";
const SplitComponent = ImportedDefaultComponent;
export { SplitComponent as component };
Original file line number Diff line number Diff line change
@@ -1 +0,0 @@
import { Route } from "imported-pendingComponent.tsx";
Original file line number Diff line number Diff line change
@@ -1 +0,0 @@
import { Route } from "imported-pendingComponent.tsx";
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { importedComponent } from '../../shared';
import { Route } from "imported.tsx";
const SplitComponent = importedComponent;
export { SplitComponent as component };
Original file line number Diff line number Diff line change
@@ -1 +0,0 @@
import { Route } from "imported.tsx";
Original file line number Diff line number Diff line change
@@ -1 +0,0 @@
import { Route } from "imported.tsx";
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import * as React from 'react';
import { Route } from "inline.tsx";
Route.addChildren([]);
import { test } from "inline.tsx";
Route.addChildren([]);
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import * as React from 'react';
import { Route } from "inline.tsx";
Route.addChildren([]);
import { test } from "inline.tsx";
Route.addChildren([]);
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,9 @@ import agGridImage from '~/images/ag-grid.png';
import nozzleImage from '~/images/nozzle.png';
import bytesImage from '~/images/bytes.svg';
import bytesUidotdevImage from '~/images/bytes-uidotdev.png';
import { textColors } from "random-number.tsx";
import { gradients } from "random-number.tsx";
const courses = [{
name: 'The Official TanStack React Query Course',
cardStyles: `border-t-4 border-red-500 hover:(border-green-500)`,
href: 'https://query.gg/?s=tanstack',
description: `Learn how to build enterprise quality apps with TanStack's React Query the easy way with our brand new course.`
}];
import { Route } from "random-number.tsx";
}];
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,9 @@ import agGridImage from '~/images/ag-grid.png';
import nozzleImage from '~/images/nozzle.png';
import bytesImage from '~/images/bytes.svg';
import bytesUidotdevImage from '~/images/bytes-uidotdev.png';
import { textColors } from "random-number.tsx";
import { gradients } from "random-number.tsx";
const courses = [{
name: 'The Official TanStack React Query Course',
cardStyles: `border-t-4 border-red-500 hover:(border-green-500)`,
href: 'https://query.gg/?s=tanstack',
description: `Learn how to build enterprise quality apps with TanStack's React Query the easy way with our brand new course.`
}];
import { Route } from "random-number.tsx";
}];
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import React from 'react';
import { Route } from "react-memo-component.tsx";
function Component() {
return <div>Component</div>;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1 +0,0 @@
import { Route } from "react-memo-component.tsx";
Original file line number Diff line number Diff line change
@@ -1 +0,0 @@
import { Route } from "react-memo-component.tsx";
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import React from 'react';
import { importedComponent } from '../../shared/imported';
import { Route } from "react-memo-imported-component.tsx";
const SplitComponent = React.memo(importedComponent);
export { SplitComponent as component };
Original file line number Diff line number Diff line change
@@ -1 +0,0 @@
import { Route } from "react-memo-imported-component.tsx";
Original file line number Diff line number Diff line change
@@ -1 +0,0 @@
import { Route } from "react-memo-imported-component.tsx";
Loading
Loading