Skip to content
Draft
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
134 changes: 128 additions & 6 deletions packages/router-plugin/src/core/code-splitter/compilers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -628,6 +628,34 @@ export function compileCodeSplitVirtualRoute(
if (t.isIdentifier(splitNode.id)) {
splitMeta.localExporterIdent = splitNode.id.name
splitMeta.shouldRemoveNode = false
} else if (t.isObjectPattern(splitNode.id) && t.isIdentifier(splitKey.node)) {
const matchingProperty = splitNode.id.properties.find((prop) => {
if (!t.isObjectProperty(prop)) {
return false
}

if (t.isIdentifier(prop.value)) {
return prop.value.name === splitKey.node.name
}

if (
t.isAssignmentPattern(prop.value) &&
t.isIdentifier(prop.value.left)
) {
return prop.value.left.name === splitKey.node.name
}

return false
})

if (!matchingProperty) {
throw new Error(
`Unable to locate the "${splitKey.node.name}" binding while splitting "${SPLIT_TYPE}".`,
)
}

splitMeta.localExporterIdent = splitKey.node.name
splitMeta.shouldRemoveNode = false
} else {
throw new Error(
`Unexpected splitNode type ☝️: ${splitNode.type}`,
Expand Down Expand Up @@ -731,13 +759,75 @@ export function compileCodeSplitVirtualRoute(

if (path.node.declaration) {
if (t.isVariableDeclaration(path.node.declaration)) {
const specifiers = path.node.declaration.declarations.flatMap(
(decl) => {
if (!t.isVariableDeclarator(decl)) {
return []
}

const identifiers: Array<t.Identifier> = []

const collectIdentifiers = (
node: t.Node | null | undefined,
) => {
if (!node) {
return
}

if (t.isIdentifier(node)) {
identifiers.push(node)
return
}

if (t.isAssignmentPattern(node)) {
collectIdentifiers(node.left)
return
}

if (t.isRestElement(node)) {
collectIdentifiers(node.argument)
return
}

if (t.isObjectPattern(node)) {
node.properties.forEach((prop) => {
if (t.isObjectProperty(prop)) {
collectIdentifiers(prop.value as t.Node)
} else if (t.isRestElement(prop)) {
collectIdentifiers(prop.argument)
}
})
return
}

if (t.isArrayPattern(node)) {
node.elements.forEach((element) => {
if (!element) {
return
}
collectIdentifiers(element as t.Node)
})
}
}

collectIdentifiers(decl.id)

return identifiers.map((identifier) =>
t.importSpecifier(
t.identifier(identifier.name),
t.identifier(identifier.name),
),
)
},
)

if (specifiers.length === 0) {
path.remove()
return
}

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),
),
),
specifiers,
t.stringLiteral(
removeSplitSearchParamFromFilename(opts.filename),
),
Expand Down Expand Up @@ -943,6 +1033,38 @@ function resolveIdentifier(path: any, node: any): t.Node | undefined {
function removeIdentifierLiteral(path: babel.NodePath, node: t.Identifier) {
const binding = path.scope.getBinding(node.name)
if (binding) {
if (
t.isVariableDeclarator(binding.path.node) &&
t.isObjectPattern(binding.path.node.id)
) {
const objectPattern = binding.path.node.id
objectPattern.properties = objectPattern.properties.filter((prop) => {
if (!t.isObjectProperty(prop)) {
return true
}

if (t.isIdentifier(prop.value) && prop.value.name === node.name) {
return false
}

if (
t.isAssignmentPattern(prop.value) &&
t.isIdentifier(prop.value.left) &&
prop.value.left.name === node.name
) {
return false
}

return true
})

if (objectPattern.properties.length === 0) {
binding.path.remove()
}

return
}

binding.path.remove()
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
const $$splitComponentImporter = () => import('destructured-export.tsx?tsr-split=component');
import { lazyRouteComponent } from '@tanstack/react-router';
import { createFileRoute } from '@tanstack/react-router';
const createBits = () => ({
component: AboutComponentImpl,
loader: () => ({
message: 'hello'
})
});
const fallbackLoader = () => ({
message: 'fallback'
});
const {
loader = fallbackLoader
} = createBits();
function AboutComponentImpl() {
return <div>About</div>;
}
export const Route = createFileRoute('/about')({
component: lazyRouteComponent($$splitComponentImporter, 'component'),
loader
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
const createBits = () => ({
component: AboutComponentImpl,
loader: () => ({
message: 'hello'
})
});
function DefaultAboutComponent() {
return <div>Default About</div>;
}
const {
component: AboutComponent = DefaultAboutComponent
} = createBits();
function AboutComponentImpl() {
return <div>About</div>;
}
export { AboutComponent as component };
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
const $$splitComponentImporter = () => import('retain-exports-destructured.tsx?tsr-split=component');
import { lazyRouteComponent } from '@tanstack/react-router';
import { createFileRoute } from '@tanstack/react-router';
const createBits = () => ({
component: AboutComponentImpl,
loader: () => ({
message: 'hello'
})
});
export const {
loader
} = createBits();
function AboutComponentImpl() {
return <div>About</div>;
}
export const Route = createFileRoute('/about')({
component: lazyRouteComponent($$splitComponentImporter, 'component'),
loader
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
import { AboutComponent } from "retain-exports-destructured.tsx";
export { AboutComponent as component };
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
const $$splitLoaderImporter = () => import('destructured-export.tsx?tsr-split=loader');
import { lazyFn } from '@tanstack/react-router';
const $$splitComponentImporter = () => import('destructured-export.tsx?tsr-split=component---errorComponent---notFoundComponent---pendingComponent');
import { lazyRouteComponent } from '@tanstack/react-router';
import { createFileRoute } from '@tanstack/react-router';
export const Route = createFileRoute('/about')({
component: lazyRouteComponent($$splitComponentImporter, 'component'),
loader: lazyFn($$splitLoaderImporter, 'loader')
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
const createBits = () => ({
component: AboutComponentImpl,
loader: () => ({
message: 'hello'
})
});
function DefaultAboutComponent() {
return <div>Default About</div>;
}
const {
component: AboutComponent = DefaultAboutComponent
} = createBits();
function AboutComponentImpl() {
return <div>About</div>;
}
export { AboutComponent as component };
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
const createBits = () => ({
component: AboutComponentImpl,
loader: () => ({
message: 'hello'
})
});
const fallbackLoader = () => ({
message: 'fallback'
});
const {
loader = fallbackLoader
} = createBits();
function AboutComponentImpl() {
return <div>About</div>;
}
export { loader };
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
const $$splitLoaderImporter = () => import('retain-exports-destructured.tsx?tsr-split=loader');
import { lazyFn } from '@tanstack/react-router';
const $$splitComponentImporter = () => import('retain-exports-destructured.tsx?tsr-split=component---errorComponent---notFoundComponent---pendingComponent');
import { lazyRouteComponent } from '@tanstack/react-router';
import { createFileRoute } from '@tanstack/react-router';
export const Route = createFileRoute('/about')({
component: lazyRouteComponent($$splitComponentImporter, 'component'),
loader: lazyFn($$splitLoaderImporter, 'loader')
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
import { AboutComponent } from "retain-exports-destructured.tsx";
export { AboutComponent as component };
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
import { loader } from "retain-exports-destructured.tsx";
export { loader };
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
const $$splitLoaderImporter = () => import('destructured-export.tsx?tsr-split=component---loader---notFoundComponent---pendingComponent');
import { lazyFn } from '@tanstack/react-router';
const $$splitComponentImporter = () => import('destructured-export.tsx?tsr-split=component---loader---notFoundComponent---pendingComponent');
import { lazyRouteComponent } from '@tanstack/react-router';
import { createFileRoute } from '@tanstack/react-router';
export const Route = createFileRoute('/about')({
component: lazyRouteComponent($$splitComponentImporter, 'component'),
loader: lazyFn($$splitLoaderImporter, 'loader')
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
const createBits = () => ({
component: AboutComponentImpl,
loader: () => ({
message: 'hello'
})
});
function DefaultAboutComponent() {
return <div>Default About</div>;
}
const fallbackLoader = () => ({
message: 'fallback'
});
const {
component: AboutComponent = DefaultAboutComponent,
loader = fallbackLoader
} = createBits();
function AboutComponentImpl() {
return <div>About</div>;
}
export { loader };
export { AboutComponent as component };
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
const $$splitLoaderImporter = () => import('retain-exports-destructured.tsx?tsr-split=component---loader---notFoundComponent---pendingComponent');
import { lazyFn } from '@tanstack/react-router';
const $$splitComponentImporter = () => import('retain-exports-destructured.tsx?tsr-split=component---loader---notFoundComponent---pendingComponent');
import { lazyRouteComponent } from '@tanstack/react-router';
import { createFileRoute } from '@tanstack/react-router';
export const Route = createFileRoute('/about')({
component: lazyRouteComponent($$splitComponentImporter, 'component'),
loader: lazyFn($$splitLoaderImporter, 'loader')
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { AboutComponent, loader } from "retain-exports-destructured.tsx";
export { loader };
export { AboutComponent as component };
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
const $$splitComponentImporter = () => import('destructured-export.tsx?tsr-split=component');
import { lazyRouteComponent } from '@tanstack/solid-router';
import { createFileRoute } from '@tanstack/solid-router';
const createBits = () => ({
component: AboutComponentImpl,
loader: () => ({
message: 'hello'
})
});
const fallbackLoader = () => ({
message: 'fallback'
});
const {
loader = fallbackLoader
} = createBits();
function AboutComponentImpl() {
return <div>About</div>;
}
export const Route = createFileRoute('/about')({
component: lazyRouteComponent($$splitComponentImporter, 'component'),
loader
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
const createBits = () => ({
component: AboutComponentImpl,
loader: () => ({
message: 'hello'
})
});
function DefaultAboutComponent() {
return <div>Default About</div>;
}
const {
component: AboutComponent = DefaultAboutComponent
} = createBits();
function AboutComponentImpl() {
return <div>About</div>;
}
export { AboutComponent as component };
Loading
Loading