الطرق المستندة إلى الملفات التي تم إنشاؤها لـ Vite
لقد استمتعت باستخدام التوجيه المستند إلى الملف منذ أن جربت Next.js (دليل الصفحات). بعد تطبيق نفس المفهوم من خلال تطبيقات Vite و Side Client ، بدأت في كتابة منشورات المدونة التي تغطي تنفيذ التوجيه المستند إلى الملفات من جانب العميل باستخدام Raive Router الذي تم تعبئته لاحقًا كما generouted .
يجلب generouted اليوم العديد من الميزات ، ويدعم أطر عمل متعددة وأجهزة توجيه ، ويلهم الأفكار والاتفاقيات من Next.js ، Remix ، Expo ، Docusaurus ، Sveltekit والمزيد.
يستخدم generouted API من Vite Glob Import لدرج الطرق داخل دليل src/pages ويقوم بإنشاء الأشجار والمعارض على أساس اتفاقيات generouted .
هناك أيضًا مكونات VITE متاحة لبعض عمليات التكامل لتوفير مكونات/خطافات/خطافات آمنة من النوع من خلال توليد الكود.
react-router-dom أو @tanstack/router ؟ أو @tanstack/react-location@solidjs/router@mdx-js/rollup تثبيت وإعدادgenerouted عبر Stackblitzsrc/pages/ Files وشاهد التغييرات الخاصة بك تعكس في حال لم يكن لديك مشروع 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 مع Solid و 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 و .mdx ملحقات الملفsrc/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 في هذه الحالة . بين الأجزاء التي سيتم تحويلها إلى مائلات إلى الأمام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+ (التفكير في الوسيط هو مسار إضافي يتراكب الطريق الحالي)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 | * | مخصص 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 TREERES TREE /كائن مستندة إلى الملفات المستخدمة افتراضيًا في <Routes /> COMPONENT عبر @generouted/react-router/lazy أو @generouted/solid-router/lazy
@generouted/react-router أو @generouted/solid-router لتمكين التحميل الكسولsrc/pages/_app.tsx<Routes /> و routes Exports عبر @generouted/react-router/plugin أو @generouted/solid-router/plugin
src/router.ts<Link> ، <Navigate> ، useModals() ، useNavigate() ، useParams() ، redirect() ، إلخ.@generouted/react-router أو مستندات @generouted/solid-router لمزيد من التفاصيل عبر @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 /> ) معهد ماساتشوستس للتكنولوجيا