npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@gulibs/react-vroutes

v0.0.14

Published

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

Readme

@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.tsaction.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 冲突的虚拟模块系统

📦 安装

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

🚀 快速开始

1. 配置 Vite 插件

// 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. 使用路由

// 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 | 加载状态 | ✅ |

⚙️ 配置选项

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 进行动态导入:

// 生成的路由代码
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

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

// 生成的路由代码
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__)
  }]
}];

优点

  • 更快的运行时性能
  • 减少网络请求
  • 适合小型应用

📝 示例代码

页面组件

// 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>
  );
}

数据加载器

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

表单处理器

// 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');
}

布局组件

// 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>
  );
}

路由元数据

// 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'
  }
};

中间件系统

基础中间件

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

路径特定中间件

// 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 支持

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

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

或在 tsconfig.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 类型错误?

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

📄 许可证

MIT License

🤝 贡献

欢迎提交 Issue 和 Pull Request!


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