@alice-lib/generator-routes
v1.0.3
Published
自动生成路由信息
Downloads
35
Readme
@alice-lib/generator-routes
基于文件系统的 React 路由自动生成器,支持 Vite 虚拟模块。
安装
npm install @alice-lib/generator-routes
# or
pnpm add @alice-lib/generator-routes快速开始
1. 配置 Vite 插件
// vite.config.ts
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import { generatorRoutesPlugin } from '@alice-lib/generator-routes/vite';
export default defineConfig({
plugins: [
react(),
generatorRoutesPlugin({
scanDir: 'src/pages', // 扫描目录
}),
],
});2. 使用生成的路由
// src/main.tsx
import { createBrowserRouter, RouterProvider } from 'react-router-dom';
import { routes } from './generateRoutes';
const router = createBrowserRouter(await routes);
ReactDOM.createRoot(document.getElementById('root')!).render(
<RouterProvider router={router} />
);3. 创建页面文件
src/pages/
├── index.tsx # /
├── about.tsx # /about
├── user/
│ ├── index.tsx # /user
│ └── profile.tsx # /user/profile
└── 1__dashboard/ # /dashboard (排序优先)
└── index.tsx插件配置
interface GeneratorRoutesPluginOptions {
/** 扫描目录,默认 'src/views' */
scanDir?: string;
/** 虚拟模块路径,默认 'src/generateRoutes.tsx' */
virtualModulePath?: string;
/** 需要排除的目录名 */
excludeDirs?: string[];
/** 文件扩展名,默认 ['.tsx', '.jsx'] */
extensions?: string[];
/** 路由结构模式:'nested' 层叠嵌套(默认),'flat' 扁平化 */
mode?: 'nested' | 'flat';
}路由模式
nested(默认)
层叠嵌套结构,保留父子关系:
generatorRoutesPlugin({
scanDir: 'src/pages',
mode: 'nested',
})生成结果:
[
{
path: 'user',
children: [
{ path: 'profile', ... },
{ path: 'settings', ... }
]
}
]flat
扁平化结构,所有路由平铺,path 拼接为完整路径:
generatorRoutesPlugin({
scanDir: 'src/pages',
mode: 'flat',
})生成结果:
[
{ path: 'user', ... },
{ path: 'user/profile', ... },
{ path: 'user/settings', ... }
]路由配置
在页面文件中导出 routerConfig 来自定义路由:
// src/pages/not-found.tsx
import { RouteConfig } from '@alice-lib/generator-routes';
const NotFound = () => <div>404</div>;
export default NotFound;
export const routerConfig: RouteConfig = {
path: '*', // 自定义路径
title: '404', // 页面标题
order: 99, // 排序权重(数字越小越靠前)
hidden: true, // 在导航中隐藏
icon: 'warning', // 菜单图标
redirect: '/home', // 重定向路径
};RouteConfig 类型
interface RouteConfig {
order?: number; // 排序权重,数字越小越靠前
title?: string; // 页面标题
icon?: string | React.ReactNode | React.ComponentType; // 菜单图标
hidden?: boolean; // 是否在导航中隐藏
index?: boolean; // 是否为首页(index route)
path?: string; // 自定义路径,默认根据目录结构生成
redirect?: string; // 重定向路径
useLayout?: boolean; // 是否使用 Layout 包裹,默认 true
[key: string]: unknown;
}文件命名约定
排序前缀
使用 数字__名称 格式控制路由顺序:
src/pages/
├── 1__home/index.tsx # /home (优先级 1)
├── 2__about/index.tsx # /about (优先级 2)
└── 3__contact/index.tsx # /contact (优先级 3)动态路由
支持 Next.js 风格的动态路由语法:
src/pages/
├── user/
│ └── [id].tsx # /user/:id - 动态参数
├── blog/
│ └── [[slug]].tsx # /blog/:slug? - 可选参数
└── docs/
└── [...path].tsx # /docs/* - Catch-all 路由| 文件名 | 生成路径 | 说明 |
|--------|----------|------|
| [id].tsx | :id | 必选动态参数 |
| [[id]].tsx | :id? | 可选动态参数 |
| [...slug].tsx | * | Catch-all(匹配所有子路径) |
动态路由也支持排序前缀:
src/pages/
└── 1__[id].tsx # /:id (优先级 1)自动排除目录
以下目录会被自动排除:
components/componentutils/utilhooks/hookservices/servicestores/storestyles/styletypes/typeconstants/constant- 以
_开头的目录
虚拟模块导入
插件会自动注入别名配置,支持以下所有导入方式:
// ✅ 别名导入(推荐)
import { routes } from '@/generateRoutes'
// ✅ 相对路径导入
import { routes } from './generateRoutes'
import { routes } from '../generateRoutes'
// ✅ 直接路径导入
import { routes } from 'src/generateRoutes'
// ✅ 虚拟模块 ID
import { routes } from 'virtual:generated-routes'所有导入方式都会被重定向到虚拟模块,即使存在同名真实文件也不会冲突。
虚拟模块导出
import {
routes, // Promise<RouteObject[]> - React Router 路由
rawRoutes, // Promise<RawRoute[]> - 原始路由配置
generateRoutes, // () => Promise<RouteObject[]>
generateRawRoutes, // () => Promise<RawRoute[]>
} from '@/generateRoutes';包导出
import {
generateRoutes, // 从 PageModules 生成路由
useRouteConfig, // 获取当前路由配置
useRouteConfigs, // 获取所有匹配路由配置
generatorRoutesPlugin, // Vite 插件
} from '@alice-lib/generator-routes';
import type {
RouteConfig,
RouteItem,
PageModule,
GeneratorRoutesPluginOptions,
} from '@alice-lib/generator-routes';Hooks
useRouteConfig
获取当前路由的配置信息:
import { useRouteConfig } from '@alice-lib/generator-routes';
function PageTitle() {
const config = useRouteConfig();
return <h1>{config?.title}</h1>;
}useRouteConfigs
获取从根到当前路由的所有配置(面包屑):
import { useRouteConfigs } from '@alice-lib/generator-routes';
function Breadcrumb() {
const configs = useRouteConfigs();
return (
<nav>
{configs.map((c, i) => (
<span key={i}>{c.title}</span>
))}
</nav>
);
}注意事项
Vite 依赖预构建优化
由于虚拟模块使用 import.meta.glob 动态导入页面组件,Vite 可能无法在启动时静态分析出所有依赖,导致开发时多次 reloading。
解决方案:在 vite.config.js 中显式声明需要预构建的依赖:
export default defineConfig({
optimizeDeps: {
include: [
// 页面中使用的第三方库
'react-markdown',
'remark-gfm',
'react-syntax-highlighter',
'aos',
'lodash-es',
// 其他常用依赖...
],
},
})Fast Refresh 警告
当页面文件同时导出组件和 routerConfig 时,可能触发 Fast Refresh 警告。解决方案:
/* @refresh reset */
import { RouteConfig } from '@alice-lib/generator-routes';
const Page = () => <div>Page</div>;
export default Page;
export const routerConfig: RouteConfig = { title: 'Page' };兼容性
- React: ^17.0.0 || ^18.0.0 || ^19.0.0
- React Router DOM: ^6.0.0 || ^7.0.0
- Vite: ^4.0.0 || ^5.0.0 || ^6.0.0
License
MIT
