เส้นทางที่สร้างขึ้นตามไฟล์สำหรับ VITE
ฉันสนุกกับการใช้การกำหนดเส้นทางตามไฟล์ตั้งแต่ฉันลอง next.js (ไดเรกทอรีหน้า) หลังจากใช้แนวคิดเดียวกันกับแอพพลิเคชั่น VITE และฝั่งไคลเอ็นต์ฉันเริ่มเขียนโพสต์บล็อกที่ครอบคลุมการใช้งานการกำหนดเส้นทางตามไฟล์ฝั่งไคลเอ็นต์ด้วย React Router ซึ่งได้ generouted การบรรจุในภายหลัง
วันนี้ generouted นำคุณสมบัติมากมายรองรับเฟรมเวิร์กและเราเตอร์หลายอย่างและเป็นแรงบันดาลใจให้กับความคิดและการประชุมจาก Next.js, Remix, Expo, Docusaurus, Sveltekit และอีกมากมาย
generouted ใช้ API นำเข้าลูกโลกของ Vite เพื่อแสดงรายการเส้นทางภายในไดเรกทอรี src/pages และสร้างทรีเส้นทางและโมดูลตามอนุสัญญาของ generouted
นอกจากนี้ยังมีปลั๊กอิน VITE สำหรับการรวมบางอย่างเพื่อให้ส่วนประกอบ/hooks/utils แบบปลอดภัยประเภทผ่านการสร้างรหัส
react-router-dom หรือ @tanstack/router ? หรือ @tanstack/react-location@solidjs/router@mdx-js/rollup การติดตั้งและการตั้งค่าgenerouted ผ่าน Stackblitzsrc/pages/ ไฟล์และดูการเปลี่ยนแปลงของคุณสะท้อนให้เห็น ในกรณีที่คุณไม่มีโครงการ VITE ที่มี React และ TypeScript ให้ตรวจสอบเอกสาร Vite เพื่อเริ่มโครงการใหม่
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 /> ) เพิ่มโฮมเพจโดยการสร้างไฟล์ใหม่ src/pages/index.tsx → / จากนั้นส่งออกส่วนประกอบเริ่มต้น:
export default function Home ( ) {
return < h1 > Home </ h1 >
}ตรวจสอบส่วนการประชุมเส้นทางด้านล่าง
คุณสามารถค้นหารายละเอียดเพิ่มเติมเกี่ยวกับการนำทางที่ปลอดภัยและโหมดส่วนกลางได้ที่เอกสาร @generouted/react-router
ในกรณีที่คุณไม่มีโครงการ VITE ที่มีของแข็งและ typeScript ตรวจสอบเอกสาร Vite เพื่อเริ่มโครงการใหม่
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' ) ! ) เพิ่มโฮมเพจโดยการสร้างไฟล์ใหม่ src/pages/index.tsx → / จากนั้นส่งออกส่วนประกอบเริ่มต้น:
export default function Home ( ) {
return < h1 > Home </ h1 >
} ดูเพิ่มเติมเกี่ยวกับการประชุมเส้นทางการกำหนด generouted ด้านล่าง
คุณสามารถค้นหารายละเอียดเพิ่มเติมเกี่ยวกับการนำทางที่ปลอดภัยและโหมดทั่วโลกได้ที่เอกสาร @generouted/solid-router
ตรวจสอบเอกสารที่นี่
ในกรณีที่คุณไม่มีโครงการ VITE ที่มี React และ TypeScript ให้ตรวจสอบเอกสาร Vite เพื่อเริ่มโครงการใหม่
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 /> ) เพิ่มโฮมเพจโดยการสร้างไฟล์ใหม่ src/pages/index.tsx → / จากนั้นส่งออกส่วนประกอบเริ่มต้น:
export default function Home ( ) {
return < h1 > Home </ h1 >
} src/pages.tsx , .jsx และ .mdxsrc/pages/_app.tsx เป็นตัวเลือกสำหรับ เค้าโครงระดับแอพsrc/pages/404.tsx สำหรับ หน้าไม่กำหนดเองที่กำหนดเอง 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 ในไดเรกทอรีซ้อนใด ๆ → src/pages/posts/_layout.tsx<Outlet /> เพื่อแสดงผลเด็กเลย์เอาต์src/pages/posts/ DIRECTORY ในกรณีนี้จะถูกห่อหุ้มด้วยเลย์เอาต์นั้น . จุด ระหว่างเซ็กเมนต์ที่จะถูกแปลงเป็น slashes ไปข้างหน้าsrc/pages/posts.nested.as.url.not.layout.tsx → /posts/nested/as/url/not/layout ()src/pages/(auth)/_layout.tsxsrc/pages/(auth)/login.tsx → /login+ (คิดว่า modal เป็นเส้นทางพิเศษซ้อนทับเส้นทางปัจจุบัน)useModals()src/pages/+info.tsx → /infosrc/pages/+checkout/+details.tsx → /checkout/detailssrc/pages/+checkout/+payment.tsx → /checkout/payment - (คิดว่าเซ็กเมนต์สามารถลบหรือลบออกจากเส้นทางเส้นทาง)src/pages/-en/about.tsx → /en?/about /en/about /aboutsrc/pages/-[lang]/about.tsx → /:lang?/about กับ→/ /en/about /fr/about /about _ จะถูก ละเว้นsrc/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| ไฟล์ | เส้นทาง | การประชุม |
|---|---|---|
(auth)/_layout.tsx | กลุ่มเค้าโครงที่ไม่มีเส้นทาง | |
(auth)/login.tsx | /login | เส้นทางปกติ |
(auth)/register.tsx | /register | เส้นทางปกติ |
blog/_components/button.tsx | เส้นทางที่ไม่สนใจโดยไดเรกทอรีที่ถูกละเว้น | |
blog/_components/comments.tsx | เส้นทางที่ไม่สนใจโดยไดเรกทอรีที่ถูกละเว้น | |
blog/[...all].tsx | /blog/* | เส้นทางการจับแบบไดนามิกทั้งหมด |
blog/[slug].tsx | /blog/:slug | เส้นทางไดนามิก |
blog/_layout.tsx | เค้าโครงสำหรับ /blog เส้นทาง | |
blog/index.tsx | /blog | เส้นทางดัชนี |
blog/tags.tsx | /blog/tags | เส้นทางปกติ |
docs/-[lang]/index.tsx | /docs/:lang?/index | เซ็กเมนต์เส้นทางไดนามิกเสริม |
docs/-[lang]/resources.tsx | /docs/:lang?/resources | เซ็กเมนต์เส้นทางไดนามิกเสริม |
docs/-en/contributors.tsx | /docs/en?/contributors | ส่วนเส้นทางคงที่เป็นทางเลือก |
+info.tsx | /info | เส้นทางโมดอล |
404.tsx | * | Custom 404 (ไม่บังคับ) |
_app.tsx | เค้าโครง app ที่กำหนดเอง (ไม่บังคับ) | |
_ignored.tsx | ไม่สนใจเส้นทาง | |
about.tsx | /about | เส้นทางปกติ |
blog.wolayout.tsx | /blog/w/o/layout | เส้นทางที่ไม่มี /blog |
index.tsx | / | เส้นทางดัชนี |
ผ่าน @generouted/react-router หรือ @generouted/solid-router
<Routes /> -องค์ประกอบการกำหนดเส้นทางตามไฟล์ที่จะแสดงผลในรายการแอพroutes -ทรีเส้นทางตามไฟล์ทรี /วัตถุที่ใช้โดยค่าเริ่มต้นที่ <Routes /> ส่วนประกอบ ผ่าน @generouted/react-router/lazy หรือ @generouted/solid-router/lazy
@generouted/react-router หรือ @generouted/solid-router เพื่อเปิดใช้งานการโหลดขี้เกียจsrc/pages/_app.tsx<Routes /> และ routes เดียวกัน ผ่าน @generouted/react-router/plugin หรือ @generouted/solid-router/plugin
src/router.ts<Link> , <Navigate> , useModals() , useNavigate() , useParams() , redirect() ฯลฯ@generouted/react-router หรือ @generouted/solid-router docs สำหรับรายละเอียดเพิ่มเติม ผ่าน @generouted/react-router/core หรือ @generouted/solid-router/core
<Routes/>มีหลายวิธีในการบรรลุเป้าหมายนั้น หากคุณต้องการจัดการตรรกะในที่เดียวคุณสามารถกำหนดเส้นทางที่ได้รับการป้องกันด้วยการจัดการการเปลี่ยนเส้นทางภายในส่วนประกอบ:
// 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
} จากนั้นใช้ส่วนประกอบนั้น ( <Redirects> ) ที่เค้าโครงระดับรูท src/pages/_app.tsx เพื่อห่อส่วนประกอบ <Outlet> :
// 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 >
)
}คุณสามารถค้นหาตัวอย่างทั้งหมดของวิธีการนี้ได้ที่เทมเพลตเรนเดอร์
คุณสามารถใช้วัตถุ routes ที่ส่งออกเพื่อปรับแต่งเราเตอร์หรือใช้เราเตอร์แฮช/หน่วยความจำ:
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 /> ) มิกซ์