Wir danken dem Remix-Team für die Pionierarbeit beim Konzept der virtuellen Dateirouten. Wir haben uns von ihrer Arbeit inspirieren lassen und sie angepasst, um mit der bestehenden dateibasierten Routengenerierung von TanStack Router zu funktionieren.
Virtuelle Dateirouten sind ein mächtiges Konzept, das es Ihnen ermöglicht, einen Routenbaum programmatisch mit Code zu erstellen, der auf reale Dateien in Ihrem Projekt verweist. Dies kann nützlich sein, wenn
Hier ist ein kurzes Beispiel für die Verwendung von virtuellen Dateirouten, um einen Routenbaum auf eine Reihe von realen Dateien in Ihrem Projekt abzubilden
// routes.ts
import {
rootRoute,
route,
index,
layout,
physical,
} from '@tanstack/virtual-file-routes'
export const routes = rootRoute('root.tsx', [
index('index.tsx'),
layout('pathlessLayout.tsx', [
route('/dashboard', 'app/dashboard.tsx', [
index('app/dashboard-index.tsx'),
route('/invoices', 'app/dashboard-invoices.tsx', [
index('app/invoices-index.tsx'),
route('$id', 'app/invoice-detail.tsx'),
]),
]),
physical('/posts', 'posts'),
]),
])
// routes.ts
import {
rootRoute,
route,
index,
layout,
physical,
} from '@tanstack/virtual-file-routes'
export const routes = rootRoute('root.tsx', [
index('index.tsx'),
layout('pathlessLayout.tsx', [
route('/dashboard', 'app/dashboard.tsx', [
index('app/dashboard-index.tsx'),
route('/invoices', 'app/dashboard-invoices.tsx', [
index('app/invoices-index.tsx'),
route('$id', 'app/invoice-detail.tsx'),
]),
]),
physical('/posts', 'posts'),
]),
])
Virtuelle Dateirouten können entweder konfiguriert werden über
Wenn Sie das TanStackRouter Plugin für Vite/Rspack/Webpack verwenden, können Sie virtuelle Dateirouten konfigurieren, indem Sie den Pfad Ihrer Routendatei an die Option virtualRoutesConfig übergeben, wenn Sie das Plugin einrichten
// vite.config.ts
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import { tanstackRouter } from '@tanstack/router-plugin/vite'
export default defineConfig({
plugins: [
tanstackRouter({
target: 'react',
virtualRouteConfig: './routes.ts',
}),
react(),
],
})
// vite.config.ts
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import { tanstackRouter } from '@tanstack/router-plugin/vite'
export default defineConfig({
plugins: [
tanstackRouter({
target: 'react',
virtualRouteConfig: './routes.ts',
}),
react(),
],
})
Oder Sie wählen, die virtuellen Routen direkt in der Konfiguration zu definieren
// vite.config.ts
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import { tanstackRouter } from '@tanstack/router-plugin/vite'
import { rootRoute } from '@tanstack/virtual-file-routes'
const routes = rootRoute('root.tsx', [
// ... the rest of your virtual route tree
])
export default defineConfig({
plugins: [tanstackRouter({ virtualRouteConfig: routes }), react()],
})
// vite.config.ts
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import { tanstackRouter } from '@tanstack/router-plugin/vite'
import { rootRoute } from '@tanstack/virtual-file-routes'
const routes = rootRoute('root.tsx', [
// ... the rest of your virtual route tree
])
export default defineConfig({
plugins: [tanstackRouter({ virtualRouteConfig: routes }), react()],
})
Um virtuelle Dateirouten zu erstellen, müssen Sie das Paket @tanstack/virtual-file-routes importieren. Dieses Paket stellt eine Reihe von Funktionen bereit, mit denen Sie virtuelle Routen erstellen können, die auf reale Dateien in Ihrem Projekt verweisen. Einige Hilfsfunktionen werden aus dem Paket exportiert
Die Funktion rootRoute wird verwendet, um eine virtuelle Root-Route zu erstellen. Sie nimmt einen Dateinamen und ein Array von Kind-Routen entgegen. Hier ist ein Beispiel für eine virtuelle Root-Route
// routes.ts
import { rootRoute } from '@tanstack/virtual-file-routes'
export const routes = rootRoute('root.tsx', [
// ... children routes
])
// routes.ts
import { rootRoute } from '@tanstack/virtual-file-routes'
export const routes = rootRoute('root.tsx', [
// ... children routes
])
Die Funktion route wird verwendet, um eine virtuelle Route zu erstellen. Sie nimmt einen Pfad, einen Dateinamen und ein Array von Kind-Routen entgegen. Hier ist ein Beispiel für eine virtuelle Route
// routes.ts
import { route } from '@tanstack/virtual-file-routes'
export const routes = rootRoute('root.tsx', [
route('/about', 'about.tsx', [
// ... children routes
]),
])
// routes.ts
import { route } from '@tanstack/virtual-file-routes'
export const routes = rootRoute('root.tsx', [
route('/about', 'about.tsx', [
// ... children routes
]),
])
Sie können auch eine virtuelle Route ohne Dateinamen definieren. Dies ermöglicht es, ein gemeinsames Pfadpräfix für seine Kinder festzulegen
// routes.ts
import { route } from '@tanstack/virtual-file-routes'
export const routes = rootRoute('root.tsx', [
route('/hello', [
route('/world', 'world.tsx'), // full path will be "/hello/world"
route('/universe', 'universe.tsx'), // full path will be "/hello/universe"
]),
])
// routes.ts
import { route } from '@tanstack/virtual-file-routes'
export const routes = rootRoute('root.tsx', [
route('/hello', [
route('/world', 'world.tsx'), // full path will be "/hello/world"
route('/universe', 'universe.tsx'), // full path will be "/hello/universe"
]),
])
Die Funktion index wird verwendet, um eine virtuelle Index-Route zu erstellen. Sie nimmt einen Dateinamen entgegen. Hier ist ein Beispiel für eine virtuelle Index-Route
import { index } from '@tanstack/virtual-file-routes'
const routes = rootRoute('root.tsx', [index('index.tsx')])
import { index } from '@tanstack/virtual-file-routes'
const routes = rootRoute('root.tsx', [index('index.tsx')])
Die Funktion layout wird verwendet, um eine virtuelle pfadlose Route zu erstellen. Sie nimmt einen Dateinamen, ein Array von Kind-Routen und eine optionale pfadlose ID entgegen. Hier ist ein Beispiel für eine virtuelle pfadlose Route
// routes.ts
import { layout } from '@tanstack/virtual-file-routes'
export const routes = rootRoute('root.tsx', [
layout('pathlessLayout.tsx', [
// ... children routes
]),
])
// routes.ts
import { layout } from '@tanstack/virtual-file-routes'
export const routes = rootRoute('root.tsx', [
layout('pathlessLayout.tsx', [
// ... children routes
]),
])
Sie können auch eine pfadlose ID angeben, um der Route eine eindeutige Kennung zu geben, die sich vom Dateinamen unterscheidet
// routes.ts
import { layout } from '@tanstack/virtual-file-routes'
export const routes = rootRoute('root.tsx', [
layout('my-pathless-layout-id', 'pathlessLayout.tsx', [
// ... children routes
]),
])
// routes.ts
import { layout } from '@tanstack/virtual-file-routes'
export const routes = rootRoute('root.tsx', [
layout('my-pathless-layout-id', 'pathlessLayout.tsx', [
// ... children routes
]),
])
Physische virtuelle Routen sind eine Möglichkeit, ein Verzeichnis der guten alten TanStack Router dateibasierten Routing-Konvention unter einem bestimmten URL-Pfad zu "mounten". Dies kann nützlich sein, wenn Sie virtuelle Routen verwenden, um einen kleinen Teil Ihres Routenbaums weit oben in der Hierarchie anzupassen, aber die Standard-Dateibasierte Routing-Konvention für Unterrouten und Verzeichnisse verwenden möchten.
Betrachten Sie die folgende Dateistruktur
/routes
├── root.tsx
├── index.tsx
├── pathlessLayout.tsx
├── app
│ ├── dashboard.tsx
│ ├── dashboard-index.tsx
│ ├── dashboard-invoices.tsx
│ ├── invoices-index.tsx
│ ├── invoice-detail.tsx
└── posts
├── index.tsx
├── $postId.tsx
├── $postId.edit.tsx
├── comments/
│ ├── index.tsx
│ ├── $commentId.tsx
└── likes/
├── index.tsx
├── $likeId.tsx
/routes
├── root.tsx
├── index.tsx
├── pathlessLayout.tsx
├── app
│ ├── dashboard.tsx
│ ├── dashboard-index.tsx
│ ├── dashboard-invoices.tsx
│ ├── invoices-index.tsx
│ ├── invoice-detail.tsx
└── posts
├── index.tsx
├── $postId.tsx
├── $postId.edit.tsx
├── comments/
│ ├── index.tsx
│ ├── $commentId.tsx
└── likes/
├── index.tsx
├── $likeId.tsx
Verwenden wir virtuelle Routen, um unseren Routenbaum für alles außer posts anzupassen, und verwenden dann physische virtuelle Routen, um das Verzeichnis posts unter dem Pfad /posts zu mounten
// routes.ts
export const routes = rootRoute('root.tsx', [
// Set up your virtual routes as normal
index('index.tsx'),
layout('pathlessLayout.tsx', [
route('/dashboard', 'app/dashboard.tsx', [
index('app/dashboard-index.tsx'),
route('/invoices', 'app/dashboard-invoices.tsx', [
index('app/invoices-index.tsx'),
route('$id', 'app/invoice-detail.tsx'),
]),
]),
// Mount the `posts` directory under the `/posts` path
physical('/posts', 'posts'),
]),
])
// routes.ts
export const routes = rootRoute('root.tsx', [
// Set up your virtual routes as normal
index('index.tsx'),
layout('pathlessLayout.tsx', [
route('/dashboard', 'app/dashboard.tsx', [
index('app/dashboard-index.tsx'),
route('/invoices', 'app/dashboard-invoices.tsx', [
index('app/invoices-index.tsx'),
route('$id', 'app/invoice-detail.tsx'),
]),
]),
// Mount the `posts` directory under the `/posts` path
physical('/posts', 'posts'),
]),
])
Der vorherige Abschnitt zeigte Ihnen, wie Sie die dateibasierte Routing-Konvention von TanStack Router innerhalb einer virtuellen Routenkonfiguration verwenden können. Das Gegenteil ist jedoch auch möglich.
Sie können den Hauptteil des Routenbaums Ihrer App mit der dateibasierten Routing-Konvention von TanStack Router konfigurieren und für bestimmte Unterbäume die virtuelle Routenkonfiguration aktivieren.
Betrachten Sie die folgende Dateistruktur
/routes
├── __root.tsx
├── foo
│ ├── bar
│ │ ├── __virtual.ts
│ │ ├── details.tsx
│ │ ├── home.tsx
│ │ └── route.ts
│ └── bar.tsx
└── index.tsx
/routes
├── __root.tsx
├── foo
│ ├── bar
│ │ ├── __virtual.ts
│ │ ├── details.tsx
│ │ ├── home.tsx
│ │ └── route.ts
│ └── bar.tsx
└── index.tsx
Betrachten wir das Verzeichnis bar, das eine spezielle Datei namens __virtual.ts enthält. Diese Datei weist den Generator an, für dieses Verzeichnis (und seine Unterverzeichnisse) zur virtuellen Dateiroutenkonfiguration zu wechseln.
__virtual.ts konfiguriert die virtuellen Routen für diesen speziellen Teilbaum des Routenbaums. Es verwendet die gleiche API wie oben beschrieben, mit dem einzigen Unterschied, dass für diesen Teilbaum keine rootRoute definiert ist
// routes/foo/bar/__virtual.ts
import {
defineVirtualSubtreeConfig,
index,
route,
} from '@tanstack/virtual-file-routes'
export default defineVirtualSubtreeConfig([
index('home.tsx'),
route('$id', 'details.tsx'),
])
// routes/foo/bar/__virtual.ts
import {
defineVirtualSubtreeConfig,
index,
route,
} from '@tanstack/virtual-file-routes'
export default defineVirtualSubtreeConfig([
index('home.tsx'),
route('$id', 'details.tsx'),
])
Die Hilfsfunktion defineVirtualSubtreeConfig ist eng an Vite's defineConfig angelehnt und ermöglicht es Ihnen, eine Teilbaumkonfiguration über einen Standardexport zu definieren. Der Standardexport kann entweder sein
Sie können die dateibasierte Routing-Konvention von TanStack Router und die virtuelle Routenkonfiguration beliebig mischen und anpassen.
Lassen Sie uns tiefer eintauchen!
Schauen Sie sich das folgende Beispiel an, das mit der dateibasierten Routing-Konvention beginnt, dann für /posts zur virtuellen Routenkonfiguration wechselt, dann für /posts/lets-go zur dateibasierten Routing-Konvention zurückkehrt, nur um dann für /posts/lets-go/deeper erneut zur virtuellen Routenkonfiguration zu wechseln.
├── __root.tsx
├── index.tsx
├── posts
│ ├── __virtual.ts
│ ├── details.tsx
│ ├── home.tsx
│ └── lets-go
│ ├── deeper
│ │ ├── __virtual.ts
│ │ └── home.tsx
│ └── index.tsx
└── posts.tsx
├── __root.tsx
├── index.tsx
├── posts
│ ├── __virtual.ts
│ ├── details.tsx
│ ├── home.tsx
│ └── lets-go
│ ├── deeper
│ │ ├── __virtual.ts
│ │ └── home.tsx
│ └── index.tsx
└── posts.tsx
Wenn Sie die TanStack Router CLI verwenden, können Sie virtuelle Dateirouten konfigurieren, indem Sie den Pfad zu Ihrer Routendatei in der Datei tsr.config.json definieren
// tsr.config.json
{
"virtualRouteConfig": "./routes.ts"
}
// tsr.config.json
{
"virtualRouteConfig": "./routes.ts"
}
Oder Sie können die virtuellen Routen direkt in der Konfiguration definieren. Das ist zwar deutlich seltener, ermöglicht es Ihnen aber, sie über die TanStack Router CLI zu konfigurieren, indem Sie ein virtualRouteConfig Objekt zu Ihrer tsr.config.json Datei hinzufügen und Ihre virtuellen Routen definieren und den resultierenden JSON-Code übergeben, der durch den Aufruf der eigentlichen rootRoute/route/index/etc Funktionen aus dem Paket @tanstack/virtual-file-routes generiert wird
// tsr.config.json
{
"virtualRouteConfig": {
"type": "root",
"file": "root.tsx",
"children": [
{
"type": "index",
"file": "home.tsx"
},
{
"type": "route",
"file": "posts/posts.tsx",
"path": "/posts",
"children": [
{
"type": "index",
"file": "posts/posts-home.tsx"
},
{
"type": "route",
"file": "posts/posts-detail.tsx",
"path": "$postId"
}
]
},
{
"type": "layout",
"id": "first",
"file": "layout/first-pathless-layout.tsx",
"children": [
{
"type": "layout",
"id": "second",
"file": "layout/second-pathless-layout.tsx",
"children": [
{
"type": "route",
"file": "a.tsx",
"path": "/route-a"
},
{
"type": "route",
"file": "b.tsx",
"path": "/route-b"
}
]
}
]
}
]
}
}
// tsr.config.json
{
"virtualRouteConfig": {
"type": "root",
"file": "root.tsx",
"children": [
{
"type": "index",
"file": "home.tsx"
},
{
"type": "route",
"file": "posts/posts.tsx",
"path": "/posts",
"children": [
{
"type": "index",
"file": "posts/posts-home.tsx"
},
{
"type": "route",
"file": "posts/posts-detail.tsx",
"path": "$postId"
}
]
},
{
"type": "layout",
"id": "first",
"file": "layout/first-pathless-layout.tsx",
"children": [
{
"type": "layout",
"id": "second",
"file": "layout/second-pathless-layout.tsx",
"children": [
{
"type": "route",
"file": "a.tsx",
"path": "/route-a"
},
{
"type": "route",
"file": "b.tsx",
"path": "/route-b"
}
]
}
]
}
]
}
}
Ihre wöchentliche Dosis JavaScript-Nachrichten. Jeden Montag kostenlos an über 100.000 Entwickler geliefert.