Wir möchten dem Remix-Team danken, das das Konzept der virtuellen Dateirouten maßgeblich geprägt hat. Wir haben uns von ihrer Arbeit inspirieren lassen und sie für die Verwendung mit der bestehenden dateibasierten Routenbaumgenerierung von TanStack Router angepasst.
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 virtueller 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 ü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: 'solid',
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: 'solid',
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 zur Verfügung, 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 die Festlegung eines gemeinsamen Pfadpräfixes für seine Kinder
// 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 mit der altbewährten Dateibasierten Routing-Konvention von TanStack Router 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 hat gezeigt, 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 Anwendung mit der dateibasierten Routing-Konvention von TanStack Router konfigurieren und sich für die virtuelle Routenkonfiguration für bestimmte Unterbäume entscheiden.
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
Werfen wir einen Blick auf 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 erklärt, wobei der einzige Unterschied darin besteht, dass für diesen Teilbaum keine rootRoute definiert wird.
// 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 Vites 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!
Sehen Sie sich das folgende Beispiel an, das mit der Dateibasierten Routing-Konvention beginnt, für /posts zur virtuellen Routenkonfiguration wechselt, für /posts/lets-go zurück zur Dateibasierten Routing-Konvention wechselt, nur um dann für /posts/lets-go/deeper wieder 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 tsr.config.json Datei 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. Dies ist zwar weitaus weniger üblich, ermöglicht es Ihnen jedoch, 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 dann das daraus resultierende JSON übergeben, das durch Aufrufen der tatsächlichen 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.