@onoxm/vite-plugin-auto-router 0.2.1 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,436 @@
1
+ # @onoxm/vite-plugin-auto-router
2
+
3
+ A Vite plugin for automatically generating React or Vue route files.
4
+
5
+ English | [中文](./README.zh-CN.md)
6
+
7
+ ## ✨ Features
8
+
9
+ - Auto-generate route configuration, no manual maintenance needed
10
+ - Supports both React and Vue frameworks
11
+ - Convention-based routing, automatically mapped by directory structure
12
+ - Supports dynamic route `[id]` syntax
13
+ - `home` page path automatically converted to `/` (configurable)
14
+ - `root` page as root route container (configurable)
15
+ - Configurable lazy loading and hot module replacement
16
+ - Supports page-level configuration files
17
+ - TypeScript type safety
18
+
19
+ ## 🚀 Installation
20
+
21
+ ```bash
22
+ npm install -D @onoxm/vite-plugin-auto-router
23
+ ```
24
+
25
+ ## 📖 Usage Guide
26
+
27
+ ### React Project
28
+
29
+ #### Install Dependencies
30
+
31
+ ```bash
32
+ npm install react-router
33
+ ```
34
+
35
+ #### Configure Vite
36
+
37
+ ```typescript
38
+ // vite.config.ts
39
+ import { defineConfig } from 'vite'
40
+ import react from '@vitejs/plugin-react'
41
+ import autoRouter from '@onoxm/vite-plugin-auto-router'
42
+
43
+ export default defineConfig({
44
+ plugins: [react(), autoRouter()]
45
+ })
46
+ ```
47
+
48
+ #### Directory Structure
49
+
50
+ ```
51
+ src/
52
+ ├── pages/
53
+ │ ├── index.tsx
54
+ │ ├── root.tsx
55
+ │ ├── 404.tsx
56
+ │ └── user/
57
+ │ ├── index.tsx
58
+ │ ├── index.config.ts
59
+ │ ├── [id].tsx
60
+ │ └── [id].config.ts
61
+ ```
62
+
63
+ #### Special Pages
64
+
65
+ - **`home` page**: Path automatically converted to `/`, used as home route
66
+ - **`root` page**: Used as root route container, wrapping all other routes
67
+ - **`404` or `notfound` page**: Path automatically converted to `/*`, used as 404 route
68
+
69
+ #### Page Configuration
70
+
71
+ Inherits from [React Router RouteObject](https://reactrouter.com/start/data/route-object), with the following modifications:
72
+
73
+ - **Removed**: `path`, `Component`, `element`, `children`
74
+ - **Added**: `type?: 'single' | 'wrap'`
75
+
76
+ ##### type: 'single'
77
+
78
+ When `type` is set to `single`, the page component will be generated as an independent route:
79
+
80
+ ```typescript
81
+ // src/pages/user/index.config.ts
82
+ import { defineConfig } from '../../router/autoRouter'
83
+
84
+ export default defineConfig({
85
+ type: 'single'
86
+ })
87
+ ```
88
+
89
+ Generated route structure:
90
+
91
+ ```typescript
92
+ // src/router/autoRouter.tsx
93
+ import type { RouteObject } from 'react-router'
94
+ import Pages404 from './../pages/404.tsx'
95
+ import Pages from './../pages/index.tsx'
96
+ import PagesRoot from './../pages/root.tsx'
97
+ import PagesUser from './../pages/user/index.tsx'
98
+ import PagesUserId from './../pages/user/[id]/index.tsx'
99
+
100
+ type PageConfig = Partial<
101
+ Omit<RouteObject, 'path' | 'Component' | 'element' | 'children'> & {
102
+ type?: 'single' | 'wrap'
103
+ }
104
+ >
105
+
106
+ export const defineConfig = (config: PageConfig) => config
107
+
108
+ export const routes: RouteObject[] = [
109
+ {
110
+ path: '/',
111
+ element: <PagesRoot />,
112
+ children: [
113
+ {
114
+ path: '/',
115
+ element: <Pages />
116
+ },
117
+ {
118
+ path: '/user',
119
+ children: [
120
+ {
121
+ path: '',
122
+ index: true,
123
+ element: <PagesUser />
124
+ },
125
+ {
126
+ path: ':id',
127
+ children: [
128
+ {
129
+ path: '',
130
+ index: true,
131
+ action: async () => {},
132
+ loader: async ({ params }) => await { params },
133
+ element: <PagesUserId />
134
+ }
135
+ ]
136
+ }
137
+ ]
138
+ }
139
+ ]
140
+ },
141
+ {
142
+ path: '/*',
143
+ element: <Pages404 />
144
+ }
145
+ ]
146
+ ```
147
+
148
+ ##### type: 'wrap'
149
+
150
+ When `type` is set to `wrap`, the page component will act as a parent route container wrapping its child routes:
151
+
152
+ ```typescript
153
+ // src/pages/user/index.config.ts
154
+ import { defineConfig } from '../../router/autoRouter'
155
+
156
+ export default defineConfig({
157
+ type: 'wrap'
158
+ })
159
+ ```
160
+
161
+ Generated route structure:
162
+
163
+ ```typescript
164
+ // src/router/autoRouter.tsx
165
+ import type { RouteObject } from 'react-router'
166
+ import Pages404 from './../pages/404.tsx'
167
+ import Pages from './../pages/index.tsx'
168
+ import PagesRoot from './../pages/root.tsx'
169
+ import PagesUser from './../pages/user/index.tsx'
170
+ import PagesUserId from './../pages/user/[id]/index.tsx'
171
+
172
+ type PageConfig = Partial<
173
+ Omit<RouteObject, 'path' | 'Component' | 'element' | 'children'> & {
174
+ type?: 'single' | 'wrap'
175
+ }
176
+ >
177
+
178
+ export const defineConfig = (config: PageConfig) => config
179
+
180
+ export const routes: RouteObject[] = [
181
+ {
182
+ path: '/',
183
+ element: <PagesRoot />,
184
+ children: [
185
+ {
186
+ path: '/',
187
+ element: <Pages />
188
+ },
189
+ {
190
+ path: '/user',
191
+ element: <PagesUser />,
192
+ children: [
193
+ {
194
+ path: ':id',
195
+ children: [
196
+ {
197
+ path: '',
198
+ index: true,
199
+ action: async () => {},
200
+ loader: async ({ params }) => await { params },
201
+ element: <PagesUserId />
202
+ }
203
+ ]
204
+ }
205
+ ]
206
+ }
207
+ ]
208
+ },
209
+ {
210
+ path: '/*',
211
+ element: <Pages404 />
212
+ }
213
+ ]
214
+ ```
215
+
216
+ ### Vue Project
217
+
218
+ #### Install Dependencies
219
+
220
+ ```bash
221
+ npm install vue-router
222
+ ```
223
+
224
+ #### Configure Vite
225
+
226
+ ```typescript
227
+ // vite.config.ts
228
+ import { defineConfig } from 'vite'
229
+ import vue from '@vitejs/plugin-vue'
230
+ import autoRouter from '@onoxm/vite-plugin-auto-router'
231
+
232
+ export default defineConfig({
233
+ plugins: [
234
+ vue(),
235
+ autoRouter({
236
+ framework: 'vue',
237
+ pagesDir: './src/views'
238
+ })
239
+ ]
240
+ })
241
+ ```
242
+
243
+ #### Directory Structure
244
+
245
+ ```
246
+ src/
247
+ ├── views/
248
+ │ ├── 404.vue
249
+ │ ├── home/
250
+ │ │ ├── index.vue
251
+ │ │ └── index.config.ts
252
+ │ └── user/
253
+ │ ├── index.vue
254
+ │ ├── index.config.ts
255
+ │ ├── [id].vue
256
+ │ └── [id].config.ts
257
+ ```
258
+
259
+ #### Special Pages
260
+
261
+ - **`home` page**: Path automatically converted to `/`, used as home route
262
+ - **`root` page**: Used as root route container, wrapping all other routes
263
+ - **`404` or `notfound` page**: Path automatically converted to `/:pathMatch(.*)*`, used as 404 route
264
+
265
+ #### Page Configuration
266
+
267
+ Inherits from [Vue Router RouteRecordRaw](https://router.vuejs.org/api/#routerecordraw), with the following modifications:
268
+
269
+ - **Removed**: `path`, `component`, `children`
270
+ - **Added**: `type?: 'single' | 'wrap'`
271
+
272
+ ##### type: 'single'
273
+
274
+ When `type` is set to `single`, the page component will be generated as an independent route:
275
+
276
+ ```typescript
277
+ // src/views/user/index.config.ts
278
+ import { defineConfig } from '../../router/autoRouter'
279
+
280
+ export default defineConfig({
281
+ type: 'single'
282
+ })
283
+ ```
284
+
285
+ Generated route structure:
286
+
287
+ ```typescript
288
+ // src/router/autoRouter.ts
289
+ import type { RouteRecordRaw } from 'vue-router'
290
+ import Views404 from './../views/404.vue'
291
+ import ViewsHome from './../views/home/index.vue'
292
+ import ViewsUser from './../views/user/index.vue'
293
+ import ViewsUserId from './../views/user/[id]/index.vue'
294
+
295
+ type PageConfig = Partial<
296
+ Omit<RouteRecordRaw, 'path' | 'component' | 'children'> & {
297
+ type?: 'single' | 'wrap'
298
+ }
299
+ >
300
+
301
+ export const defineConfig = (config: PageConfig) => config
302
+
303
+ export const routes: RouteRecordRaw[] = [
304
+ {
305
+ path: '/',
306
+ children: [
307
+ {
308
+ path: '',
309
+ name: 'home',
310
+ component: ViewsHome
311
+ }
312
+ ]
313
+ },
314
+ {
315
+ path: '/user',
316
+ children: [
317
+ {
318
+ path: '',
319
+ component: ViewsUser
320
+ },
321
+ {
322
+ path: ':id',
323
+ children: [
324
+ {
325
+ path: '',
326
+ component: ViewsUserId
327
+ }
328
+ ]
329
+ }
330
+ ]
331
+ },
332
+ {
333
+ path: '/:pathMatch(.*)*',
334
+ children: [
335
+ {
336
+ path: '',
337
+ component: Views404
338
+ }
339
+ ]
340
+ }
341
+ ]
342
+ ```
343
+
344
+ ##### type: 'wrap'
345
+
346
+ When `type` is set to `wrap`, the page component will act as a parent route container wrapping its child routes:
347
+
348
+ ```typescript
349
+ // src/views/user/index.config.ts
350
+ import { defineConfig } from '../../router/autoRouter'
351
+
352
+ export default defineConfig({
353
+ type: 'wrap'
354
+ })
355
+ ```
356
+
357
+ Generated route structure:
358
+
359
+ ```typescript
360
+ // src/router/autoRouter.ts
361
+ import type { RouteRecordRaw } from 'vue-router'
362
+ import Views404 from './../views/404.vue'
363
+ import ViewsHome from './../views/home/index.vue'
364
+ import ViewsUser from './../views/user/index.vue'
365
+ import ViewsUserId from './../views/user/[id]/index.vue'
366
+
367
+ type PageConfig = Partial<
368
+ Omit<RouteRecordRaw, 'path' | 'component' | 'children'> & {
369
+ type?: 'single' | 'wrap'
370
+ }
371
+ >
372
+
373
+ export const defineConfig = (config: PageConfig) => config
374
+
375
+ export const routes: RouteRecordRaw[] = [
376
+ {
377
+ path: '/',
378
+ children: [
379
+ {
380
+ path: '',
381
+ name: 'home',
382
+ component: ViewsHome
383
+ }
384
+ ]
385
+ },
386
+ {
387
+ path: '/user',
388
+ component: ViewsUser,
389
+ children: [
390
+ {
391
+ path: ':id',
392
+ children: [
393
+ {
394
+ path: '',
395
+ component: ViewsUserId
396
+ }
397
+ ]
398
+ }
399
+ ]
400
+ },
401
+ {
402
+ path: '/:pathMatch(.*)*',
403
+ children: [
404
+ {
405
+ path: '',
406
+ component: Views404
407
+ }
408
+ ]
409
+ }
410
+ ]
411
+ ```
412
+
413
+ ## ⚙️ Configuration Options
414
+
415
+ ### Plugin Configuration
416
+
417
+ | Option | Type | Default | Description |
418
+ | ------------ | ------------------ | --------------- | ----------------------------------- |
419
+ | `framework` | `'react' \| 'vue'` | `'react'` | Framework type |
420
+ | `pagesDir` | `string` | `'./src/pages'` | Pages directory |
421
+ | `routesFile` | `string` | `undefined` | Generated route file path |
422
+ | `keepHome` | `boolean` | `false` | Whether to keep home page path |
423
+ | `keepRoot` | `boolean` | `false` | Whether to keep root page path |
424
+ | `lazy` | `boolean` | `true` | Whether to enable lazy loading |
425
+ | `hmr` | `boolean` | `false` | Whether to enable hot module update |
426
+
427
+ ### Page Configuration
428
+
429
+ | Option | Type | Default | Description |
430
+ | ------ | -------------------- | ---------- | --------------------------- |
431
+ | `type` | `'single' \| 'wrap'` | `'single'` | Route type |
432
+ | `*` | `any` | `any` | Inherits from router config |
433
+
434
+ ## 📄 License
435
+
436
+ MIT