next-vite-router 1.2.2 → 1.2.3
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 +14 -22
- package/dist/cli.cjs +1 -1
- package/dist/plugin.js +87 -72
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -6,33 +6,19 @@ Define routes with folders and let the package generate the
|
|
|
6
6
|
[React Router](https://reactrouter.com/) `RouteObject[]`. It does not replace
|
|
7
7
|
React Router, navigation, history, loaders, or application state.
|
|
8
8
|
|
|
9
|
-
## Release notes
|
|
10
|
-
|
|
11
|
-
### Plugin import
|
|
12
|
-
|
|
13
|
-
The Vite plugin is no longer exported from the main
|
|
14
|
-
`next-vite-router` entry point. Existing imports must be migrated:
|
|
15
|
-
|
|
16
|
-
```ts
|
|
17
|
-
// Previous import
|
|
18
|
-
import { nextViteRouter } from "next-vite-router";
|
|
19
|
-
|
|
20
|
-
// Current import
|
|
21
|
-
import { nextViteRouter } from "next-vite-router/plugin";
|
|
22
|
-
```
|
|
23
|
-
|
|
24
|
-
The plugin remains available through `next-vite-router/plugin`. This separation
|
|
25
|
-
prevents the plugin's Node dependencies from being included in the application's
|
|
26
|
-
browser dependency graph.
|
|
27
|
-
|
|
28
9
|
## Start here
|
|
29
10
|
|
|
30
11
|
```bash
|
|
31
12
|
npm create vite@latest my-app -- --template react-ts
|
|
32
13
|
cd my-app
|
|
33
|
-
npm install next-vite-router
|
|
14
|
+
npm install next-vite-router
|
|
34
15
|
```
|
|
35
16
|
|
|
17
|
+
`next-vite-router` declares `react-router-dom` as a peer dependency. Recent
|
|
18
|
+
versions of npm install this dependency automatically; if your package manager
|
|
19
|
+
does not resolve peer dependencies automatically, install
|
|
20
|
+
`react-router-dom` explicitly.
|
|
21
|
+
|
|
36
22
|
Add the plugin to `vite.config.ts`:
|
|
37
23
|
|
|
38
24
|
```ts
|
|
@@ -203,8 +189,14 @@ No manual declaration for the virtual module is required.
|
|
|
203
189
|
|
|
204
190
|
Pages and `not-found.tsx` files use Vite's non-eager `import.meta.glob`, so
|
|
205
191
|
Vite can emit separate chunks for pages. Layouts are eager because they wrap
|
|
206
|
-
the generated route tree
|
|
207
|
-
|
|
192
|
+
the generated route tree. Vite handles ordinary content changes to pages,
|
|
193
|
+
layouts, and `not-found.tsx` through its normal HMR mechanism. Creating,
|
|
194
|
+
deleting, or renaming a route-related file also refreshes the generated route
|
|
195
|
+
module and route declarations. Because Vite cannot reliably preserve a cached
|
|
196
|
+
route tree when an `import.meta.glob` entry is added or removed, these
|
|
197
|
+
structural changes trigger a full-page reload as a fallback. Lazy-loaded route
|
|
198
|
+
components remain lazy-loaded during normal navigation. Lazy loading is
|
|
199
|
+
enabled by default:
|
|
208
200
|
|
|
209
201
|
```tsx
|
|
210
202
|
import { configureRouter } from "next-vite-router";
|
package/dist/cli.cjs
CHANGED
package/dist/plugin.js
CHANGED
|
@@ -1,60 +1,60 @@
|
|
|
1
1
|
import h from "node:fs";
|
|
2
2
|
import l from "node:path";
|
|
3
|
-
import { a as
|
|
4
|
-
function
|
|
5
|
-
const e =
|
|
3
|
+
import { a as b, n as j } from "./tree-HwBRWJNI.js";
|
|
4
|
+
function $(n) {
|
|
5
|
+
const e = n.split(l.sep).filter(Boolean).map(j).filter(Boolean);
|
|
6
6
|
return e.length > 0 ? `/${e.join("/")}` : "/";
|
|
7
7
|
}
|
|
8
|
-
function
|
|
9
|
-
const
|
|
10
|
-
function
|
|
11
|
-
for (const
|
|
12
|
-
const
|
|
13
|
-
if (
|
|
14
|
-
|
|
15
|
-
else if (
|
|
16
|
-
const
|
|
17
|
-
const
|
|
18
|
-
if (
|
|
19
|
-
return { name:
|
|
20
|
-
const
|
|
21
|
-
return
|
|
22
|
-
}).filter((
|
|
23
|
-
|
|
24
|
-
const
|
|
25
|
-
if (
|
|
26
|
-
const
|
|
27
|
-
|
|
8
|
+
function T(n, e) {
|
|
9
|
+
const r = /* @__PURE__ */ new Map();
|
|
10
|
+
function i(a) {
|
|
11
|
+
for (const o of h.readdirSync(a, { withFileTypes: !0 })) {
|
|
12
|
+
const p = l.join(a, o.name);
|
|
13
|
+
if (o.isDirectory())
|
|
14
|
+
i(p);
|
|
15
|
+
else if (o.isFile() && o.name === e) {
|
|
16
|
+
const s = l.relative(n, a), u = s.split(l.sep).filter(Boolean), y = u.map((t) => {
|
|
17
|
+
const c = t.match(/^\[\[\.\.\.(.+)\]\]$/);
|
|
18
|
+
if (c)
|
|
19
|
+
return { name: c[1], optional: !0 };
|
|
20
|
+
const m = t.match(/^\[\.\.\.(.+)\]$/);
|
|
21
|
+
return m ? { name: m[1], optional: !1 } : void 0;
|
|
22
|
+
}).filter((t) => !!t), d = $(s);
|
|
23
|
+
r.set(d, { path: d, params: y });
|
|
24
|
+
const f = u[u.length - 1];
|
|
25
|
+
if (f == null ? void 0 : f.match(/^\[\[\.\.\.(.+)\]\]$/)) {
|
|
26
|
+
const t = u.slice(0, -1).join(l.sep), c = $(t);
|
|
27
|
+
r.has(c) || r.set(c, { path: c, params: [] });
|
|
28
28
|
}
|
|
29
29
|
}
|
|
30
30
|
}
|
|
31
31
|
}
|
|
32
|
-
return h.existsSync(
|
|
32
|
+
return h.existsSync(n) && i(n), [...r.values()].sort((a, o) => a.path.localeCompare(o.path));
|
|
33
33
|
}
|
|
34
|
-
function
|
|
35
|
-
const
|
|
36
|
-
function
|
|
37
|
-
for (const
|
|
38
|
-
const
|
|
39
|
-
|
|
34
|
+
function F(n, e) {
|
|
35
|
+
const r = [];
|
|
36
|
+
function i(a) {
|
|
37
|
+
for (const o of h.readdirSync(a, { withFileTypes: !0 })) {
|
|
38
|
+
const p = l.join(a, o.name);
|
|
39
|
+
o.isDirectory() ? i(p) : o.isFile() && o.name === e && r.push(l.relative(n, p));
|
|
40
40
|
}
|
|
41
41
|
}
|
|
42
|
-
return h.existsSync(
|
|
42
|
+
return h.existsSync(n) && i(n), r;
|
|
43
43
|
}
|
|
44
|
-
function
|
|
45
|
-
const e =
|
|
44
|
+
function k(n) {
|
|
45
|
+
const e = n.match(/^\/(?:\[\.\.\.|:)([^/\]]+)\]?$/);
|
|
46
46
|
return e == null ? void 0 : e[1];
|
|
47
47
|
}
|
|
48
|
-
function
|
|
49
|
-
const e =
|
|
50
|
-
`),
|
|
51
|
-
const
|
|
52
|
-
...
|
|
53
|
-
...a.map(({ name:
|
|
48
|
+
function w(n) {
|
|
49
|
+
const e = n.map(({ path: i }) => ` | "${i}"`).join(`
|
|
50
|
+
`), r = n.map(({ path: i, params: a }) => {
|
|
51
|
+
const o = i.split("/").map((s) => k(`/${s}`)).filter((s) => !!s), p = o.length > 0 || a.length > 0 ? [
|
|
52
|
+
...o.map((s) => ` ${s}: string;`),
|
|
53
|
+
...a.map(({ name: s, optional: u }) => ` ${s}${u ? "?" : ""}: string;`)
|
|
54
54
|
].join(`
|
|
55
55
|
`) : " [key: string]: never;";
|
|
56
|
-
return ` "${
|
|
57
|
-
${
|
|
56
|
+
return ` "${i}": {
|
|
57
|
+
${p}
|
|
58
58
|
};`;
|
|
59
59
|
}).join(`
|
|
60
60
|
`);
|
|
@@ -70,7 +70,7 @@ ${e || ' | "/"'};
|
|
|
70
70
|
: never;
|
|
71
71
|
|
|
72
72
|
export interface RoutePathParams {
|
|
73
|
-
${
|
|
73
|
+
${r}
|
|
74
74
|
}
|
|
75
75
|
|
|
76
76
|
export const generateRoutes: () => RouteObject[];
|
|
@@ -80,53 +80,62 @@ ${n}
|
|
|
80
80
|
}
|
|
81
81
|
`;
|
|
82
82
|
}
|
|
83
|
-
function
|
|
83
|
+
function D(n = {}) {
|
|
84
84
|
const {
|
|
85
85
|
pagesDir: e = "src/app",
|
|
86
|
-
pageFile:
|
|
87
|
-
layoutFile:
|
|
86
|
+
pageFile: r = "page.tsx",
|
|
87
|
+
layoutFile: i = "layout.tsx",
|
|
88
88
|
notFoundFile: a = "not-found.tsx"
|
|
89
|
-
} =
|
|
90
|
-
let u = "", y = "";
|
|
91
|
-
function
|
|
92
|
-
const
|
|
93
|
-
h.writeFileSync(y,
|
|
89
|
+
} = n, o = { pagesDir: e, pageFile: r, layoutFile: i, notFoundFile: a }, p = "virtual:next-vite-router", s = "\0" + p;
|
|
90
|
+
let u = "", y = "", d, f;
|
|
91
|
+
function g() {
|
|
92
|
+
const t = w(T(u, r));
|
|
93
|
+
h.writeFileSync(y, t, "utf-8");
|
|
94
94
|
}
|
|
95
95
|
return {
|
|
96
96
|
name: "next-vite-router",
|
|
97
|
-
configResolved(
|
|
98
|
-
u = l.resolve(
|
|
97
|
+
configResolved(t) {
|
|
98
|
+
u = l.resolve(t.root, e), y = l.join(l.dirname(u), "virtual-next-vite-router.d.ts"), b(F(u, r), o), g();
|
|
99
99
|
},
|
|
100
|
-
configureServer(
|
|
101
|
-
|
|
102
|
-
|
|
100
|
+
configureServer(t) {
|
|
101
|
+
if (d === t)
|
|
102
|
+
return;
|
|
103
|
+
f == null || f(), d = t;
|
|
104
|
+
const c = (P) => {
|
|
105
|
+
if (l.relative(u, P).startsWith("..") || ![r, i, a].includes(l.basename(P)))
|
|
103
106
|
return;
|
|
104
107
|
try {
|
|
105
|
-
|
|
106
|
-
} catch (
|
|
107
|
-
|
|
108
|
-
|
|
108
|
+
b(F(u, r), o);
|
|
109
|
+
} catch (x) {
|
|
110
|
+
t.config.logger.error(
|
|
111
|
+
x instanceof Error ? x.message : String(x)
|
|
109
112
|
);
|
|
110
113
|
return;
|
|
111
114
|
}
|
|
112
|
-
|
|
113
|
-
const
|
|
114
|
-
|
|
115
|
+
g();
|
|
116
|
+
const v = t.moduleGraph.getModuleById(s);
|
|
117
|
+
v && (t.moduleGraph.invalidateModule(v), m && clearTimeout(m), m = setTimeout(() => {
|
|
118
|
+
m = void 0, t.ws.send({ type: "full-reload", path: "*" });
|
|
119
|
+
}, 0));
|
|
115
120
|
};
|
|
116
|
-
|
|
121
|
+
let m;
|
|
122
|
+
const R = () => {
|
|
123
|
+
m && (clearTimeout(m), m = void 0), t.watcher.off("add", c), t.watcher.off("unlink", c), t.watcher.off("close", R), d === t && (d = void 0, f = void 0);
|
|
124
|
+
};
|
|
125
|
+
t.watcher.on("add", c), t.watcher.on("unlink", c), t.watcher.once("close", R), f = R;
|
|
117
126
|
},
|
|
118
|
-
resolveId(
|
|
119
|
-
if (
|
|
120
|
-
return
|
|
127
|
+
resolveId(t) {
|
|
128
|
+
if (t === p)
|
|
129
|
+
return s;
|
|
121
130
|
},
|
|
122
|
-
load(
|
|
123
|
-
if (
|
|
131
|
+
load(t) {
|
|
132
|
+
if (t === s)
|
|
124
133
|
return `
|
|
125
134
|
import { buildRouteTree, treeToRoutes, normalizeSegment, createLazyElement, useParams } from 'next-vite-router';
|
|
126
135
|
import { Link, useRoutes } from 'react-router-dom';
|
|
127
136
|
|
|
128
|
-
const pagesGlob = import.meta.glob('/${e}/**/${
|
|
129
|
-
const layoutsGlob = import.meta.glob('/${e}/**/${
|
|
137
|
+
const pagesGlob = import.meta.glob('/${e}/**/${r}');
|
|
138
|
+
const layoutsGlob = import.meta.glob('/${e}/**/${i}', { eager: true });
|
|
130
139
|
const notFoundsGlob = import.meta.glob('/${e}/**/${a}');
|
|
131
140
|
|
|
132
141
|
const transformPath = (path) => path.replace('/${e}/', '');
|
|
@@ -142,7 +151,7 @@ const notFounds = Object.fromEntries(
|
|
|
142
151
|
);
|
|
143
152
|
|
|
144
153
|
export function generateRoutes() {
|
|
145
|
-
const tree = buildRouteTree(pages, layouts, notFounds, ${JSON.stringify(
|
|
154
|
+
const tree = buildRouteTree(pages, layouts, notFounds, ${JSON.stringify(o)});
|
|
146
155
|
const routes = treeToRoutes(tree, true);
|
|
147
156
|
return routes;
|
|
148
157
|
}
|
|
@@ -154,6 +163,12 @@ export function Router() {
|
|
|
154
163
|
|
|
155
164
|
let routes;
|
|
156
165
|
|
|
166
|
+
if (import.meta.hot) {
|
|
167
|
+
import.meta.hot.accept(() => {
|
|
168
|
+
routes = undefined;
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
|
|
157
172
|
export { Link, useRoutes };
|
|
158
173
|
export { useParams };
|
|
159
174
|
`;
|
|
@@ -161,5 +176,5 @@ export { useParams };
|
|
|
161
176
|
};
|
|
162
177
|
}
|
|
163
178
|
export {
|
|
164
|
-
|
|
179
|
+
D as nextViteRouter
|
|
165
180
|
};
|