npm package: @gulibs/react-vroutes
Description: 基于 React Router v7 的文件系统自动路由生成器，为所有 React + Vite 项目提供类似 Next.js 的开发体验
Latest version: 0.0.14

# @gulibs/react-vroutes

> 🚀 基于 React Router v7 的文件系统自动路由生成器，为所有 React + Vite 项目提供类似 Next.js 的开发体验

## ✨ 特性

### 🚀 核心功能

- 🔥 **文件系统路由** - 基于文件结构自动生成路由，零配置启动
- ⚡ **完美热更新** - 文件变化实时同步，开发体验丝滑
- 🎯 **智能识别** - 自动区分页面、布局、数据加载等文件类型
- 📦 **代码分割** - 内置 React.lazy 支持，自动优化性能
- 🛡️ **类型安全** - 完整 TypeScript 支持，智能提示无忧

### 📁 路由风格支持

- **目录约定式**: `pages/about/page.tsx` → `/about`
- **扁平风格**: `pages/about.page.tsx` → `/about`
- **混合模式**: 同时支持两种风格
- **动态路由**: `[id].page.tsx` → `/:id`
- **通配符路由**: `[...slug].page.tsx` → `/*`
- **嵌套路由**: 支持多层嵌套结构
- **索引路由**: 自动处理 index 路由

### 🔧 React Router v7 新特性支持

- ✅ `loader` / `action` - 数据加载和操作（服务端 / 客户端）
- ✅ `middleware` - 路由中间件支持（Data Mode）
- ✅ `errorElement` - 错误边界组件（通过 `error.tsx` 文件）
- ✅ `loadingElement` - 加载元素（通过 `loading.tsx` 文件）

### 🛡️ 中间件系统

- **中间件自动发现** - 自动扫描 `middleware.ts` 文件
- **基于文件路径自动匹配** - 通过文件系统层级结构自动应用到对应路由
- **执行顺序控制** - Root → Parent → Child 执行顺序
- **React Router v7 Data Mode** - 使用官方中间件 API

### 📦 数据加载和处理

- **loader 支持** - 服务端 / 客户端数据加载
- **action 支持** - 表单处理和数据操作
- **优先级控制** - 独立文件和页面导出共存
- **文件约定** - 支持 `loader.ts` 和 `action.ts` 独立文件

### 🎯 文件类型识别

- **页面文件** - `page.tsx`, `index.tsx`
- **布局文件** - `layout.tsx`, `_layout.tsx`
- **错误文件** - `error.tsx`, `_error.tsx`, `404.tsx`
- **加载文件** - `loading.tsx`, `_loading.tsx`
- **处理文件** - `handle.ts`, `_handle.ts`
- **中间件文件** - `middleware.ts`
- **加载器文件** - `loader.ts`, `_loader.ts`
- **操作文件** - `action.ts`, `_action.ts`

### ⚡ 性能优化

- **动态导入模式** - `dynamic: true` 使用 React.lazy
- **静态导入模式** - `dynamic: false` 使用静态导入
- **代码分割** - 自动按路由分割代码
- **缓存机制** - 智能缓存提升性能
- **文件监听优化** - 避免循环监控和性能问题

### 🔍 开发体验

- **调试模式** - 详细的调试日志
- **错误处理** - 完善的错误边界和错误处理
- **日志系统** - 分级日志输出
- **类型提示** - 完整的 TypeScript 类型定义
- **虚拟模块** - 避免 HMR 冲突的虚拟模块系统

## 📦 安装

```bash
npm install @gulibs/react-vroutes
# 或
pnpm add @gulibs/react-vroutes
# 或
yarn add @gulibs/react-vroutes
```

## 🚀 快速开始

### 1. 配置 Vite 插件

```typescript
// vite.config.ts
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import { autoRoutes } from '@gulibs/react-vroutes';

export default defineConfig({
  plugins: [
    react(),
    autoRoutes({
      dirs: [{ dir: './src/pages', baseRoute: '/' }],
      dynamic: true,    // 启用代码分割
      debug: true       // 开发时启用调试
    })
  ]
});
```

### 2. 创建页面文件

```
src/pages/
├── page.tsx                 # / 路由
├── about.page.tsx          # /about 路由
├── layout.tsx              # 根布局
├── middleware.ts           # 全局中间件
└── users/
    ├── page.tsx            # /users 路由
    ├── layout.tsx          # 用户模块布局
    ├── middleware.ts       # 用户模块中间件
    └── [id]/
        ├── page.tsx        # /users/:id 路由
        ├── loader.ts       # 数据加载
        ├── action.ts       # 表单处理
        ├── handle.ts       # 路由元数据
        ├── loading.tsx     # 加载状态
        ├── error.tsx       # 错误边界
        └── middleware.ts   # 用户详情中间件
```

### 3. 使用路由

