next-vite-router 1.1.0 → 1.2.0
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 +46 -9
- package/dist/cli.cjs +33 -28
- package/dist/index.d.ts +25 -16
- package/dist/index.js +155 -115
- package/dist/path-BodMUTCM.js +14 -0
- package/dist/plugin.js +126 -4
- package/package.json +3 -1
- package/dist/index.plugin--ecyiAem.js +0 -132
package/README.md
CHANGED
|
@@ -6,6 +6,25 @@ 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
|
+
|
|
9
28
|
## Start here
|
|
10
29
|
|
|
11
30
|
```bash
|
|
@@ -83,16 +102,19 @@ npm run dev
|
|
|
83
102
|
|
|
84
103
|
## Use React Router directly
|
|
85
104
|
|
|
86
|
-
`Router` is only a convenience wrapper around
|
|
87
|
-
|
|
105
|
+
`Router` is only a convenience wrapper around `useRoutes(routes)`. Routes are
|
|
106
|
+
generated lazily on the first render, so calls to `configureRouter` and
|
|
107
|
+
`registerMiddleware` made during application setup are applied before route
|
|
108
|
+
elements are created. You can keep using React Router APIs:
|
|
88
109
|
|
|
89
110
|
```tsx
|
|
90
111
|
import {
|
|
91
112
|
Link,
|
|
92
113
|
generateRoutes,
|
|
93
114
|
useRoutes,
|
|
115
|
+
useParams,
|
|
94
116
|
} from "virtual:next-vite-router";
|
|
95
|
-
import { useNavigate
|
|
117
|
+
import { useNavigate } from "react-router-dom";
|
|
96
118
|
|
|
97
119
|
const routes = generateRoutes();
|
|
98
120
|
|
|
@@ -107,9 +129,10 @@ export default function App() {
|
|
|
107
129
|
}
|
|
108
130
|
```
|
|
109
131
|
|
|
110
|
-
Use `useNavigate`,
|
|
111
|
-
|
|
112
|
-
|
|
132
|
+
Use `useNavigate`, loaders, actions, and other React Router APIs from
|
|
133
|
+
`react-router-dom`. The package `useParams` hook is also available from the
|
|
134
|
+
virtual module and maps catch-all names such as `slug`. The package does not
|
|
135
|
+
create competing navigation or data-loading APIs.
|
|
113
136
|
|
|
114
137
|
## File conventions
|
|
115
138
|
|
|
@@ -119,10 +142,19 @@ navigation or data-loading APIs.
|
|
|
119
142
|
| `layout.tsx` | Nested layout rendered with React Router's `Outlet` |
|
|
120
143
|
| `not-found.tsx` | `*` route for that subtree |
|
|
121
144
|
| `[id]` | Dynamic segment `:id` |
|
|
122
|
-
| `[...slug]` | Catch-all `*` segment |
|
|
123
|
-
| `[[...slug]]` | Optional catch-all `*` segment |
|
|
145
|
+
| `[...slug]` | Catch-all `*` segment; package `useParams` exposes it as `slug` |
|
|
146
|
+
| `[[...slug]]` | Optional catch-all `*` segment; package `useParams` exposes it as `slug` |
|
|
124
147
|
| `(admin)` | Route group omitted from the URL |
|
|
125
148
|
|
|
149
|
+
Catch-all pages and `not-found.tsx` at the same level both use React Router's
|
|
150
|
+
`*` path and should not be declared together if their fallback behavior must
|
|
151
|
+
be distinct. The catch-all parameter provider wraps the page route, so a
|
|
152
|
+
layout cannot read that parameter through the package `useParams` hook.
|
|
153
|
+
|
|
154
|
+
The Vite plugin accepts custom `pageFile`, `layoutFile`, and `notFoundFile`
|
|
155
|
+
names. `createRouteGenerator` accepts the same options, plus `pagesDir`, as
|
|
156
|
+
its optional fourth argument when custom glob paths or extensions are used.
|
|
157
|
+
|
|
126
158
|
Layouts are the recommended way to add route-scoped navigation, providers, or
|
|
127
159
|
authorization:
|
|
128
160
|
|
|
@@ -146,6 +178,10 @@ export default function DashboardLayout() {
|
|
|
146
178
|
}
|
|
147
179
|
```
|
|
148
180
|
|
|
181
|
+
The Vite plugin is a Node/Vite integration and should be imported from
|
|
182
|
+
`next-vite-router/plugin`; the main `next-vite-router` entry remains safe for
|
|
183
|
+
browser application code.
|
|
184
|
+
|
|
149
185
|
## Type-safe paths
|
|
150
186
|
|
|
151
187
|
The Vite plugin generates `virtual-next-vite-router.d.ts` automatically:
|
|
@@ -167,7 +203,8 @@ No manual declaration for the virtual module is required.
|
|
|
167
203
|
|
|
168
204
|
Pages and `not-found.tsx` files use Vite's non-eager `import.meta.glob`, so
|
|
169
205
|
Vite can emit separate chunks for pages. Layouts are eager because they wrap
|
|
170
|
-
the generated route tree
|
|
206
|
+
the generated route tree; changing a layout can therefore cause a full
|
|
207
|
+
development reload. Lazy loading is enabled by default:
|
|
171
208
|
|
|
172
209
|
```tsx
|
|
173
210
|
import { configureRouter } from "next-vite-router";
|
package/dist/cli.cjs
CHANGED
|
@@ -47,7 +47,7 @@ function detectPackageManager() {
|
|
|
47
47
|
case "pnpm":
|
|
48
48
|
return {
|
|
49
49
|
name: "pnpm",
|
|
50
|
-
createProjectCommand: (projectName, template) => `pnpm create vite@latest ${projectName} --template ${template} --no-
|
|
50
|
+
createProjectCommand: (projectName, template) => `pnpm create vite@latest ${projectName} --template ${template} --no-interactive`,
|
|
51
51
|
addDepsCommand: (deps) => `pnpm add ${deps.join(" ")}`,
|
|
52
52
|
addDevDepsCommand: (deps) => `pnpm add -D ${deps.join(" ")}`,
|
|
53
53
|
installCommand: "pnpm install"
|
|
@@ -55,7 +55,7 @@ function detectPackageManager() {
|
|
|
55
55
|
case "bun":
|
|
56
56
|
return {
|
|
57
57
|
name: "bun",
|
|
58
|
-
createProjectCommand: (projectName, template) => `bun create vite ${projectName} --template=${template} --no-
|
|
58
|
+
createProjectCommand: (projectName, template) => `bun create vite ${projectName} --template=${template} --no-interactive`,
|
|
59
59
|
addDepsCommand: (deps) => `bun add ${deps.join(" ")}`,
|
|
60
60
|
addDevDepsCommand: (deps) => `bun add -d ${deps.join(" ")}`,
|
|
61
61
|
installCommand: "bun install"
|
|
@@ -63,7 +63,7 @@ function detectPackageManager() {
|
|
|
63
63
|
case "yarn":
|
|
64
64
|
return {
|
|
65
65
|
name: "yarn",
|
|
66
|
-
createProjectCommand: (projectName, template) => `yarn create vite ${projectName} --template=${template} --no-
|
|
66
|
+
createProjectCommand: (projectName, template) => `yarn create vite ${projectName} --template=${template} --no-interactive`,
|
|
67
67
|
addDepsCommand: (deps) => `yarn add ${deps.join(" ")}`,
|
|
68
68
|
addDevDepsCommand: (deps) => `yarn add -D ${deps.join(" ")}`,
|
|
69
69
|
installCommand: "yarn install"
|
|
@@ -72,7 +72,7 @@ function detectPackageManager() {
|
|
|
72
72
|
default:
|
|
73
73
|
return {
|
|
74
74
|
name: "npm",
|
|
75
|
-
createProjectCommand: (projectName, template) => `npm create vite@latest ${projectName} -- --template ${template} --no-
|
|
75
|
+
createProjectCommand: (projectName, template) => `npm create vite@latest ${projectName} -- --template ${template} --no-interactive`,
|
|
76
76
|
addDepsCommand: (deps) => `npm install ${deps.join(" ")}`,
|
|
77
77
|
addDevDepsCommand: (deps) => `npm install -D ${deps.join(" ")}`,
|
|
78
78
|
installCommand: "npm install"
|
|
@@ -126,10 +126,17 @@ const logger = {
|
|
|
126
126
|
}
|
|
127
127
|
};
|
|
128
128
|
function getViteConfigPath(projectDir) {
|
|
129
|
-
const
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
129
|
+
for (const fileName of [
|
|
130
|
+
"vite.config.ts",
|
|
131
|
+
"vite.config.mts",
|
|
132
|
+
"vite.config.cts",
|
|
133
|
+
"vite.config.js",
|
|
134
|
+
"vite.config.mjs",
|
|
135
|
+
"vite.config.cjs"
|
|
136
|
+
]) {
|
|
137
|
+
const configPath = path.join(projectDir, fileName);
|
|
138
|
+
if (fs.existsSync(configPath)) return configPath;
|
|
139
|
+
}
|
|
133
140
|
return null;
|
|
134
141
|
}
|
|
135
142
|
function readViteConfig(projectDir) {
|
|
@@ -211,10 +218,19 @@ function createVirtualDTS(projectDir, useSrc) {
|
|
|
211
218
|
|
|
212
219
|
export const generateRoutes: () => RouteObject[];
|
|
213
220
|
export function Router(): ReactElement | null;
|
|
221
|
+
export function useParams<T extends Record<string, string | undefined> = Record<string, string | undefined>>(): T;
|
|
214
222
|
export { Link, useRoutes } from 'react-router-dom';
|
|
215
223
|
}
|
|
216
224
|
`;
|
|
217
225
|
fs.writeFileSync(filePath, content, "utf-8");
|
|
226
|
+
const gitignorePath = path.join(projectDir, ".gitignore");
|
|
227
|
+
const entry = useSrc ? "src/virtual-next-vite-router.d.ts" : "virtual-next-vite-router.d.ts";
|
|
228
|
+
const currentGitignore = fs.existsSync(gitignorePath) ? fs.readFileSync(gitignorePath, "utf-8") : "";
|
|
229
|
+
if (!currentGitignore.split(/\r?\n/).includes(entry)) {
|
|
230
|
+
const prefix = currentGitignore && !currentGitignore.endsWith("\n") ? "\n" : "";
|
|
231
|
+
fs.writeFileSync(gitignorePath, `${currentGitignore}${prefix}${entry}
|
|
232
|
+
`, "utf-8");
|
|
233
|
+
}
|
|
218
234
|
}
|
|
219
235
|
function createMainTSX(projectDir, useSrc) {
|
|
220
236
|
const targetDir = useSrc ? path.join(projectDir, "src") : projectDir;
|
|
@@ -225,19 +241,12 @@ function createMainTSX(projectDir, useSrc) {
|
|
|
225
241
|
const content = `import { StrictMode } from 'react';
|
|
226
242
|
import { createRoot } from 'react-dom/client';
|
|
227
243
|
import { BrowserRouter } from "react-router-dom";
|
|
228
|
-
import {
|
|
229
|
-
|
|
230
|
-
const routes = generateRoutes();
|
|
231
|
-
|
|
232
|
-
export default function App() {
|
|
233
|
-
const element = useRoutes(routes);
|
|
234
|
-
return element;
|
|
235
|
-
}
|
|
244
|
+
import { Router } from 'virtual:next-vite-router';
|
|
236
245
|
|
|
237
246
|
createRoot(document.getElementById('root')!).render(
|
|
238
247
|
<StrictMode>
|
|
239
248
|
<BrowserRouter>
|
|
240
|
-
<
|
|
249
|
+
<Router />
|
|
241
250
|
</BrowserRouter>
|
|
242
251
|
</StrictMode>,
|
|
243
252
|
);
|
|
@@ -463,12 +472,11 @@ const init = new commander.Command().name("init").description(
|
|
|
463
472
|
name: "template",
|
|
464
473
|
message: "Select a template:",
|
|
465
474
|
choices: [
|
|
466
|
-
{ title: "React + TypeScript", value: "react-ts" },
|
|
475
|
+
{ title: "React + TypeScript (Recommended)", value: "react-ts" },
|
|
467
476
|
{
|
|
468
477
|
title: "React + TypeScript (React Compiler)",
|
|
469
478
|
value: "react-compiler-ts"
|
|
470
|
-
}
|
|
471
|
-
{ title: "React + SWC (Recommended)", value: "react-swc-ts" }
|
|
479
|
+
}
|
|
472
480
|
],
|
|
473
481
|
initial: 0
|
|
474
482
|
},
|
|
@@ -512,13 +520,10 @@ const init = new commander.Command().name("init").description(
|
|
|
512
520
|
const useTailwind = tailwindResponse.useTailwind;
|
|
513
521
|
const createCommand = pm.createProjectCommand(projectName, variant);
|
|
514
522
|
logger.info(`Creating project "${projectName}" using ${pm.name}...`);
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
});
|
|
520
|
-
} catch (error) {
|
|
521
|
-
}
|
|
523
|
+
child_process.execSync(createCommand, {
|
|
524
|
+
stdio: ["pipe", "inherit", "inherit"],
|
|
525
|
+
input: "n\n"
|
|
526
|
+
});
|
|
522
527
|
logger.info("Installing dependencies...");
|
|
523
528
|
child_process.execSync(pm.installCommand, { stdio: "inherit", cwd: projectName });
|
|
524
529
|
logger.info(
|
|
@@ -539,7 +544,7 @@ const init = new commander.Command().name("init").description(
|
|
|
539
544
|
Project "${projectName}" is ready!
|
|
540
545
|
`);
|
|
541
546
|
});
|
|
542
|
-
const version = "1.
|
|
547
|
+
const version = "1.2.0";
|
|
543
548
|
const pkg = {
|
|
544
549
|
version
|
|
545
550
|
};
|
package/dist/index.d.ts
CHANGED
|
@@ -1,9 +1,14 @@
|
|
|
1
|
+
import { ComponentType } from 'react';
|
|
1
2
|
import { default as default_2 } from 'react';
|
|
2
|
-
import { Plugin as Plugin_2 } from 'vite';
|
|
3
3
|
import { ReactElement } from 'react';
|
|
4
4
|
import { RouteObject } from 'react-router-dom';
|
|
5
5
|
|
|
6
|
-
export declare function buildRouteTree(pages: Record<string, () => Promise<any>>, layouts: Record<string, any>, notFounds: Record<string, () => Promise<any
|
|
6
|
+
export declare function buildRouteTree(pages: Record<string, () => Promise<any>>, layouts: Record<string, any>, notFounds: Record<string, () => Promise<any>>, fileOptions?: RouteFileOptions): RouteNode;
|
|
7
|
+
|
|
8
|
+
export declare function CatchAllParamProvider({ name, children, }: {
|
|
9
|
+
name: string;
|
|
10
|
+
children: default_2.ReactElement;
|
|
11
|
+
}): default_2.ReactElement;
|
|
7
12
|
|
|
8
13
|
export declare function clearMiddlewares(): void;
|
|
9
14
|
|
|
@@ -34,23 +39,14 @@ export declare function createLazyElement(loader: () => Promise<any>, cacheKey:
|
|
|
34
39
|
* // Then use it
|
|
35
40
|
* const routes = generateCustomRoutes();
|
|
36
41
|
*/
|
|
37
|
-
export declare function createRouteGenerator(pages: Record<string, () => Promise<any>>, layouts: Record<string, any>, notFounds: Record<string, () => Promise<any
|
|
42
|
+
export declare function createRouteGenerator(pages: Record<string, () => Promise<any>>, layouts: Record<string, any>, notFounds: Record<string, () => Promise<any>>, fileOptions?: RouteFileOptions): () => RouteObject[];
|
|
38
43
|
|
|
39
44
|
/**
|
|
40
45
|
* Extract the route path from a file path
|
|
41
46
|
* @example "../../app/blog/[id]/page.tsx" -> "blog/[id]"
|
|
42
47
|
* @example "../../app/page.tsx" -> ""
|
|
43
48
|
*/
|
|
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
|
-
};
|
|
49
|
+
export declare function extractRoutePath(filePath: string, { pagesDir, pageFile, layoutFile, notFoundFile }?: RouteFileOptions): string;
|
|
54
50
|
|
|
55
51
|
/**
|
|
56
52
|
* Normalize a Next.js segment to a React Router segment
|
|
@@ -62,14 +58,25 @@ export declare function normalizeSegment(segment: string): string;
|
|
|
62
58
|
|
|
63
59
|
export declare function registerMiddleware(pattern: RegExp, middleware: RouteMiddleware): void;
|
|
64
60
|
|
|
61
|
+
export declare type RouteFileOptions = {
|
|
62
|
+
pagesDir?: string;
|
|
63
|
+
pageFile?: string;
|
|
64
|
+
layoutFile?: string;
|
|
65
|
+
notFoundFile?: string;
|
|
66
|
+
};
|
|
67
|
+
|
|
65
68
|
export declare type RouteMiddleware = (element: ReactElement) => ReactElement;
|
|
66
69
|
|
|
70
|
+
export declare type RouteModuleLoader = () => Promise<{
|
|
71
|
+
default: ComponentType;
|
|
72
|
+
}>;
|
|
73
|
+
|
|
67
74
|
export declare type RouteNode = {
|
|
68
75
|
segment: string;
|
|
69
76
|
fullPath: string;
|
|
70
|
-
page?:
|
|
71
|
-
layout?:
|
|
72
|
-
notFound?:
|
|
77
|
+
page?: RouteModuleLoader;
|
|
78
|
+
layout?: ComponentType;
|
|
79
|
+
notFound?: RouteModuleLoader;
|
|
73
80
|
children: Map<string, RouteNode>;
|
|
74
81
|
};
|
|
75
82
|
|
|
@@ -81,4 +88,6 @@ export declare type RouterConfig = {
|
|
|
81
88
|
|
|
82
89
|
export declare function treeToRoutes(node: RouteNode, isRoot?: boolean, currentPath?: string): RouteObject[];
|
|
83
90
|
|
|
91
|
+
export declare function useParams<T extends Record<string, string | undefined> = Record<string, string | undefined>>(): T;
|
|
92
|
+
|
|
84
93
|
export { }
|
package/dist/index.js
CHANGED
|
@@ -1,156 +1,196 @@
|
|
|
1
|
-
import { e as
|
|
2
|
-
import {
|
|
3
|
-
import
|
|
4
|
-
const
|
|
1
|
+
import { e as z, n as p } from "./path-BodMUTCM.js";
|
|
2
|
+
import i, { Suspense as E, lazy as L, createContext as M, useContext as x } from "react";
|
|
3
|
+
import { useParams as k } from "react-router-dom";
|
|
4
|
+
const A = {
|
|
5
5
|
enableLazyLoading: !0
|
|
6
6
|
};
|
|
7
|
-
let
|
|
8
|
-
function
|
|
9
|
-
|
|
7
|
+
let m = { ...A };
|
|
8
|
+
function B(e) {
|
|
9
|
+
m = { ...m, ...e };
|
|
10
10
|
}
|
|
11
|
-
function
|
|
12
|
-
return
|
|
11
|
+
function S() {
|
|
12
|
+
return m;
|
|
13
13
|
}
|
|
14
|
-
let
|
|
15
|
-
function
|
|
16
|
-
|
|
14
|
+
let g = [];
|
|
15
|
+
function H(e, t) {
|
|
16
|
+
g.push({ pattern: e, middleware: t });
|
|
17
17
|
}
|
|
18
|
-
function
|
|
19
|
-
|
|
18
|
+
function I() {
|
|
19
|
+
g = [];
|
|
20
20
|
}
|
|
21
|
-
function
|
|
22
|
-
let n =
|
|
23
|
-
for (const
|
|
24
|
-
|
|
21
|
+
function d(e, t) {
|
|
22
|
+
let n = t;
|
|
23
|
+
for (const r of g)
|
|
24
|
+
r.pattern.test(e) && (n = r.middleware(n));
|
|
25
25
|
return n;
|
|
26
26
|
}
|
|
27
|
-
const
|
|
28
|
-
function
|
|
29
|
-
const
|
|
30
|
-
if (
|
|
31
|
-
const
|
|
32
|
-
|
|
27
|
+
const T = () => i.createElement("div"), C = /* @__PURE__ */ new Map();
|
|
28
|
+
function w(e, t, n) {
|
|
29
|
+
const r = S();
|
|
30
|
+
if (r.enableLazyLoading === !1) {
|
|
31
|
+
const u = i.lazy(e), s = i.createElement(
|
|
32
|
+
E,
|
|
33
33
|
{ fallback: null },
|
|
34
34
|
// No loading fallback when disabled
|
|
35
|
-
i.createElement(
|
|
35
|
+
i.createElement(u)
|
|
36
36
|
);
|
|
37
|
-
return n ?
|
|
37
|
+
return n ? d(n, s) : s;
|
|
38
38
|
}
|
|
39
|
-
let
|
|
40
|
-
|
|
41
|
-
const o =
|
|
42
|
-
|
|
39
|
+
let a = C.get(t);
|
|
40
|
+
a || (a = L(e), C.set(t, a));
|
|
41
|
+
const o = r.loadingFallback || T, l = i.createElement(
|
|
42
|
+
E,
|
|
43
43
|
{ fallback: i.createElement(o) },
|
|
44
|
-
i.createElement(
|
|
44
|
+
i.createElement(a)
|
|
45
45
|
);
|
|
46
|
-
return n ?
|
|
47
|
-
}
|
|
48
|
-
function
|
|
49
|
-
const
|
|
50
|
-
let
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
segment:
|
|
54
|
-
fullPath:
|
|
46
|
+
return n ? d(n, l) : l;
|
|
47
|
+
}
|
|
48
|
+
function h(e, t, n, r, a) {
|
|
49
|
+
const o = z(t, a), l = o ? o.split("/") : [];
|
|
50
|
+
let u = e, s = "";
|
|
51
|
+
l.forEach((c, v) => {
|
|
52
|
+
s = s ? `${s}/${c}` : c, u.children.has(c) || u.children.set(c, {
|
|
53
|
+
segment: c,
|
|
54
|
+
fullPath: s,
|
|
55
55
|
children: /* @__PURE__ */ new Map()
|
|
56
|
-
}),
|
|
57
|
-
}),
|
|
56
|
+
}), u = u.children.get(c), v === l.length - 1 && (u[r] = n);
|
|
57
|
+
}), l.length === 0 && (e[r] = n);
|
|
58
58
|
}
|
|
59
|
-
function
|
|
60
|
-
const
|
|
59
|
+
function j(e, t, n, r) {
|
|
60
|
+
const a = {
|
|
61
61
|
segment: "",
|
|
62
62
|
fullPath: "",
|
|
63
63
|
children: /* @__PURE__ */ new Map()
|
|
64
64
|
};
|
|
65
|
-
return Object.entries(
|
|
66
|
-
|
|
67
|
-
}), Object.entries(e).forEach(([
|
|
68
|
-
|
|
69
|
-
}), Object.entries(n).forEach(([
|
|
70
|
-
|
|
71
|
-
}),
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
65
|
+
return Object.entries(t).forEach(([o, l]) => {
|
|
66
|
+
h(a, o, l.default, "layout", r);
|
|
67
|
+
}), Object.entries(e).forEach(([o, l]) => {
|
|
68
|
+
h(a, o, l, "page", r);
|
|
69
|
+
}), Object.entries(n).forEach(([o, l]) => {
|
|
70
|
+
h(a, o, l, "notFound", r);
|
|
71
|
+
}), a;
|
|
72
|
+
}
|
|
73
|
+
const F = M(void 0);
|
|
74
|
+
function N({
|
|
75
|
+
name: e,
|
|
76
|
+
children: t
|
|
77
|
+
}) {
|
|
78
|
+
return i.createElement(
|
|
79
|
+
F.Provider,
|
|
80
|
+
{ value: e },
|
|
81
|
+
t
|
|
78
82
|
);
|
|
79
|
-
return n ? { index: !0, element: t } : { path: f(e.segment), element: t };
|
|
80
83
|
}
|
|
81
|
-
function
|
|
84
|
+
function D() {
|
|
85
|
+
return x(F);
|
|
86
|
+
}
|
|
87
|
+
function P(e, t) {
|
|
88
|
+
return d(e, i.createElement(t));
|
|
89
|
+
}
|
|
90
|
+
function f(e, t, n = !1) {
|
|
91
|
+
const r = e.page;
|
|
92
|
+
if (!r)
|
|
93
|
+
throw new Error(`Route node "${e.fullPath}" has no page loader`);
|
|
94
|
+
const a = w(
|
|
95
|
+
async () => ({ default: (await r()).default }),
|
|
96
|
+
`page:${e.fullPath || t}`,
|
|
97
|
+
t
|
|
98
|
+
), o = e.segment.match(/^\[\[?\.\.\.(.+?)\]\]?$/), l = o ? i.createElement(N, {
|
|
99
|
+
name: o[1],
|
|
100
|
+
children: a
|
|
101
|
+
}) : a;
|
|
102
|
+
return n ? { index: !0, element: l } : { path: p(e.segment), element: l };
|
|
103
|
+
}
|
|
104
|
+
function R(e) {
|
|
105
|
+
const t = e.notFound;
|
|
106
|
+
if (!t)
|
|
107
|
+
throw new Error(`Route node "${e.fullPath}" has no not-found loader`);
|
|
108
|
+
const n = e.fullPath ? `/${e.fullPath}` : "/";
|
|
82
109
|
return {
|
|
83
110
|
path: "*",
|
|
84
|
-
element:
|
|
85
|
-
async () => ({ default: (await
|
|
86
|
-
`notfound:${e.fullPath}
|
|
111
|
+
element: w(
|
|
112
|
+
async () => ({ default: (await t()).default }),
|
|
113
|
+
`notfound:${e.fullPath}`,
|
|
114
|
+
n
|
|
87
115
|
)
|
|
88
116
|
};
|
|
89
117
|
}
|
|
90
|
-
function
|
|
118
|
+
function $(e, t) {
|
|
91
119
|
const n = [];
|
|
92
|
-
return [...e.children.entries()].sort(([
|
|
93
|
-
const o =
|
|
94
|
-
n.push(...
|
|
120
|
+
return [...e.children.entries()].sort(([r], [a]) => r.localeCompare(a)).forEach(([r, a]) => {
|
|
121
|
+
const o = p(r), l = o ? t ? `${t}/${o}` : `/${o}` : t;
|
|
122
|
+
n.push(...b(a, !1, l));
|
|
95
123
|
}), n;
|
|
96
124
|
}
|
|
97
|
-
function
|
|
98
|
-
const
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
125
|
+
function y(e, t) {
|
|
126
|
+
const n = [];
|
|
127
|
+
return e.page && n.push(f(e, t || "/", !0)), n.push(...$(e, t)), e.notFound && n.push(R(e)), n;
|
|
128
|
+
}
|
|
129
|
+
function b(e, t = !1, n = "") {
|
|
130
|
+
const r = [];
|
|
131
|
+
if (t) {
|
|
132
|
+
const c = y(e, "");
|
|
133
|
+
return e.layout ? (r.push({
|
|
134
|
+
path: "/",
|
|
135
|
+
element: P("/", e.layout),
|
|
136
|
+
children: c
|
|
137
|
+
}), r) : e.page ? (r.push({
|
|
138
|
+
path: "/",
|
|
139
|
+
element: f(e, "/", !1).element,
|
|
140
|
+
children: c.slice(1).length > 0 ? c.slice(1) : void 0
|
|
141
|
+
}), r) : e.notFound ? (r.push({
|
|
102
142
|
path: "/",
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
}), t;
|
|
143
|
+
children: c
|
|
144
|
+
}), r) : c;
|
|
106
145
|
}
|
|
146
|
+
const a = p(e.segment), o = !a, l = o ? n : n + "/" + a, u = $(e, l), s = e.notFound ? [R(e)] : [];
|
|
107
147
|
if (e.layout) {
|
|
108
|
-
const
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
element: i.createElement(e.layout),
|
|
115
|
-
children: u.length > 0 ? u : void 0
|
|
116
|
-
}), t;
|
|
148
|
+
const c = y(e, l);
|
|
149
|
+
return [{
|
|
150
|
+
...o ? {} : { path: a },
|
|
151
|
+
element: P(l, e.layout),
|
|
152
|
+
children: c.length > 0 ? c : void 0
|
|
153
|
+
}];
|
|
117
154
|
}
|
|
118
|
-
if (e.page)
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
155
|
+
if (e.page && !o)
|
|
156
|
+
return [{
|
|
157
|
+
path: a,
|
|
158
|
+
element: f(e, l).element,
|
|
159
|
+
children: [...u, ...s].length > 0 ? [...u, ...s] : void 0
|
|
160
|
+
}];
|
|
161
|
+
if (e.page || e.notFound || !o) {
|
|
162
|
+
const c = [
|
|
163
|
+
...e.page ? [f(e, l, !0)] : [],
|
|
164
|
+
...u,
|
|
165
|
+
...s
|
|
166
|
+
];
|
|
167
|
+
return [{
|
|
168
|
+
...o ? {} : { path: a },
|
|
169
|
+
children: c.length > 0 ? c : void 0
|
|
170
|
+
}];
|
|
132
171
|
}
|
|
133
|
-
|
|
134
|
-
return l ? [{
|
|
135
|
-
path: l,
|
|
136
|
-
children: o.length > 0 ? o : void 0
|
|
137
|
-
}] : o;
|
|
172
|
+
return u;
|
|
138
173
|
}
|
|
139
|
-
function
|
|
174
|
+
function J(e, t, n, r) {
|
|
140
175
|
return () => {
|
|
141
|
-
const
|
|
142
|
-
return
|
|
176
|
+
const a = j(e, t, n, r);
|
|
177
|
+
return b(a, !0);
|
|
143
178
|
};
|
|
144
179
|
}
|
|
180
|
+
function Q() {
|
|
181
|
+
const e = k(), t = D();
|
|
182
|
+
return typeof t == "string" && e["*"] !== void 0 ? { ...e, [t]: e["*"] } : e;
|
|
183
|
+
}
|
|
145
184
|
export {
|
|
146
|
-
|
|
147
|
-
j as
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
185
|
+
N as CatchAllParamProvider,
|
|
186
|
+
j as buildRouteTree,
|
|
187
|
+
I as clearMiddlewares,
|
|
188
|
+
B as configureRouter,
|
|
189
|
+
w as createLazyElement,
|
|
190
|
+
J as createRouteGenerator,
|
|
191
|
+
z as extractRoutePath,
|
|
192
|
+
p as normalizeSegment,
|
|
193
|
+
H as registerMiddleware,
|
|
194
|
+
b as treeToRoutes,
|
|
195
|
+
Q as useParams
|
|
156
196
|
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
function $(e) {
|
|
2
|
+
return /^\([^)]+\)$/.test(e) ? "" : /^\[\[\.\.\.(.+)\]\]$/.test(e) || /^\[\.\.\.(.+)\]$/.test(e) ? "*" : /^\[([^\]]+)\]$/.test(e) ? e.replace(/^\[([^\]]+)\]$/, ":$1") : e;
|
|
3
|
+
}
|
|
4
|
+
function u(e, { pagesDir: t, pageFile: a = "page.tsx", layoutFile: n = "layout.tsx", notFoundFile: c = "not-found.tsx" } = {}) {
|
|
5
|
+
const o = e.replace(/\\/g, "/"), r = t == null ? void 0 : t.replace(/\\/g, "/").replace(/^\/|\/$/g, ""), l = [a, n, c].map((p) => p.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")).join("|");
|
|
6
|
+
return o.replace(
|
|
7
|
+
r ? new RegExp(`^.*(?:^|/)${r}/`) : /^.*(?:^|\/)(?:app|pages)\//,
|
|
8
|
+
""
|
|
9
|
+
).replace(/\\/g, "/").replace(new RegExp(`/?(?:${l})$`), "");
|
|
10
|
+
}
|
|
11
|
+
export {
|
|
12
|
+
u as e,
|
|
13
|
+
$ as n
|
|
14
|
+
};
|
package/dist/plugin.js
CHANGED
|
@@ -1,6 +1,128 @@
|
|
|
1
|
-
import "node:fs";
|
|
2
|
-
import "node:path";
|
|
3
|
-
import {
|
|
1
|
+
import m from "node:fs";
|
|
2
|
+
import i from "node:path";
|
|
3
|
+
import { n as g } from "./path-BodMUTCM.js";
|
|
4
|
+
function h(o) {
|
|
5
|
+
const e = o.split(i.sep).filter(Boolean).map(g).filter(Boolean);
|
|
6
|
+
return e.length > 0 ? `/${e.join("/")}` : "/";
|
|
7
|
+
}
|
|
8
|
+
function x(o, e) {
|
|
9
|
+
const s = /* @__PURE__ */ new Set();
|
|
10
|
+
function r(n) {
|
|
11
|
+
for (const u of m.readdirSync(n, { withFileTypes: !0 })) {
|
|
12
|
+
const a = i.join(n, u.name);
|
|
13
|
+
u.isDirectory() ? r(a) : u.isFile() && u.name === e && s.add(h(i.relative(o, n)));
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
return m.existsSync(o) && r(o), [...s].sort();
|
|
17
|
+
}
|
|
18
|
+
function v(o) {
|
|
19
|
+
const e = o.match(/^\/(?:\[\.\.\.|:)([^/\]]+)\]?$/);
|
|
20
|
+
return e == null ? void 0 : e[1];
|
|
21
|
+
}
|
|
22
|
+
function P(o) {
|
|
23
|
+
const e = o.map((r) => ` | "${r}"`).join(`
|
|
24
|
+
`), s = o.map((r) => {
|
|
25
|
+
const n = r.split("/").map((a) => v(`/${a}`)).filter((a) => !!a), u = n.length > 0 ? n.map((a) => ` ${a}: string;`).join(`
|
|
26
|
+
`) : " [key: string]: never;";
|
|
27
|
+
return ` "${r}": {
|
|
28
|
+
${u}
|
|
29
|
+
};`;
|
|
30
|
+
}).join(`
|
|
31
|
+
`);
|
|
32
|
+
return `declare module 'virtual:next-vite-router' {
|
|
33
|
+
import type { ReactElement } from 'react';
|
|
34
|
+
import type { RouteObject } from 'react-router-dom';
|
|
35
|
+
|
|
36
|
+
export type RoutePath =
|
|
37
|
+
${e || ' | "/"'};
|
|
38
|
+
|
|
39
|
+
export type RouteParams<P extends RoutePath> = P extends keyof RoutePathParams
|
|
40
|
+
? RoutePathParams[P]
|
|
41
|
+
: never;
|
|
42
|
+
|
|
43
|
+
export interface RoutePathParams {
|
|
44
|
+
${s}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export const generateRoutes: () => RouteObject[];
|
|
48
|
+
export function Router(): ReactElement | null;
|
|
49
|
+
export function useParams<T extends Record<string, string | undefined> = Record<string, string | undefined>>(): T;
|
|
50
|
+
export { Link, useRoutes } from 'react-router-dom';
|
|
51
|
+
}
|
|
52
|
+
`;
|
|
53
|
+
}
|
|
54
|
+
function k(o = {}) {
|
|
55
|
+
const {
|
|
56
|
+
pagesDir: e = "src/app",
|
|
57
|
+
pageFile: s = "page.tsx",
|
|
58
|
+
layoutFile: r = "layout.tsx",
|
|
59
|
+
notFoundFile: n = "not-found.tsx"
|
|
60
|
+
} = o, u = { pagesDir: e, pageFile: s, layoutFile: r, notFoundFile: n }, a = "virtual:next-vite-router", c = "\0" + a;
|
|
61
|
+
let l = "", p = "";
|
|
62
|
+
function d() {
|
|
63
|
+
const t = P(x(l, s));
|
|
64
|
+
m.writeFileSync(p, t, "utf-8");
|
|
65
|
+
}
|
|
66
|
+
return {
|
|
67
|
+
name: "next-vite-router",
|
|
68
|
+
configResolved(t) {
|
|
69
|
+
l = i.resolve(t.root, e), p = i.join(i.dirname(l), "virtual-next-vite-router.d.ts"), d();
|
|
70
|
+
},
|
|
71
|
+
configureServer(t) {
|
|
72
|
+
const f = (y) => {
|
|
73
|
+
if (i.relative(l, y).startsWith("..") || ![s, r, n].includes(i.basename(y)))
|
|
74
|
+
return;
|
|
75
|
+
d();
|
|
76
|
+
const R = t.moduleGraph.getModuleById(c);
|
|
77
|
+
R && (t.moduleGraph.invalidateModule(R), t.ws.send({ type: "full-reload", path: "*" }));
|
|
78
|
+
};
|
|
79
|
+
t.watcher.on("add", f), t.watcher.on("unlink", f);
|
|
80
|
+
},
|
|
81
|
+
resolveId(t) {
|
|
82
|
+
if (t === a)
|
|
83
|
+
return c;
|
|
84
|
+
},
|
|
85
|
+
load(t) {
|
|
86
|
+
if (t === c)
|
|
87
|
+
return `
|
|
88
|
+
import { buildRouteTree, treeToRoutes, normalizeSegment, createLazyElement, useParams } from 'next-vite-router';
|
|
89
|
+
import { Link, useRoutes } from 'react-router-dom';
|
|
90
|
+
|
|
91
|
+
const pagesGlob = import.meta.glob('/${e}/**/${s}');
|
|
92
|
+
const layoutsGlob = import.meta.glob('/${e}/**/${r}', { eager: true });
|
|
93
|
+
const notFoundsGlob = import.meta.glob('/${e}/**/${n}');
|
|
94
|
+
|
|
95
|
+
const transformPath = (path) => path.replace('/${e}/', '');
|
|
96
|
+
|
|
97
|
+
const pages = Object.fromEntries(
|
|
98
|
+
Object.entries(pagesGlob).map(([key, value]) => [transformPath(key), value])
|
|
99
|
+
);
|
|
100
|
+
const layouts = Object.fromEntries(
|
|
101
|
+
Object.entries(layoutsGlob).map(([key, value]) => [transformPath(key), value])
|
|
102
|
+
);
|
|
103
|
+
const notFounds = Object.fromEntries(
|
|
104
|
+
Object.entries(notFoundsGlob).map(([key, value]) => [transformPath(key), value])
|
|
105
|
+
);
|
|
106
|
+
|
|
107
|
+
export function generateRoutes() {
|
|
108
|
+
const tree = buildRouteTree(pages, layouts, notFounds, ${JSON.stringify(u)});
|
|
109
|
+
const routes = treeToRoutes(tree, true);
|
|
110
|
+
return routes;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
export function Router() {
|
|
114
|
+
routes ??= generateRoutes();
|
|
115
|
+
return useRoutes(routes);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
let routes;
|
|
119
|
+
|
|
120
|
+
export { Link, useRoutes };
|
|
121
|
+
export { useParams };
|
|
122
|
+
`;
|
|
123
|
+
}
|
|
124
|
+
};
|
|
125
|
+
}
|
|
4
126
|
export {
|
|
5
|
-
|
|
127
|
+
k as nextViteRouter
|
|
6
128
|
};
|
package/package.json
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "next-vite-router",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.0",
|
|
4
4
|
"description": "Next.js-like file-based routing for React + Vite",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
7
7
|
"types": "./dist/index.d.ts",
|
|
8
|
+
"sideEffects": false,
|
|
8
9
|
"bin": {
|
|
9
10
|
"create-next-vite-router": "./dist/cli.cjs"
|
|
10
11
|
},
|
|
@@ -65,6 +66,7 @@
|
|
|
65
66
|
"test:local": "node test/test-package.js",
|
|
66
67
|
"test:routes": "node test/test-route-types.js",
|
|
67
68
|
"test:generator": "node --test test/routes.test.js",
|
|
69
|
+
"test:params": "node --test test/params.test.js",
|
|
68
70
|
"test:compatibility": "node test/test-compatibility.js",
|
|
69
71
|
"preview": "pnpm pack --dry-run",
|
|
70
72
|
"cli": "cd test && node ../dist/cli.cjs"
|
|
@@ -1,132 +0,0 @@
|
|
|
1
|
-
import p from "node:fs";
|
|
2
|
-
import i from "node:path";
|
|
3
|
-
function y(e) {
|
|
4
|
-
return /^\([^)]+\)$/.test(e) ? "" : /^\[\[\.\.\.(.+)\]\]$/.test(e) || /^\[\.\.\.(.+)\]$/.test(e) ? "*" : /^\[([^\]]+)\]$/.test(e) ? e.replace(/^\[([^\]]+)\]$/, ":$1") : e;
|
|
5
|
-
}
|
|
6
|
-
function b(e) {
|
|
7
|
-
return e.replace(/\\/g, "/").replace("../../app/", "").replace(/\/?(page|layout|not-found)\.tsx$/, "");
|
|
8
|
-
}
|
|
9
|
-
function R(e) {
|
|
10
|
-
const t = e.split(i.sep).filter(Boolean).map(y).filter(Boolean);
|
|
11
|
-
return t.length > 0 ? `/${t.join("/")}` : "/";
|
|
12
|
-
}
|
|
13
|
-
function h(e, t) {
|
|
14
|
-
const s = /* @__PURE__ */ new Set();
|
|
15
|
-
function n(a) {
|
|
16
|
-
for (const u of p.readdirSync(a, { withFileTypes: !0 })) {
|
|
17
|
-
const r = i.join(a, u.name);
|
|
18
|
-
u.isDirectory() ? n(r) : u.isFile() && u.name === t && s.add(R(i.relative(e, a)));
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
return p.existsSync(e) && n(e), [...s].sort();
|
|
22
|
-
}
|
|
23
|
-
function x(e) {
|
|
24
|
-
const t = e.match(/^\/(?:\[\.\.\.|:)([^/\]]+)\]?$/);
|
|
25
|
-
return t == null ? void 0 : t[1];
|
|
26
|
-
}
|
|
27
|
-
function $(e) {
|
|
28
|
-
const t = e.map((n) => ` | "${n}"`).join(`
|
|
29
|
-
`), s = e.map((n) => {
|
|
30
|
-
const a = n.split("/").map((r) => x(`/${r}`)).filter((r) => !!r), u = a.length > 0 ? a.map((r) => ` ${r}: string;`).join(`
|
|
31
|
-
`) : " [key: string]: never;";
|
|
32
|
-
return ` "${n}": {
|
|
33
|
-
${u}
|
|
34
|
-
};`;
|
|
35
|
-
}).join(`
|
|
36
|
-
`);
|
|
37
|
-
return `declare module 'virtual:next-vite-router' {
|
|
38
|
-
import type { ReactElement } from 'react';
|
|
39
|
-
import type { RouteObject } from 'react-router-dom';
|
|
40
|
-
|
|
41
|
-
export type RoutePath =
|
|
42
|
-
${t || ' | "/"'};
|
|
43
|
-
|
|
44
|
-
export type RouteParams<P extends RoutePath> = P extends keyof RoutePathParams
|
|
45
|
-
? RoutePathParams[P]
|
|
46
|
-
: never;
|
|
47
|
-
|
|
48
|
-
export interface RoutePathParams {
|
|
49
|
-
${s}
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
export const generateRoutes: () => RouteObject[];
|
|
53
|
-
export function Router(): ReactElement | null;
|
|
54
|
-
export { Link, useRoutes } from 'react-router-dom';
|
|
55
|
-
}
|
|
56
|
-
`;
|
|
57
|
-
}
|
|
58
|
-
function g(e = {}) {
|
|
59
|
-
const {
|
|
60
|
-
pagesDir: t = "src/app",
|
|
61
|
-
pageFile: s = "page.tsx",
|
|
62
|
-
layoutFile: n = "layout.tsx",
|
|
63
|
-
notFoundFile: a = "not-found.tsx"
|
|
64
|
-
} = e, u = "virtual:next-vite-router", r = "\0" + u;
|
|
65
|
-
let l = "", m = "";
|
|
66
|
-
function f() {
|
|
67
|
-
const o = $(h(l, s));
|
|
68
|
-
p.writeFileSync(m, o, "utf-8");
|
|
69
|
-
}
|
|
70
|
-
return {
|
|
71
|
-
name: "next-vite-router",
|
|
72
|
-
configResolved(o) {
|
|
73
|
-
l = i.resolve(o.root, t), m = i.join(i.dirname(l), "virtual-next-vite-router.d.ts"), f();
|
|
74
|
-
},
|
|
75
|
-
resolveId(o) {
|
|
76
|
-
if (o === u)
|
|
77
|
-
return r;
|
|
78
|
-
},
|
|
79
|
-
load(o) {
|
|
80
|
-
if (o === r)
|
|
81
|
-
return `
|
|
82
|
-
import { buildRouteTree, treeToRoutes, normalizeSegment, createLazyElement } from 'next-vite-router';
|
|
83
|
-
import { Link, useRoutes } from 'react-router-dom';
|
|
84
|
-
|
|
85
|
-
const pagesGlob = import.meta.glob('/${t}/**/${s}');
|
|
86
|
-
const layoutsGlob = import.meta.glob('/${t}/**/${n}', { eager: true });
|
|
87
|
-
const notFoundsGlob = import.meta.glob('/${t}/**/${a}');
|
|
88
|
-
|
|
89
|
-
const transformPath = (path) => path.replace('/${t}/', '');
|
|
90
|
-
|
|
91
|
-
const pages = Object.fromEntries(
|
|
92
|
-
Object.entries(pagesGlob).map(([key, value]) => [transformPath(key), value])
|
|
93
|
-
);
|
|
94
|
-
const layouts = Object.fromEntries(
|
|
95
|
-
Object.entries(layoutsGlob).map(([key, value]) => [transformPath(key), value])
|
|
96
|
-
);
|
|
97
|
-
const notFounds = Object.fromEntries(
|
|
98
|
-
Object.entries(notFoundsGlob).map(([key, value]) => [transformPath(key), value])
|
|
99
|
-
);
|
|
100
|
-
|
|
101
|
-
export function generateRoutes() {
|
|
102
|
-
const tree = buildRouteTree(pages, layouts, notFounds);
|
|
103
|
-
const routes = treeToRoutes(tree, true);
|
|
104
|
-
return routes;
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
export function Router() {
|
|
108
|
-
return useRoutes(generateRoutes());
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
export { Link, useRoutes };
|
|
112
|
-
`;
|
|
113
|
-
},
|
|
114
|
-
handleHotUpdate({ file: o, server: c }) {
|
|
115
|
-
if (o.includes(t) && (o.endsWith(s) || o.endsWith(n) || o.endsWith(a))) {
|
|
116
|
-
f();
|
|
117
|
-
const d = c.moduleGraph.getModuleById(
|
|
118
|
-
r
|
|
119
|
-
);
|
|
120
|
-
d && (c.moduleGraph.invalidateModule(d), c.ws.send({
|
|
121
|
-
type: "full-reload",
|
|
122
|
-
path: "*"
|
|
123
|
-
}));
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
};
|
|
127
|
-
}
|
|
128
|
-
export {
|
|
129
|
-
g as a,
|
|
130
|
-
b as e,
|
|
131
|
-
y as n
|
|
132
|
-
};
|