Generierte dateibasierte Routen für vite
Ich habe es genossen, dateibasiertes Routing zu verwenden, seit ich Next.js (Pages-Verzeichnis) ausprobiert habe. Nachdem ich dasselbe Konzept mit vite und clientseitigen Anwendungen angewendet hatte, begann ich, Blog-Posts zu schreiben, die die Implementierung von clientseitigem dateibasiertem Routing mit React Router abdeckten, der später als generouted verpackt wurde.
Heute bringt generouted viele Funktionen mit, unterstützt mehrere Frameworks und Router und inspiriert Ideen und Konventionen von Next.js, Remix, Expo, Docusaurus, Sveltekit und mehr.
generouted verwendet die Glob -Import -API von Vite, um die Routen im Verzeichnis src/pages aufzulisten, und generiert den Routes -Baum und die Modale basierend auf den Konventionen von generouted .
Für einige Integrationen stehen auch VITE-Plugins zur Verfügung, um die Typ-Safe-Komponenten/-haken/-Sile über die Code-Generation bereitzustellen.
react-router-dom oder @tanstack/router ? oder @tanstack/react-location@solidjs/router@mdx-js/rollup Installation und Setupgenerouted über Stackblitzsrc/pages/ Dateien und sehen Sie, wie Ihre Änderungen reflektieren Wenn Sie kein Vite -Projekt mit React und TypeScript haben, überprüfen Sie die VITE -Dokumentation, um ein neues Projekt zu starten.
pnpm add @generouted/react-router react-router-dom // vite.config.ts
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import generouted from '@generouted/react-router/plugin'
export default defineConfig ( { plugins : [ react ( ) , generouted ( ) ] } ) // src/main.tsx
import { createRoot } from 'react-dom/client'
import { Routes } from '@generouted/react-router'
createRoot ( document . getElementById ( 'root' ) ! ) . render ( < Routes /> ) Fügen Sie die Startseite hinzu, indem Sie eine neue Datei src/pages/index.tsx → / erstellen und dann eine Standardkomponente exportieren:
export default function Home ( ) {
return < h1 > Home </ h1 >
}Überprüfen Sie den Abschnitt Routing Conventions unten.
Weitere Details zur Typ-Safe-Navigation und globalen Modalen finden Sie unter @generouted/react-router Dokumenten.
Wenn Sie kein Vite -Projekt mit soliden und typischen Schriften haben, überprüfen Sie die VITE -Dokumentation, um ein neues Projekt zu starten.
pnpm add @generouted/solid-router @solidjs/router // vite.config.ts
import { defineConfig } from 'vite'
import solid from 'vite-plugin-solid'
import generouted from '@generouted/solid-router/plugin'
export default defineConfig ( { plugins : [ solid ( ) , generouted ( ) ] } ) // src/main.tsx
import { render } from 'solid-js/web'
import { Routes } from '@generouted/solid-router'
render ( Routes , document . getElementById ( 'root' ) ! ) Fügen Sie die Startseite hinzu, indem Sie eine neue Datei src/pages/index.tsx → / erstellen und dann eine Standardkomponente exportieren:
export default function Home ( ) {
return < h1 > Home </ h1 >
} Weitere Informationen zu generouted Routing -Konventionen finden Sie unten.
Weitere Details zur Typ-Safe-Navigation und globalen Modalen finden Sie unter @generouted/solid-router Dokumenten.
Schauen Sie sich die Dokumente hier an
Wenn Sie kein Vite -Projekt mit React und TypeScript haben, überprüfen Sie die VITE -Dokumentation, um ein neues Projekt zu starten.
pnpm add generouted @tanstack/react-location // src/main.tsx
import { createRoot } from 'react-dom/client'
import { Routes } from 'generouted/react-location'
createRoot ( document . getElementById ( 'root' ) ! ) . render ( < Routes /> ) Fügen Sie die Startseite hinzu, indem Sie eine neue Datei src/pages/index.tsx → / erstellen und dann eine Standardkomponente exportieren:
export default function Home ( ) {
return < h1 > Home </ h1 >
} src/pages.tsx , .jsx und .mdx -Dateierweiterungensrc/pages/_app.tsx für ein App -Level -Layoutsrc/pages/404.tsx für eine benutzerdefinierte nicht gegründete Seite src/pages/index.tsx → /src/pages/posts/index.tsx → /posts src/pages/posts/2022/index.tsx → /posts/2022src/pages/posts/2022/resolutions.tsx → /posts/2022/resolutions src/pages/posts/[slug].tsx → /posts/:slugsrc/pages/posts/[slug]/tags.tsx → /posts/:slug/tagssrc/pages/posts/[...all].tsx → /posts/* _layout.tsx in einem verschachtelten Verzeichnis → src/pages/posts/_layout.tsx<Outlet /> -Komponente, um Layout -Kinder zu rendernsrc/pages/posts/ Verzeichnisses in diesem Fall mit diesem Layout verpackt . zwischen den Segmenten, die in die Weiterleitung von Schrägstrichen umgewandelt werden sollensrc/pages/posts.nested.as.url.not.layout.tsx → /posts/nested/as/url/not/layout ()src/pages/(auth)/_layout.tsxsrc/pages/(auth)/login.tsx → /login+ (denke, der Modal ist eine zusätzliche Route, die die aktuelle Route überlagert)useModals() Hooksrc/pages/+info.tsx → /infosrc/pages/+checkout/+details.tsx → /checkout/detailssrc/pages/+checkout/+payment.tsx → /checkout/payment - (Denken Sie, dass das Segment vom Routenpfad abtrahiert oder entfernt werden kann)src/pages/-en/about.tsx → /en?/about → /en/about , /aboutsrc/pages/-[lang]/about.tsx → /:lang?/about → /en/about , /fr/about , /about _ wird ignoriertsrc/pages/_ignored.tsxsrc/pages/posts/_components/button.tsxsrc/pages/posts/_components/link.tsxexport default Component() {...}export const Loader = () => {...}export const Action = () => {...}export const Pending = () => {...}export const Catch = () => {...}src/pages
├── (auth)
│ ├── _layout.tsx
│ ├── login.tsx
│ └── register.tsx
├── blog
│ ├── _components
│ │ ├── button.tsx
│ │ └── comments.tsx
│ ├── [...all].tsx
│ ├── [slug].tsx
│ ├── _layout.tsx
│ ├── index.tsx
│ └── tags.tsx
├── docs
│ ├── -[lang]
│ │ ├── index.tsx
│ │ └── resources.tsx
│ └── -en
│ └── contributors.tsx
├── +info.tsx
├── 404.tsx
├── _app.tsx
├── _ignored.tsx
├── about.tsx
├── blog.w.o.layout.tsx
└── index.tsx| Datei | Weg | Konvention |
|---|---|---|
(auth)/_layout.tsx | Pfadloses Layoutgruppe | |
(auth)/login.tsx | /login | Regelmäßige Route |
(auth)/register.tsx | /register | Regelmäßige Route |
blog/_components/button.tsx | Ignorierte die Route durch ein ignoriertes Verzeichnis | |
blog/_components/comments.tsx | Ignorierte die Route durch ein ignoriertes Verzeichnis | |
blog/[...all].tsx | /blog/* | Dynamischer Catch-All-Route |
blog/[slug].tsx | /blog/:slug | Dynamische Route |
blog/_layout.tsx | Layout für /blog -Routen | |
blog/index.tsx | /blog | Indexroute |
blog/tags.tsx | /blog/tags | Regelmäßige Route |
docs/-[lang]/index.tsx | /docs/:lang?/index | Optionales dynamisches Routensegment |
docs/-[lang]/resources.tsx | /docs/:lang?/resources | Optionales dynamisches Routensegment |
docs/-en/contributors.tsx | /docs/en?/contributors | Optionales statisches Routensegment |
+info.tsx | /info | Modale Route |
404.tsx | * | Custom 404 (optional) |
_app.tsx | Benutzerdefinierte app -Layout (optional) | |
_ignored.tsx | Ignorierte Route | |
about.tsx | /about | Regelmäßige Route |
blog.wolayout.tsx | /blog/w/o/layout | Route ohne /blog -Layout |
index.tsx | / | Indexroute |
Via @generouted/react-router oder @generouted/solid-router
<Routes /> -Dateibasierte Routing-Komponente, die im App-Eintrag gerendert werden sollenroutes -Dateibasierte Routenbaum /Objekt, das standardmäßig unter <Routes /> Komponente verwendet wird Via @generouted/react-router/lazy oder @generouted/solid-router/lazy
@generouted/react-router oder @generouted/solid-router um faul laden zu lassensrc/pages/_app.tsx<Routes /> und routes Exporte Via @generouted/react-router/plugin oder @generouted/solid-router/plugin
src/router.ts Datei<Link> , <Navigate> , useModals() , useNavigate() , useParams() , redirect() usw.@generouted/react-router -Dokumente oder @generouted/solid-router -Dokumente Via @generouted/react-router/core oder @generouted/solid-router/core
<Routes/> -Komponente zu verwendenEs gibt mehrere Ansätze, um dies zu erreichen. Wenn Sie es vorziehen, die Logik an einem Ort zu behandeln, können Sie die geschützten Routen mit der Umleitungsbehandlung innerhalb einer Komponente definieren:
// src/config/redirects.tsx
import { Navigate , useLocation } from 'react-router-dom'
import { useAuth } from '../context/auth'
import { Path } from '../router'
const PRIVATE : Path [ ] = [ '/logout' ]
const PUBLIC : Path [ ] = [ '/login' ]
export const Redirects = ( { children } : { children : React . ReactNode } ) => {
const auth = useAuth ( )
const location = useLocation ( )
const authenticatedOnPublicPath = auth . active && PUBLIC . includes ( location . pathname as Path )
const unAuthenticatedOnPrivatePath = ! auth . active && PRIVATE . includes ( location . pathname as Path )
if ( authenticatedOnPublicPath ) return < Navigate to = "/" replace />
if ( unAuthenticatedOnPrivatePath ) return < Navigate to = "/login" replace />
return children
} Verwenden Sie dann diese Komponente ( <Redirects> ) am Root-Level-Layout src/pages/_app.tsx um die <Outlet> -Komponente zu wickeln:
// src/pages/_app.tsx
import { Outlet } from 'react-router-dom'
import { Redirects } from '../config/redirects'
export default function App ( ) {
return (
< section >
< header >
< nav > ... </ nav >
</ header >
< main >
< Redirects >
< Outlet />
</ Redirects >
</ main >
</ section >
)
}Sie können ein vollständiges Beispiel für diesen Ansatz bei Render Vorlage finden
Sie können das Objekt für exportierte routes verwenden, um den Router anzupassen oder Hash/Memory -Router zu verwenden:
import { createRoot } from 'react-dom/client'
import { RouterProvider , createHashRouter } from 'react-router-dom'
import { routes } from '@generouted/react-router'
const router = createHashRouter ( routes )
const Routes = ( ) => < RouterProvider router = { router } />
createRoot ( document . getElementById ( 'root' ) ! ) . render ( < Routes /> ) MIT