生成的Vite基於文件的路由
自從嘗試Next.js(頁面目錄)以來,我喜歡使用基於文件的路由。在使用VITE和客戶端應用程序應用相同的概念之後,我開始編寫博客文章,涵蓋了用React路由器實現基於客戶端的文件路由器的文章,該路由器後來包裝為generouted 。
今天的generouted帶來了許多功能,支持多個框架和路由器,並激發了Next.js,Remix,Expo,Docusaurus,Sveltekit等的想法和慣例。
generouted使用Vite的Glob Import API列出src/pages目錄中的路由,並根據generouted的公約生成路由樹和模態。
還可以通過代碼生成來提供某些集成的Vite插件來提供類型安全組件/鉤/utils。
react-router-dom或@tanstack/router ?或@tanstack/react-location@solidjs/router的堅實支持@mdx-js/rollup安裝和設置generouted的互動遊樂場src/pages/ files,然後查看反映的更改如果您沒有帶有React和打字稿的Vite項目,請檢查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項目,請檢查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文檔上找到有關類型安全導航和全局模式的更多詳細信息。
在這裡查看文檔
如果您沒有帶有React和打字稿的Vite項目,請檢查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/目錄中的所有文件都將使用該佈局包裝.在要轉換為前向斜線的細分之間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 - 默認情況下使用的基於文件的路由樹 /對象<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
}然後在根級佈局src/pages/_app.tsx上使用該組件( <Redirects> )來包裝<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 /> ) 麻省理工學院