```typescript
// src/main.tsx
import React from 'react';
import ReactDOM from 'react-dom/client';
import { createBrowserRouter, RouterProvider } from 'react-router';
import { routes } from '@gulibs/react-autopages';

const router = createBrowserRouter(routes);

ReactDOM.createRoot(document.getElementById('root')!).render(
  <React.StrictMode>
    <RouterProvider router={router} />
  </React.StrictMode>
);
```

## 📁 文件约定

### 路由文件（生成路由）

| 文件名 | 路由路径 | 说明 |
|--------|----------|------|
| `page.tsx` | `/` | 目录首页 |
| `about.page.tsx` | `/about` | 扁平风格页面 |
| `[id].page.tsx` | `/:id` | 动态路由 |
| `[...slug].page.tsx` | `/*` | 通配符路由 |
| `layout.tsx` | - | 嵌套布局组件 |

### 辅助文件（不生成路由）

| 文件名 | 功能 | React Router v7 |
|--------|------|-----------------|
| `loader.ts` | 数据加载（服务端 / 客户端） | ✅ |
| `action.ts` | 表单处理 | ✅ |
| `handle.ts` | 路由元数据 | ✅ |
| `middleware.ts` | 路由中间件 | ✅ |
| `error.tsx` | 错误边界（errorElement） | ✅ |
| `loading.tsx` | 加载状态 | ✅ |

## ⚙️ 配置选项

```typescript
interface IAutoRoutesPluginOptions {
  // 路由目录配置（必需）
  dirs: Array<{
    dir: string;              // 扫描目录
    baseRoute: string;        // 基础路由
    include?: string[];       // 包含模式（文件匹配）
    exclude?: string[];       // 排除模式（文件匹配）
    nested?: boolean;         // 嵌套模式
  }>;

  // 动态导入
  dynamic?: boolean;          // 代码分割（默认: false）

  // 路由模式
  routeMode?: 'nested' | 'flat';  // 默认: 'flat'

  // 全局文件匹配模式（应用到所有目录）
  include?: string[];         // 全局包含模式
  exclude?: string[];         // 全局排除模式

  // 路由风格检测
  routeStyleDetection?: {
    enabled?: boolean;        // 自动检测路由风格
    forceStyle?: 'directory' | 'flat' | 'mixed';
  };

  // Loader/Action 优先级
  loaderActionPriority?: {
    preferFiles?: boolean;    // 优先独立文件（默认: true）
  };

  // React Router v7 特性
  enableMiddleware?: boolean;  // 启用中间件支持（默认: false）
  useNewSystem?: boolean;      // 使用新的 loader/action 系统（默认: true）

  // 缓存配置
  cache?: boolean;            // 启用缓存（默认: true）
  cacheTime?: number;         // 缓存时间（毫秒，默认: 60000）

  // 调试
  debug?: boolean;            // 调试模式（默认: false）
}
```

## 🔄 动态导入模式

### dynamic: true （默认）

启用代码分割，使用 `React.lazy` 进行动态导入：

```typescript
// 生成的路由代码
export const routes = [{
  path: "/",
  element: React.createElement(React.lazy(() => import("/src/pages/layout.tsx"))),
  children: [{
    index: true,
    element: React.createElement(React.lazy(() => import("/src/pages/page.tsx")))
  }]
}];
```

**优点**：
- 自动代码分割
- 按需加载，提升首屏性能
- 支持 Suspense 边界

### dynamic: false

使用静态导入，所有组件在构建时打包：

```typescript
// 生成的路由代码
import __$React_Route_Srcpages_Page_$page__ from "/src/pages/page.tsx"
import __$React_Route_Srcpages_Layout_$layout__ from "/src/pages/layout.tsx"

export const routes = [{
  path: "/",
  element: React.createElement(__$React_Route_Srcpages_Layout_$layout__),
  children: [{
    index: true,
    element: React.createElement(__$React_Route_Srcpages_Page_$page__)
  }]
}];
```

**优点**：
- 更快的运行时性能
- 减少网络请求
- 适合小型应用

## 📝 示例代码

### 页面组件

```typescript
// pages/users/page.tsx
import { useLoaderData } from 'react-router';

export default function UsersPage() {
  const { users } = useLoaderData();

  return (
    <div>
      <h1>用户列表</h1>
      {users.map(user => (
        <div key={user.id}>{user.name}</div>
      ))}
    </div>
  );
}
```

### 数据加载器

```typescript
// pages/users/loader.ts
export async function loader({ params }) {
  const users = await fetch('/api/users').then(res => res.json());
  return { users };
}
```

### 表单处理器

```typescript
// pages/users/action.ts
import { redirect } from 'react-router';

export async function action({ request }) {
  const formData = await request.formData();
  const name = formData.get('name');

  await fetch('/api/users', {
    method: 'POST',
    body: JSON.stringify({ name }),
    headers: { 'Content-Type': 'application/json' }
  });

  return redirect('/users');
}
```

