{"_id":"@alice-lib/generator-routes","_rev":"4-a44d84dedc0ecb2269c787a4f813f3a3","name":"@alice-lib/generator-routes","dist-tags":{"latest":"1.0.3"},"versions":{"1.0.0":{"name":"@alice-lib/generator-routes","version":"1.0.0","author":{"name":"senjyouhara"},"_id":"@alice-lib/generator-routes@1.0.0","maintainers":[{"name":"senjyouhara","email":"lzj724@qq.com"}],"dist":{"shasum":"5195135e054ed2ea4401f682c00ce18f016dde74","tarball":"https://registry.npmjs.org/@alice-lib/generator-routes/-/generator-routes-1.0.0.tgz","fileCount":10,"integrity":"sha512-Ik1VRGomsQOf2LiIVunO9tMumiIKEYe4It+JHOCsX7WjySwkmHyLS/Bb3ZMvqZrmWchfNkg3dr6HCOJpzjvnUQ==","signatures":[{"sig":"MEUCIHawJsXv4f/WsHVakbmlLCOgZybW/hK9jsZncHkab55aAiEAgQQdk8N6BKRbpq66mq+i7/NUAMBThi6wMCseujTdRkc=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":29388},"main":"lib/index.js","types":"./lib/index.d.ts","module":"lib/index.js","exports":{".":{"import":"./lib/index.js","default":"./lib/index.js","require":"./lib/index.js"}},"gitHead":"94b92b3e9cb269df048be50a2ec0c0f1836cbf7c","scripts":{"build":"father build","start":"dumi dev","prepublishOnly":"npm run build"},"_npmUser":{"name":"senjyouhara","email":"lzj724@qq.com"},"_npmVersion":"11.6.4","description":"自动生成路由信息","directories":{},"_nodeVersion":"20.15.0","dependencies":{},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"raf":"^3.4.1"},"peerDependencies":{"react":"^17.0.0","react-dom":"^17.0.0","react-router-dom":"^6.0.0"},"_npmOperationalInternal":{"tmp":"tmp/generator-routes_1.0.0_1771038128506_0.16323366117537286","host":"s3://npm-registry-packages-npm-production"}},"1.0.1":{"name":"@alice-lib/generator-routes","version":"1.0.1","author":{"name":"senjyouhara"},"_id":"@alice-lib/generator-routes@1.0.1","maintainers":[{"name":"senjyouhara","email":"lzj724@qq.com"}],"dist":{"shasum":"ca0080c331b6c9459c591c30eab78cf2c879e01a","tarball":"https://registry.npmjs.org/@alice-lib/generator-routes/-/generator-routes-1.0.1.tgz","fileCount":26,"integrity":"sha512-D02yvmDEw5Y8CkzTtMXAaEARb87qQTZOzasI7EJ2znFP+vxFQ+JjdRLZoR3TfzyMXrvtoQJkyGP0t9p73HAqtA==","signatures":[{"sig":"MEUCIQC1A+kHSs9wY/o9IMCQhVXF5QU2uPhLdfgaeTjrzHam3QIgDJNT3/TDIci4WXLphVN0nbHDfR1GaWIkm50c/3zVO6k=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":46718},"main":"lib/index.js","type":"module","types":"./lib/index.d.ts","module":"lib/index.js","exports":{".":{"import":"./lib/index.js","default":"./lib/index.js","require":"./lib/index.js"},"./vite":{"import":"./lib/vite-plugin.js","default":"./lib/vite-plugin.js","require":"./lib/vite-plugin.js"}},"gitHead":"9c06b467c56c2f52e81757e6f813fd9fe85aab7b","scripts":{"build":"father build","start":"dumi dev","prepublishOnly":"npm run build"},"_npmUser":{"name":"senjyouhara","email":"lzj724@qq.com"},"_npmVersion":"10.8.2","description":"自动生成路由信息","directories":{},"_nodeVersion":"20.18.1","dependencies":{},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"raf":"^3.4.1","vite":"^6.0.0"},"peerDependencies":{"vite":"^4.0.0 || ^5.0.0 || ^6.0.0","react":"^17.0.0 || ^18.0.0 || ^19.0.0","react-dom":"^17.0.0 || ^18.0.0 || ^19.0.0","react-router-dom":"^6.0.0 || ^7.0.0"},"_npmOperationalInternal":{"tmp":"tmp/generator-routes_1.0.1_1771239581049_0.22450295277757903","host":"s3://npm-registry-packages-npm-production"}},"1.0.2":{"name":"@alice-lib/generator-routes","version":"1.0.2","author":{"name":"senjyouhara"},"_id":"@alice-lib/generator-routes@1.0.2","maintainers":[{"name":"senjyouhara","email":"lzj724@qq.com"}],"dist":{"shasum":"cd51adf0d0d66b6dc526721d0b95f2a4b6c48f2f","tarball":"https://registry.npmjs.org/@alice-lib/generator-routes/-/generator-routes-1.0.2.tgz","fileCount":26,"integrity":"sha512-d5wfM3eIh5OGc7D+sRADK9sf6pFsTNRj4DS9kUMgwIgA81VFm1hCVk00J+ZevdGp4nJYQiH61XLkMOsLUZm2pA==","signatures":[{"sig":"MEYCIQCU34AwyoOf2Vpe8OKbZ8QmAVaUB8fFSr/tTgzOPniyFQIhAPyXb0ZNcaKfzE1pxiXaNt6tx5oQkXUPeMrn0502C8P9","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":52466},"main":"lib/index.js","type":"module","types":"./lib/index.d.ts","module":"lib/index.js","exports":{".":{"import":"./lib/index.js","default":"./lib/index.js","require":"./lib/index.js"},"./vite":{"import":"./lib/vite-plugin.js","default":"./lib/vite-plugin.js","require":"./lib/vite-plugin.js"}},"gitHead":"17eb4004ce882f80af0d287e2a58d59542242e24","scripts":{"build":"father build","start":"dumi dev","prepublishOnly":"npm run build"},"_npmUser":{"name":"senjyouhara","email":"lzj724@qq.com"},"_npmVersion":"10.8.2","description":"自动生成路由信息","directories":{},"_nodeVersion":"20.18.1","publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"raf":"^3.4.1","vite":"^6.0.0","babel-plugin-add-import-extension":"^1.6.0"},"peerDependencies":{"vite":"^4.0.0 || ^5.0.0 || ^6.0.0","react":"^17.0.0 || ^18.0.0 || ^19.0.0","react-dom":"^17.0.0 || ^18.0.0 || ^19.0.0","react-router-dom":"^6.0.0 || ^7.0.0"},"_npmOperationalInternal":{"tmp":"tmp/generator-routes_1.0.2_1771245364695_0.6940401888191583","host":"s3://npm-registry-packages-npm-production"}},"1.0.3":{"name":"@alice-lib/generator-routes","author":{"name":"senjyouhara"},"version":"1.0.3","description":"自动生成路由信息","type":"module","main":"lib/index.js","module":"lib/index.js","exports":{".":{"import":"./lib/index.js","require":"./lib/index.js","default":"./lib/index.js"},"./vite":{"import":"./lib/vite-plugin.js","require":"./lib/vite-plugin.js","default":"./lib/vite-plugin.js"}},"scripts":{"start":"dumi dev","build":"father build","prepublishOnly":"npm run build"},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"peerDependencies":{"react":"^17.0.0 || ^18.0.0 || ^19.0.0","react-dom":"^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"},"dependencies":{"fast-glob":"^3.3.2"},"devDependencies":{"@types/node":"^22.0.0","babel-plugin-add-import-extension":"^1.6.0","raf":"^3.4.1","vite":"^6.0.0"},"_id":"@alice-lib/generator-routes@1.0.3","gitHead":"796323d4f3549a4e2576cc09bec9bf36d1dfc0a5","types":"./lib/index.d.ts","_nodeVersion":"20.18.1","_npmVersion":"10.8.2","dist":{"integrity":"sha512-AV08v4gagPugSl+mIG/PZVMW3t/8zoayONgfX4ekxdy7nLuSQj2cdtmDN9NONkgNdKkQUJ+xuJhoCwesvZPnPw==","shasum":"c040f80186280831c82e8bcd98550d7b36858add","tarball":"https://registry.npmjs.org/@alice-lib/generator-routes/-/generator-routes-1.0.3.tgz","fileCount":28,"unpackedSize":89074,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQDRJQpi1fTFdb5VQxDQedRyynLD+ZVwcO5x71PKOrjNrQIhAL/GSQCuooVBUIz22X50rfg72fYemZqGGEOsauVfb+gf"}]},"_npmUser":{"name":"senjyouhara","email":"lzj724@qq.com"},"directories":{},"maintainers":[{"name":"senjyouhara","email":"lzj724@qq.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/generator-routes_1.0.3_1771672263097_0.4402539149999949"},"_hasShrinkwrap":false}},"time":{"created":"2026-02-14T03:02:08.408Z","modified":"2026-02-21T11:11:03.373Z","1.0.0":"2026-02-14T03:02:08.644Z","1.0.1":"2026-02-16T10:59:41.198Z","1.0.2":"2026-02-16T12:36:04.845Z","1.0.3":"2026-02-21T11:11:03.245Z"},"author":{"name":"senjyouhara"},"description":"自动生成路由信息","maintainers":[{"name":"senjyouhara","email":"lzj724@qq.com"}],"readme":"# @alice-lib/generator-routes\r\n\r\n基于文件系统的 React 路由自动生成器，支持 Vite 虚拟模块。\r\n\r\n## 安装\r\n\r\n```bash\r\nnpm install @alice-lib/generator-routes\r\n# or\r\npnpm add @alice-lib/generator-routes\r\n```\r\n\r\n## 快速开始\r\n\r\n### 1. 配置 Vite 插件\r\n\r\n```typescript\r\n// vite.config.ts\r\nimport { defineConfig } from 'vite';\r\nimport react from '@vitejs/plugin-react';\r\nimport { generatorRoutesPlugin } from '@alice-lib/generator-routes/vite';\r\n\r\nexport default defineConfig({\r\n  plugins: [\r\n    react(),\r\n    generatorRoutesPlugin({\r\n      scanDir: 'src/pages',  // 扫描目录\r\n    }),\r\n  ],\r\n});\r\n```\r\n\r\n### 2. 使用生成的路由\r\n\r\n```typescript\r\n// src/main.tsx\r\nimport { createBrowserRouter, RouterProvider } from 'react-router-dom';\r\nimport { routes } from './generateRoutes';\r\n\r\nconst router = createBrowserRouter(await routes);\r\n\r\nReactDOM.createRoot(document.getElementById('root')!).render(\r\n  <RouterProvider router={router} />\r\n);\r\n```\r\n\r\n### 3. 创建页面文件\r\n\r\n```\r\nsrc/pages/\r\n├── index.tsx          # /\r\n├── about.tsx          # /about\r\n├── user/\r\n│   ├── index.tsx      # /user\r\n│   └── profile.tsx    # /user/profile\r\n└── 1__dashboard/      # /dashboard (排序优先)\r\n    └── index.tsx\r\n```\r\n\r\n## 插件配置\r\n\r\n```typescript\r\ninterface GeneratorRoutesPluginOptions {\r\n  /** 扫描目录，默认 'src/views' */\r\n  scanDir?: string;\r\n  /** 虚拟模块路径，默认 'src/generateRoutes.tsx' */\r\n  virtualModulePath?: string;\r\n  /** 需要排除的目录名 */\r\n  excludeDirs?: string[];\r\n  /** 文件扩展名，默认 ['.tsx', '.jsx'] */\r\n  extensions?: string[];\r\n  /** 路由结构模式：'nested' 层叠嵌套（默认），'flat' 扁平化 */\r\n  mode?: 'nested' | 'flat';\r\n}\r\n```\r\n\r\n### 路由模式\r\n\r\n#### nested（默认）\r\n\r\n层叠嵌套结构，保留父子关系：\r\n\r\n```typescript\r\ngeneratorRoutesPlugin({\r\n  scanDir: 'src/pages',\r\n  mode: 'nested',\r\n})\r\n```\r\n\r\n生成结果：\r\n```javascript\r\n[\r\n  {\r\n    path: 'user',\r\n    children: [\r\n      { path: 'profile', ... },\r\n      { path: 'settings', ... }\r\n    ]\r\n  }\r\n]\r\n```\r\n\r\n#### flat\r\n\r\n扁平化结构，所有路由平铺，path 拼接为完整路径：\r\n\r\n```typescript\r\ngeneratorRoutesPlugin({\r\n  scanDir: 'src/pages',\r\n  mode: 'flat',\r\n})\r\n```\r\n\r\n生成结果：\r\n```javascript\r\n[\r\n  { path: 'user', ... },\r\n  { path: 'user/profile', ... },\r\n  { path: 'user/settings', ... }\r\n]\r\n```\r\n\r\n## 路由配置\r\n\r\n在页面文件中导出 `routerConfig` 来自定义路由：\r\n\r\n```tsx\r\n// src/pages/not-found.tsx\r\nimport { RouteConfig } from '@alice-lib/generator-routes';\r\n\r\nconst NotFound = () => <div>404</div>;\r\n\r\nexport default NotFound;\r\n\r\nexport const routerConfig: RouteConfig = {\r\n  path: '*',           // 自定义路径\r\n  title: '404',        // 页面标题\r\n  order: 99,           // 排序权重（数字越小越靠前）\r\n  hidden: true,        // 在导航中隐藏\r\n  icon: 'warning',     // 菜单图标\r\n  redirect: '/home',   // 重定向路径\r\n};\r\n```\r\n\r\n### RouteConfig 类型\r\n\r\n```typescript\r\ninterface RouteConfig {\r\n  order?: number;       // 排序权重，数字越小越靠前\r\n  title?: string;       // 页面标题\r\n  icon?: string | React.ReactNode | React.ComponentType;  // 菜单图标\r\n  hidden?: boolean;     // 是否在导航中隐藏\r\n  index?: boolean;      // 是否为首页（index route）\r\n  path?: string;        // 自定义路径，默认根据目录结构生成\r\n  redirect?: string;    // 重定向路径\r\n  useLayout?: boolean;  // 是否使用 Layout 包裹，默认 true\r\n  [key: string]: unknown;\r\n}\r\n```\r\n\r\n## 文件命名约定\r\n\r\n### 排序前缀\r\n\r\n使用 `数字__名称` 格式控制路由顺序：\r\n\r\n```\r\nsrc/pages/\r\n├── 1__home/index.tsx      # /home (优先级 1)\r\n├── 2__about/index.tsx     # /about (优先级 2)\r\n└── 3__contact/index.tsx   # /contact (优先级 3)\r\n```\r\n\r\n### 动态路由\r\n\r\n支持 Next.js 风格的动态路由语法：\r\n\r\n```\r\nsrc/pages/\r\n├── user/\r\n│   └── [id].tsx           # /user/:id - 动态参数\r\n├── blog/\r\n│   └── [[slug]].tsx       # /blog/:slug? - 可选参数\r\n└── docs/\r\n    └── [...path].tsx      # /docs/* - Catch-all 路由\r\n```\r\n\r\n| 文件名 | 生成路径 | 说明 |\r\n|--------|----------|------|\r\n| `[id].tsx` | `:id` | 必选动态参数 |\r\n| `[[id]].tsx` | `:id?` | 可选动态参数 |\r\n| `[...slug].tsx` | `*` | Catch-all（匹配所有子路径） |\r\n\r\n动态路由也支持排序前缀：\r\n\r\n```\r\nsrc/pages/\r\n└── 1__[id].tsx            # /:id (优先级 1)\r\n```\r\n\r\n### 自动排除目录\r\n\r\n以下目录会被自动排除：\r\n\r\n- `components` / `component`\r\n- `utils` / `util`\r\n- `hooks` / `hook`\r\n- `services` / `service`\r\n- `stores` / `store`\r\n- `styles` / `style`\r\n- `types` / `type`\r\n- `constants` / `constant`\r\n- 以 `_` 开头的目录\r\n\r\n## 虚拟模块导入\r\n\r\n插件会自动注入别名配置，支持以下所有导入方式：\r\n\r\n```typescript\r\n// ✅ 别名导入（推荐）\r\nimport { routes } from '@/generateRoutes'\r\n\r\n// ✅ 相对路径导入\r\nimport { routes } from './generateRoutes'\r\nimport { routes } from '../generateRoutes'\r\n\r\n// ✅ 直接路径导入\r\nimport { routes } from 'src/generateRoutes'\r\n\r\n// ✅ 虚拟模块 ID\r\nimport { routes } from 'virtual:generated-routes'\r\n```\r\n\r\n所有导入方式都会被重定向到虚拟模块，即使存在同名真实文件也不会冲突。\r\n\r\n### 虚拟模块导出\r\n\r\n```typescript\r\nimport {\r\n  routes,              // Promise<RouteObject[]> - React Router 路由\r\n  rawRoutes,           // Promise<RawRoute[]> - 原始路由配置\r\n  generateRoutes,      // () => Promise<RouteObject[]>\r\n  generateRawRoutes,   // () => Promise<RawRoute[]>\r\n} from '@/generateRoutes';\r\n```\r\n\r\n### 包导出\r\n\r\n```typescript\r\nimport {\r\n  generateRoutes,           // 从 PageModules 生成路由\r\n  useRouteConfig,           // 获取当前路由配置\r\n  useRouteConfigs,          // 获取所有匹配路由配置\r\n  generatorRoutesPlugin,    // Vite 插件\r\n} from '@alice-lib/generator-routes';\r\n\r\nimport type {\r\n  RouteConfig,\r\n  RouteItem,\r\n  PageModule,\r\n  GeneratorRoutesPluginOptions,\r\n} from '@alice-lib/generator-routes';\r\n```\r\n\r\n## Hooks\r\n\r\n### useRouteConfig\r\n\r\n获取当前路由的配置信息：\r\n\r\n```tsx\r\nimport { useRouteConfig } from '@alice-lib/generator-routes';\r\n\r\nfunction PageTitle() {\r\n  const config = useRouteConfig();\r\n  return <h1>{config?.title}</h1>;\r\n}\r\n```\r\n\r\n### useRouteConfigs\r\n\r\n获取从根到当前路由的所有配置（面包屑）：\r\n\r\n```tsx\r\nimport { useRouteConfigs } from '@alice-lib/generator-routes';\r\n\r\nfunction Breadcrumb() {\r\n  const configs = useRouteConfigs();\r\n  return (\r\n    <nav>\r\n      {configs.map((c, i) => (\r\n        <span key={i}>{c.title}</span>\r\n      ))}\r\n    </nav>\r\n  );\r\n}\r\n```\r\n\r\n## 注意事项\r\n\r\n### Vite 依赖预构建优化\r\n\r\n由于虚拟模块使用 `import.meta.glob` 动态导入页面组件，Vite 可能无法在启动时静态分析出所有依赖，导致开发时多次 reloading。\r\n\r\n解决方案：在 `vite.config.js` 中显式声明需要预构建的依赖：\r\n\r\n```javascript\r\nexport default defineConfig({\r\n  optimizeDeps: {\r\n    include: [\r\n      // 页面中使用的第三方库\r\n      'react-markdown',\r\n      'remark-gfm',\r\n      'react-syntax-highlighter',\r\n      'aos',\r\n      'lodash-es',\r\n      // 其他常用依赖...\r\n    ],\r\n  },\r\n})\r\n```\r\n\r\n### Fast Refresh 警告\r\n\r\n当页面文件同时导出组件和 `routerConfig` 时，可能触发 Fast Refresh 警告。解决方案：\r\n\r\n```tsx\r\n/* @refresh reset */\r\nimport { RouteConfig } from '@alice-lib/generator-routes';\r\n\r\nconst Page = () => <div>Page</div>;\r\nexport default Page;\r\n\r\nexport const routerConfig: RouteConfig = { title: 'Page' };\r\n```\r\n\r\n## 兼容性\r\n\r\n- React: ^17.0.0 || ^18.0.0 || ^19.0.0\r\n- React Router DOM: ^6.0.0 || ^7.0.0\r\n- Vite: ^4.0.0 || ^5.0.0 || ^6.0.0\r\n\r\n## License\r\n\r\nMIT\r\n","readmeFilename":"README.md"}