next-vite-router 1.0.2
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/LICENSE +21 -0
- package/README.md +177 -0
- package/dist/index.d.ts +84 -0
- package/dist/index.js +145 -0
- package/dist/plugin.d.ts +12 -0
- package/dist/plugin.js +59 -0
- package/package.json +59 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 Your Rlzee
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
# Next Vite Router
|
|
2
|
+
|
|
3
|
+
Next Vite Router is an npm package that provides Next.js-style, file-based routing for React applications built with Vite. It generates React Router route objects from a filesystem layout (pages, layouts, not-found), and it exposes a Vite plugin that injects a virtual module to generate routes at build/dev time.
|
|
4
|
+
|
|
5
|
+
This README focuses on how consumers install and use the package (no publishing instructions).
|
|
6
|
+
|
|
7
|
+
## Installation
|
|
8
|
+
|
|
9
|
+
Install with your package manager of choice:
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
pnpm add next-vite-router
|
|
13
|
+
# or
|
|
14
|
+
npm install next-vite-router
|
|
15
|
+
# or
|
|
16
|
+
yarn add next-vite-router
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
The package has peer dependencies: React, React DOM and React Router DOM. Make sure your project already includes compatible versions (React 18+ is recommended).
|
|
20
|
+
|
|
21
|
+
## Quick Start Vite plugin
|
|
22
|
+
|
|
23
|
+
The recommended and easiest way to use this library in a Vite app is via the Vite plugin. The plugin exposes a virtual module `virtual:next-vite-router` that provides a `generateRoutes()` function and re-exports `useRoutes` from `react-router-dom` for convenience.
|
|
24
|
+
|
|
25
|
+
Example `vite.config.ts`:
|
|
26
|
+
|
|
27
|
+
```ts
|
|
28
|
+
import { defineConfig } from 'vite';
|
|
29
|
+
import react from '@vitejs/plugin-react';
|
|
30
|
+
import { nextViteRouter } from 'next-vite-router';
|
|
31
|
+
|
|
32
|
+
export default defineConfig({
|
|
33
|
+
plugins: [
|
|
34
|
+
react(),
|
|
35
|
+
nextViteRouter({ pagesDir: 'src/pages' })
|
|
36
|
+
]
|
|
37
|
+
});
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Example usage inside your app (client entry):
|
|
41
|
+
|
|
42
|
+
```tsx
|
|
43
|
+
import React from 'react';
|
|
44
|
+
import { BrowserRouter } from 'react-router-dom';
|
|
45
|
+
import { generateRoutes, useRoutes } from 'virtual:next-vite-router';
|
|
46
|
+
|
|
47
|
+
const routes = generateRoutes();
|
|
48
|
+
|
|
49
|
+
function App() {
|
|
50
|
+
const element = useRoutes(routes);
|
|
51
|
+
return <BrowserRouter>{element}</BrowserRouter>;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export default App;
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Notes:
|
|
58
|
+
|
|
59
|
+
- The plugin default `pagesDir` is `src/app`. You can change it via options.
|
|
60
|
+
- The virtual module is `virtual:next-vite-router` (the plugin resolves it internally).
|
|
61
|
+
|
|
62
|
+
## Programmatic route generation
|
|
63
|
+
|
|
64
|
+
If you prefer to generate routes manually (for custom setups), the package exports helpers you can use with `import.meta.glob`.
|
|
65
|
+
|
|
66
|
+
Example:
|
|
67
|
+
|
|
68
|
+
```ts
|
|
69
|
+
import { createRouteGenerator } from 'next-vite-router';
|
|
70
|
+
|
|
71
|
+
// in a Vite environment
|
|
72
|
+
const pages = import.meta.glob('../../pages/**/page.tsx');
|
|
73
|
+
const layouts = import.meta.glob('../../pages/**/layout.tsx', { eager: true });
|
|
74
|
+
const notFounds = import.meta.glob('../../pages/**/not-found.tsx');
|
|
75
|
+
|
|
76
|
+
const generateRoutes = createRouteGenerator(pages, layouts, notFounds);
|
|
77
|
+
const routes = generateRoutes();
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
Use this when you need a fully custom glob layout or want to call the generator at runtime.
|
|
81
|
+
|
|
82
|
+
## API Reference
|
|
83
|
+
|
|
84
|
+
Exports from the package (see `src/index.ts`):
|
|
85
|
+
|
|
86
|
+
- `createRouteGenerator(pages, layouts, notFounds)` returns a function that builds `RouteObject[]` using your globs.
|
|
87
|
+
- `buildRouteTree` builds the intermediate route tree from page/layout/not-found globs.
|
|
88
|
+
- `treeToRoutes` converts the route tree to React Router routes.
|
|
89
|
+
- `registerMiddleware`, `clearMiddlewares` middleware helpers to manage registered middlewares.
|
|
90
|
+
- `configureRouter` configure router-level options.
|
|
91
|
+
- `nextViteRouter(options)` Vite plugin factory. Options:
|
|
92
|
+
- `pagesDir?: string` (default: `src/app`)
|
|
93
|
+
- `pageFile?: string` (default: `page.tsx`)
|
|
94
|
+
- `layoutFile?: string` (default: `layout.tsx`)
|
|
95
|
+
- `notFoundFile?: string` (default: `not-found.tsx`)
|
|
96
|
+
- Types exported: `RouterConfig`, `RouteNode`, `RouteMiddleware`, `NextViteRouterPluginOptions`.
|
|
97
|
+
|
|
98
|
+
### `configureRouter(config: RouterConfig)`
|
|
99
|
+
|
|
100
|
+
Use `configureRouter` to set global router options for runtime behavior. The function merges the provided `config` with any existing configuration.
|
|
101
|
+
|
|
102
|
+
Common `RouterConfig` fields:
|
|
103
|
+
|
|
104
|
+
- `loadingFallback?: React.ComponentType` component shown while lazy-loaded page components load.
|
|
105
|
+
- `pagesDir?: string` path used by the generator to resolve pages (useful if you need to override defaults at runtime).
|
|
106
|
+
- `enableLazyLoading?: boolean` when true, pages are wrapped to load lazily.
|
|
107
|
+
|
|
108
|
+
Example:
|
|
109
|
+
|
|
110
|
+
```ts
|
|
111
|
+
import { configureRouter } from 'next-vite-router';
|
|
112
|
+
|
|
113
|
+
configureRouter({
|
|
114
|
+
loadingFallback: () => <div>Loading...</div>,
|
|
115
|
+
enableLazyLoading: true,
|
|
116
|
+
});
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
Call `configureRouter` during app bootstrap before calling `generateRoutes()`.
|
|
120
|
+
|
|
121
|
+
### `registerMiddleware(pattern: RegExp, middleware: RouteMiddleware)`
|
|
122
|
+
|
|
123
|
+
`registerMiddleware` lets you register middleware functions that will be applied to route elements whose path matches the provided `pattern` (a `RegExp`). Middlewares receive the route element (`ReactElement`) and should return a new element (for example wrapping it with providers, guards, or layout components).
|
|
124
|
+
|
|
125
|
+
Important details:
|
|
126
|
+
|
|
127
|
+
- Middlewares are stored in insertion order and applied sequentially.
|
|
128
|
+
- To remove all registered middlewares, use `clearMiddlewares()`.
|
|
129
|
+
- The internal helper `applyMiddlewares(path, element)` is used when constructing the final route element.
|
|
130
|
+
|
|
131
|
+
Example:
|
|
132
|
+
|
|
133
|
+
```ts
|
|
134
|
+
import { registerMiddleware } from 'next-vite-router';
|
|
135
|
+
|
|
136
|
+
registerMiddleware(/^\/dashboard/, (element) => (
|
|
137
|
+
<AuthGuard>{element}</AuthGuard>
|
|
138
|
+
));
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
## Configuration options (plugin)
|
|
142
|
+
|
|
143
|
+
The plugin takes an options object. Defaults are:
|
|
144
|
+
|
|
145
|
+
```ts
|
|
146
|
+
{
|
|
147
|
+
pagesDir: 'src/app',
|
|
148
|
+
pageFile: 'page.tsx',
|
|
149
|
+
layoutFile: 'layout.tsx',
|
|
150
|
+
notFoundFile: 'not-found.tsx',
|
|
151
|
+
}
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
Pass a custom `pagesDir` if your project uses `src/pages` or another convention.
|
|
155
|
+
|
|
156
|
+
## Examples & Demos
|
|
157
|
+
|
|
158
|
+
If you want, I can add a small demo app showing:
|
|
159
|
+
|
|
160
|
+
- A minimal `src/pages` layout with nested layouts
|
|
161
|
+
- How `generateRoutes()` maps files to React Router routes
|
|
162
|
+
- A Vite dev server example showing HMR for page/layout changes
|
|
163
|
+
|
|
164
|
+
Tell me which example you'd prefer and I will scaffold it.
|
|
165
|
+
|
|
166
|
+
## Contributing
|
|
167
|
+
|
|
168
|
+
Contributions welcome. Suggested workflow:
|
|
169
|
+
|
|
170
|
+
1. Fork the repo
|
|
171
|
+
2. Create a branch
|
|
172
|
+
3. Run `pnpm install` and `pnpm run dev` to test locally
|
|
173
|
+
4. Open a PR with description and tests/examples if applicable
|
|
174
|
+
|
|
175
|
+
## License
|
|
176
|
+
|
|
177
|
+
MIT
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { default as default_2 } from 'react';
|
|
2
|
+
import { Plugin as Plugin_2 } from 'vite';
|
|
3
|
+
import { ReactElement } from 'react';
|
|
4
|
+
import { RouteObject } from 'react-router-dom';
|
|
5
|
+
|
|
6
|
+
export declare function buildRouteTree(pages: Record<string, () => Promise<any>>, layouts: Record<string, any>, notFounds: Record<string, () => Promise<any>>): RouteNode;
|
|
7
|
+
|
|
8
|
+
export declare function clearMiddlewares(): void;
|
|
9
|
+
|
|
10
|
+
export declare function configureRouter(config: RouterConfig): void;
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Create a lazy element wrapped with Suspense and apply middlewares
|
|
14
|
+
* @param loader - Function that loads the component
|
|
15
|
+
* @param cacheKey - Unique key for the cache
|
|
16
|
+
* @param routePath - Route path for middlewares
|
|
17
|
+
*/
|
|
18
|
+
export declare function createLazyElement(loader: () => Promise<any>, cacheKey: string, routePath?: string): default_2.ReactElement;
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Create a custom route generator function using your own files
|
|
22
|
+
*
|
|
23
|
+
* ⚠️ NOTE: This function is intended for advanced use only.
|
|
24
|
+
* For most cases, use the Vite plugin which automatically handles the paths.
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* // In your configuration file
|
|
28
|
+
* const pages = import.meta.glob("../../pages/**\\/page.tsx");
|
|
29
|
+
* const layouts = import.meta.glob("../../pages/**\\/layout.tsx", { eager: true });
|
|
30
|
+
* const notFounds = import.meta.glob("../../pages/**\\/not-found.tsx");
|
|
31
|
+
*
|
|
32
|
+
* export const generateCustomRoutes = createRouteGenerator(pages, layouts, notFounds);
|
|
33
|
+
*
|
|
34
|
+
* // Then use it
|
|
35
|
+
* const routes = generateCustomRoutes();
|
|
36
|
+
*/
|
|
37
|
+
export declare function createRouteGenerator(pages: Record<string, () => Promise<any>>, layouts: Record<string, any>, notFounds: Record<string, () => Promise<any>>): () => RouteObject[];
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Extract the route path from a file path
|
|
41
|
+
* @example "../../app/blog/[id]/page.tsx" -> "blog/[id]"
|
|
42
|
+
* @example "../../app/page.tsx" -> ""
|
|
43
|
+
*/
|
|
44
|
+
export declare function extractRoutePath(filePath: string): string;
|
|
45
|
+
|
|
46
|
+
export declare function nextViteRouter(options?: NextViteRouterPluginOptions): Plugin_2;
|
|
47
|
+
|
|
48
|
+
export declare type NextViteRouterPluginOptions = {
|
|
49
|
+
pagesDir?: string;
|
|
50
|
+
pageFile?: string;
|
|
51
|
+
layoutFile?: string;
|
|
52
|
+
notFoundFile?: string;
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Normalize a Next.js segment to a React Router segment
|
|
57
|
+
* @example (admin) -> ""
|
|
58
|
+
* @example [id] -> :id
|
|
59
|
+
* @example [...slug] -> *
|
|
60
|
+
*/
|
|
61
|
+
export declare function normalizeSegment(segment: string): string;
|
|
62
|
+
|
|
63
|
+
export declare function registerMiddleware(pattern: RegExp, middleware: RouteMiddleware): void;
|
|
64
|
+
|
|
65
|
+
export declare type RouteMiddleware = (element: ReactElement) => ReactElement;
|
|
66
|
+
|
|
67
|
+
export declare type RouteNode = {
|
|
68
|
+
segment: string;
|
|
69
|
+
fullPath: string;
|
|
70
|
+
page?: any;
|
|
71
|
+
layout?: any;
|
|
72
|
+
notFound?: any;
|
|
73
|
+
children: Map<string, RouteNode>;
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
export declare type RouterConfig = {
|
|
77
|
+
loadingFallback?: React.ComponentType;
|
|
78
|
+
pagesDir?: string;
|
|
79
|
+
enableLazyLoading?: boolean;
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
export declare function treeToRoutes(node: RouteNode, isRoot?: boolean, currentPath?: string): RouteObject[];
|
|
83
|
+
|
|
84
|
+
export { }
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
import i, { lazy as z, Suspense as b } from "react";
|
|
2
|
+
import { nextViteRouter as N } from "./plugin.js";
|
|
3
|
+
function f(e) {
|
|
4
|
+
return /^\([^)]+\)$/.test(e) ? "" : /^\[\.\.\.(.+)\]$/.test(e) ? "*" : /^\[([^\]]+)\]$/.test(e) ? e.replace(/^\[([^\]]+)\]$/, ":$1") : e;
|
|
5
|
+
}
|
|
6
|
+
function F(e) {
|
|
7
|
+
return e.replace("../../app/", "").replace(/\/?(page|layout|not-found)\.tsx$/, "");
|
|
8
|
+
}
|
|
9
|
+
let m = {};
|
|
10
|
+
function S(e) {
|
|
11
|
+
m = { ...m, ...e };
|
|
12
|
+
}
|
|
13
|
+
function C() {
|
|
14
|
+
return m;
|
|
15
|
+
}
|
|
16
|
+
let d = [];
|
|
17
|
+
function k(e, a) {
|
|
18
|
+
d.push({ pattern: e, middleware: a });
|
|
19
|
+
}
|
|
20
|
+
function T() {
|
|
21
|
+
d = [];
|
|
22
|
+
}
|
|
23
|
+
function g(e, a) {
|
|
24
|
+
let r = a;
|
|
25
|
+
for (const n of d)
|
|
26
|
+
n.pattern.test(e) && (r = n.middleware(r));
|
|
27
|
+
return r;
|
|
28
|
+
}
|
|
29
|
+
const x = () => i.createElement("div"), E = /* @__PURE__ */ new Map();
|
|
30
|
+
function $(e, a, r) {
|
|
31
|
+
const n = C();
|
|
32
|
+
if (n.enableLazyLoading === !1) {
|
|
33
|
+
const u = i.lazy(e), c = i.createElement(u);
|
|
34
|
+
return r ? g(r, c) : c;
|
|
35
|
+
}
|
|
36
|
+
let t = E.get(a);
|
|
37
|
+
t || (t = z(e), E.set(a, t));
|
|
38
|
+
const o = n.loadingFallback || x, l = i.createElement(
|
|
39
|
+
b,
|
|
40
|
+
{ fallback: i.createElement(o) },
|
|
41
|
+
i.createElement(t)
|
|
42
|
+
);
|
|
43
|
+
return r ? g(r, l) : l;
|
|
44
|
+
}
|
|
45
|
+
function p(e, a, r, n) {
|
|
46
|
+
const t = F(a), o = t ? t.split("/") : [];
|
|
47
|
+
let l = e, u = "";
|
|
48
|
+
o.forEach((c, w) => {
|
|
49
|
+
u = u ? `${u}/${c}` : c, l.children.has(c) || l.children.set(c, {
|
|
50
|
+
segment: c,
|
|
51
|
+
fullPath: u,
|
|
52
|
+
children: /* @__PURE__ */ new Map()
|
|
53
|
+
}), l = l.children.get(c), w === o.length - 1 && (l[n] = r);
|
|
54
|
+
}), o.length === 0 && (e[n] = r);
|
|
55
|
+
}
|
|
56
|
+
function M(e, a, r) {
|
|
57
|
+
const n = {
|
|
58
|
+
segment: "",
|
|
59
|
+
fullPath: "",
|
|
60
|
+
children: /* @__PURE__ */ new Map()
|
|
61
|
+
};
|
|
62
|
+
return Object.entries(a).forEach(([t, o]) => {
|
|
63
|
+
p(n, t, o.default, "layout");
|
|
64
|
+
}), Object.entries(e).forEach(([t, o]) => {
|
|
65
|
+
p(n, t, o, "page");
|
|
66
|
+
}), Object.entries(r).forEach(([t, o]) => {
|
|
67
|
+
p(n, t, o, "notFound");
|
|
68
|
+
}), n;
|
|
69
|
+
}
|
|
70
|
+
function h(e, a, r = !1) {
|
|
71
|
+
const n = $(
|
|
72
|
+
async () => ({ default: (await e.page()).default }),
|
|
73
|
+
`page:${e.fullPath || a}`,
|
|
74
|
+
a
|
|
75
|
+
);
|
|
76
|
+
return r ? { index: !0, element: n } : { path: f(e.segment), element: n };
|
|
77
|
+
}
|
|
78
|
+
function y(e) {
|
|
79
|
+
return {
|
|
80
|
+
path: "*",
|
|
81
|
+
element: $(
|
|
82
|
+
async () => ({ default: (await e.notFound()).default }),
|
|
83
|
+
`notfound:${e.fullPath}`
|
|
84
|
+
)
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
function s(e, a) {
|
|
88
|
+
const r = [];
|
|
89
|
+
return e.children.forEach((n, t) => {
|
|
90
|
+
const o = f(t), l = o ? a ? `${a}/${o}` : `/${o}` : a;
|
|
91
|
+
r.push(...R(n, !1, l));
|
|
92
|
+
}), r;
|
|
93
|
+
}
|
|
94
|
+
function R(e, a = !1, r = "") {
|
|
95
|
+
const n = [];
|
|
96
|
+
if (a && e.layout) {
|
|
97
|
+
const t = [];
|
|
98
|
+
return e.page && t.push(h(e, "/", !0)), t.push(...s(e, "")), e.notFound && t.push(y(e)), n.push({
|
|
99
|
+
path: "/",
|
|
100
|
+
element: i.createElement(e.layout),
|
|
101
|
+
children: t
|
|
102
|
+
}), n;
|
|
103
|
+
}
|
|
104
|
+
if (e.layout) {
|
|
105
|
+
const t = f(e.segment);
|
|
106
|
+
if (!t)
|
|
107
|
+
return s(e, r);
|
|
108
|
+
const o = r + "/" + t, l = [];
|
|
109
|
+
return e.page && l.push(h(e, o, !0)), l.push(...s(e, o)), e.notFound && l.push(y(e)), n.push({
|
|
110
|
+
path: t,
|
|
111
|
+
element: i.createElement(e.layout),
|
|
112
|
+
children: l.length > 0 ? l : void 0
|
|
113
|
+
}), n;
|
|
114
|
+
}
|
|
115
|
+
if (e.page) {
|
|
116
|
+
const t = f(e.segment);
|
|
117
|
+
if (!t)
|
|
118
|
+
return s(e, r);
|
|
119
|
+
const o = r + "/" + t, l = s(e, o), u = h(e, o, !1);
|
|
120
|
+
return n.push({
|
|
121
|
+
path: u.path,
|
|
122
|
+
element: u.element,
|
|
123
|
+
children: l.length > 0 ? l : void 0
|
|
124
|
+
}), n;
|
|
125
|
+
}
|
|
126
|
+
return s(e, r);
|
|
127
|
+
}
|
|
128
|
+
function j(e, a, r) {
|
|
129
|
+
return () => {
|
|
130
|
+
const n = M(e, a, r);
|
|
131
|
+
return R(n, !0);
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
export {
|
|
135
|
+
M as buildRouteTree,
|
|
136
|
+
T as clearMiddlewares,
|
|
137
|
+
S as configureRouter,
|
|
138
|
+
$ as createLazyElement,
|
|
139
|
+
j as createRouteGenerator,
|
|
140
|
+
F as extractRoutePath,
|
|
141
|
+
N as nextViteRouter,
|
|
142
|
+
f as normalizeSegment,
|
|
143
|
+
k as registerMiddleware,
|
|
144
|
+
R as treeToRoutes
|
|
145
|
+
};
|
package/dist/plugin.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { Plugin as Plugin_2 } from 'vite';
|
|
2
|
+
|
|
3
|
+
export declare function nextViteRouter(options?: NextViteRouterPluginOptions): Plugin_2;
|
|
4
|
+
|
|
5
|
+
export declare type NextViteRouterPluginOptions = {
|
|
6
|
+
pagesDir?: string;
|
|
7
|
+
pageFile?: string;
|
|
8
|
+
layoutFile?: string;
|
|
9
|
+
notFoundFile?: string;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export { }
|
package/dist/plugin.js
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
function d(i = {}) {
|
|
2
|
+
const {
|
|
3
|
+
pagesDir: t = "src/app",
|
|
4
|
+
pageFile: n = "page.tsx",
|
|
5
|
+
layoutFile: a = "layout.tsx",
|
|
6
|
+
notFoundFile: u = "not-found.tsx"
|
|
7
|
+
} = i, s = "virtual:next-vite-router", o = "\0" + s;
|
|
8
|
+
return {
|
|
9
|
+
name: "next-vite-router",
|
|
10
|
+
resolveId(e) {
|
|
11
|
+
if (e === s)
|
|
12
|
+
return o;
|
|
13
|
+
},
|
|
14
|
+
load(e) {
|
|
15
|
+
if (e === o)
|
|
16
|
+
return `
|
|
17
|
+
import { buildRouteTree, treeToRoutes, normalizeSegment, createLazyElement } from 'next-vite-router';
|
|
18
|
+
|
|
19
|
+
const pagesGlob = import.meta.glob('/${t}/**/${n}');
|
|
20
|
+
const layoutsGlob = import.meta.glob('/${t}/**/${a}', { eager: true });
|
|
21
|
+
const notFoundsGlob = import.meta.glob('/${t}/**/${u}');
|
|
22
|
+
|
|
23
|
+
const transformPath = (path) => path.replace('/${t}/', '');
|
|
24
|
+
|
|
25
|
+
const pages = Object.fromEntries(
|
|
26
|
+
Object.entries(pagesGlob).map(([key, value]) => [transformPath(key), value])
|
|
27
|
+
);
|
|
28
|
+
const layouts = Object.fromEntries(
|
|
29
|
+
Object.entries(layoutsGlob).map(([key, value]) => [transformPath(key), value])
|
|
30
|
+
);
|
|
31
|
+
const notFounds = Object.fromEntries(
|
|
32
|
+
Object.entries(notFoundsGlob).map(([key, value]) => [transformPath(key), value])
|
|
33
|
+
);
|
|
34
|
+
|
|
35
|
+
export function generateRoutes() {
|
|
36
|
+
const tree = buildRouteTree(pages, layouts, notFounds);
|
|
37
|
+
const routes = treeToRoutes(tree, true);
|
|
38
|
+
return routes;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export { useRoutes } from 'react-router-dom';
|
|
42
|
+
`;
|
|
43
|
+
},
|
|
44
|
+
handleHotUpdate({ file: e, server: r }) {
|
|
45
|
+
if (e.includes(t) && (e.endsWith(n) || e.endsWith(a) || e.endsWith(u))) {
|
|
46
|
+
const l = r.moduleGraph.getModuleById(
|
|
47
|
+
o
|
|
48
|
+
);
|
|
49
|
+
l && (r.moduleGraph.invalidateModule(l), r.ws.send({
|
|
50
|
+
type: "full-reload",
|
|
51
|
+
path: "*"
|
|
52
|
+
}));
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
export {
|
|
58
|
+
d as nextViteRouter
|
|
59
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "next-vite-router",
|
|
3
|
+
"version": "1.0.2",
|
|
4
|
+
"description": "Next.js-like file-based routing for React + Vite",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"import": "./dist/index.js",
|
|
11
|
+
"types": "./dist/index.d.ts"
|
|
12
|
+
},
|
|
13
|
+
"./plugin": {
|
|
14
|
+
"import": "./dist/plugin.js",
|
|
15
|
+
"types": "./dist/plugin.d.ts"
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
"files": [
|
|
19
|
+
"dist",
|
|
20
|
+
"README.md",
|
|
21
|
+
"LICENSE"
|
|
22
|
+
],
|
|
23
|
+
"keywords": [
|
|
24
|
+
"react",
|
|
25
|
+
"vite",
|
|
26
|
+
"router",
|
|
27
|
+
"nextjs",
|
|
28
|
+
"file-based-routing",
|
|
29
|
+
"filesystem-router",
|
|
30
|
+
"react-router"
|
|
31
|
+
],
|
|
32
|
+
"author": "Rlzee",
|
|
33
|
+
"repository": {
|
|
34
|
+
"type": "git",
|
|
35
|
+
"url": "https://github.com/Rlzee/next-vite-router"
|
|
36
|
+
},
|
|
37
|
+
"homepage": "https://github.com/Rlzee/next-vite-router#readme",
|
|
38
|
+
"license": "MIT",
|
|
39
|
+
"peerDependencies": {
|
|
40
|
+
"react": "^18.0.0",
|
|
41
|
+
"react-dom": "^18.0.0",
|
|
42
|
+
"react-router-dom": "^6.0.0",
|
|
43
|
+
"vite": "^5.0.0"
|
|
44
|
+
},
|
|
45
|
+
"devDependencies": {
|
|
46
|
+
"@types/node": "^24.10.1",
|
|
47
|
+
"@types/react": "^18.0.0",
|
|
48
|
+
"@types/react-dom": "^18.0.0",
|
|
49
|
+
"typescript": "^5.0.0",
|
|
50
|
+
"vite": "^5.0.0",
|
|
51
|
+
"vite-plugin-dts": "^3.0.0"
|
|
52
|
+
},
|
|
53
|
+
"scripts": {
|
|
54
|
+
"dev": "vite build --watch",
|
|
55
|
+
"build": "vite build",
|
|
56
|
+
"test:local": "node test/test-package.js",
|
|
57
|
+
"preview": "pnpm pack --dry-run"
|
|
58
|
+
}
|
|
59
|
+
}
|