### 布局组件

```typescript
// pages/layout.tsx
import { Outlet } from 'react-router';

export default function RootLayout() {
  return (
    <div>
      <nav>
        <a href="/">首页</a>
        <a href="/about">关于</a>
        <a href="/users">用户</a>
      </nav>

      <main>
        <Outlet />
      </main>
    </div>
  );
}
```

### 路由元数据

```typescript
// pages/users/[id]/handle.ts
export const handle = {
  breadcrumb: (params) => [
    { label: '首页', href: '/' },
    { label: '用户管理', href: '/users' },
    { label: `用户 ${params.id}`, href: `/users/${params.id}` }
  ],
  title: (params) => `用户详情 - 用户 ${params.id}`,
  permissions: ['user:read'],
  meta: {
    keywords: ['用户', '详情'],
    robots: 'index, follow'
  }
};
```

### 中间件系统

#### 基础中间件

```typescript
// pages/middleware.ts - 全局中间件
export default [
  async ({ request, context, params }, next) => {
    console.log('🌍 全局中间件: 请求开始', request.url);
    const response = await next();
    console.log('🌍 全局中间件: 请求结束');
    return response;
  }
];
```

#### 路径特定中间件

```typescript
// pages/users/middleware.ts - 用户模块中间件
export default [
  async ({ request, context, params }, next) => {
    // 只对 /users/* 路径生效
    console.log('👥 用户模块中间件: 请求开始', request.url);
    const response = await next();
    console.log('👥 用户模块中间件: 请求结束');
    return response;
  }
];
```

#### 中间件执行顺序

中间件按照以下顺序执行：

1. **Root 中间件** - 匹配 `/` 的中间件
2. **Parent 中间件** - 匹配父级路径的中间件
3. **Child 中间件** - 匹配当前路径的中间件

例如，访问 `/users/123` 时：
- 先执行匹配 `/` 的全局中间件
- 再执行匹配 `/users` 的中间件
- 最后执行匹配 `/users/123` 的中间件

## 🔧 TypeScript 支持

添加类型声明以获得完整的智能提示：

```typescript
// vite-env.d.ts
/// <reference types="@gulibs/react-vroutes/react-routes" />
```

或在 `tsconfig.json` 中添加：

```json
{
  "compilerOptions": {
    "types": ["@gulibs/react-vroutes/react-routes"]
  }
}
```

## 🎯 核心改进

### 相比 vgrove-autoroutes

- ✅ 修复嵌套路由生成错误
- ✅ 正确处理 layout 和 page 的组合关系
- ✅ 支持可选的中间层路由（除根目录外）
- ✅ 支持 React Router v7 新特性
- ✅ 改进数据加载方式（独立文件和页面导出可共存）
- ✅ 更好的 TypeScript 支持
- ✅ 完善的热更新机制
- ✅ 简化的中间件系统（Data Mode）

### 关键技术点

1. **虚拟模块系统** - 使用路径嵌入方式避免 HMR 冲突
2. **路由生成逻辑** - 正确处理 layout + page 组合
3. **Loader/Action 优先级** - 支持独立文件和页面导出共存
4. **热更新优化** - 文件监听过滤，避免循环监控
5. **React Router v7 中间件** - 使用官方 Data Mode API

## 📚 项目结构

```
react-vroutes/
├── lib/                    # 库源码
│   ├── constant.ts        # 常量定义
│   ├── context.ts         # 路由上下文
│   ├── errors.ts          # 错误处理
│   ├── logger.ts          # 日志系统
│   ├── parser.ts          # 路由解析器
│   ├── plugin.ts          # Vite 插件
│   ├── stringifier.ts     # 路由生成器
│   ├── types.ts           # 类型定义
│   ├── client.ts          # 客户端 hooks
│   └── index.ts           # 入口文件
├── test/src/              # 测试代码
│   └── pages/             # 测试页面
├── react-routes.d.ts      # 类型声明
├── vite.config.ts         # Vite 配置
└── package.json           # 项目配置
```

## 🐛 故障排除

### 热更新不工作？

- 确保文件在配置的目录中
- 检查文件命名是否符合约定
- 尝试重启开发服务器

### 路由没有生成？

- 文件名是否包含 `.page.tsx` 或为 `page.tsx`
- 文件是否被 `exclude` 规则排除
- 启用 `debug: true` 查看详细日志

### TypeScript 类型错误？

```typescript
// 添加类型声明
declare module '@gulibs/react-autopages' {
  export const routes: Array<RouteObject>;
}
```

## 📄 许可证

MIT License

## 🤝 贡献

欢迎提交 Issue 和 Pull Request！

---

**🚀 立即体验零配置路由的便利！**