vite-react-ssg 0.2.0 → 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 +202 -26
- package/dist/index.cjs +11 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.mjs +12 -1
- package/dist/node/cli.cjs +1 -1
- package/dist/node/cli.mjs +1 -1
- package/dist/node.cjs +1 -1
- package/dist/node.d.ts +1 -1
- package/dist/node.mjs +1 -1
- package/dist/shared/{vite-react-ssg.b0fd1823.cjs → vite-react-ssg.9cf631b2.cjs} +71 -35
- package/dist/shared/{vite-react-ssg.b83f6ed3.mjs → vite-react-ssg.f12aa7be.mjs} +69 -33
- package/dist/{types-408e974a.d.ts → types-c03d6a58.d.ts} +11 -2
- package/package.json +1 -2
package/README.md
CHANGED
|
@@ -4,7 +4,24 @@ Static-site generation for React on Vite.
|
|
|
4
4
|
|
|
5
5
|
[](https://www.npmjs.com/package/vite-react-ssg)
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
# Table of contents
|
|
8
|
+
* [Usage](#usage)
|
|
9
|
+
* [Extra route options](#extra-route-options)
|
|
10
|
+
* [`entry`](#entry)
|
|
11
|
+
* [`getStaticPaths`](#getstaticpaths)
|
|
12
|
+
* [lazy](#lazy)
|
|
13
|
+
* [`<ClientOnly/>`](#clientonly)
|
|
14
|
+
* [Document head](#document-head)
|
|
15
|
+
* [Reactive head](#reactive-head)
|
|
16
|
+
* [CSS in JS](#css-in-js)
|
|
17
|
+
* [Critical CSS](#critical-css)
|
|
18
|
+
* [Configuration](#configuration)
|
|
19
|
+
* [Custom Routes to Render](#custom-routes-to-render)
|
|
20
|
+
* [Use CSR in development environment](#use-csr-in-development-environment)
|
|
21
|
+
* [Roadmap](#roadmap)
|
|
22
|
+
* [Credits](#credits)
|
|
23
|
+
|
|
24
|
+
## Usage
|
|
8
25
|
|
|
9
26
|
<pre>
|
|
10
27
|
<b>npm i -D vite-react-ssg</b> <em>react-router-dom</em>
|
|
@@ -46,40 +63,91 @@ import React from 'react'
|
|
|
46
63
|
import type { RouteRecord } from 'vite-react-ssg'
|
|
47
64
|
import './App.css'
|
|
48
65
|
|
|
49
|
-
const pages = import.meta.glob<any>('./pages/**/*.tsx')
|
|
50
|
-
|
|
51
|
-
const children: RouteRecord[] = Object.entries(pages).map(([filepath, component]) => {
|
|
52
|
-
let path = filepath.split('/pages')[1]
|
|
53
|
-
path = path.split('.')[0].replace('index', '')
|
|
54
|
-
const entry = `src${filepath.slice(1)}`
|
|
55
|
-
|
|
56
|
-
if (path.endsWith('/')) {
|
|
57
|
-
return {
|
|
58
|
-
index: true,
|
|
59
|
-
Component: React.lazy(component),
|
|
60
|
-
entry,
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
return {
|
|
64
|
-
path,
|
|
65
|
-
Component: React.lazy(component),
|
|
66
|
-
// Used to obtain static resources through manifest
|
|
67
|
-
entry,
|
|
68
|
-
}
|
|
69
|
-
})
|
|
70
|
-
|
|
71
66
|
const Layout = React.lazy(() => import('./Layout'))
|
|
67
|
+
|
|
72
68
|
export const routes: RouteRecord[] = [
|
|
73
69
|
{
|
|
74
70
|
path: '/',
|
|
75
71
|
element: <Layout />,
|
|
76
|
-
children,
|
|
77
|
-
// Used to obtain static resources through manifest
|
|
78
72
|
entry: 'src/Layout.tsx',
|
|
73
|
+
children: [
|
|
74
|
+
{
|
|
75
|
+
path: 'a',
|
|
76
|
+
Component: React.lazy(() => import('./pages/a')),
|
|
77
|
+
entry: 'src/pages/a.tsx',
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
index: true,
|
|
81
|
+
Component: React.lazy(() => import('./pages/index')),
|
|
82
|
+
// Used to obtain static resources through manifest
|
|
83
|
+
entry: 'src/pages/index.tsx',
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
path: 'nest/:b',
|
|
87
|
+
Component: React.lazy(() => import('./pages/nest/[b]')),
|
|
88
|
+
entry: 'src/pages/nest/[b].tsx',
|
|
89
|
+
// To determine which paths will be pre-rendered
|
|
90
|
+
getStaticPaths: () => ['nest/b1', 'nest/b2'],
|
|
91
|
+
},
|
|
92
|
+
],
|
|
79
93
|
},
|
|
80
94
|
]
|
|
81
95
|
```
|
|
82
96
|
|
|
97
|
+
## Extra route options
|
|
98
|
+
|
|
99
|
+
The RouteObject of vite-react-ssg is based on react-router, and vite-react-ssg receives some additional properties.
|
|
100
|
+
|
|
101
|
+
#### `entry`
|
|
102
|
+
Used to obtain static resources.If you introduce static resources (such as css files) in that route and use lazy loading (such as React.lazy or route.lazy), you should set the entry field. It should be the path from root to the target file.
|
|
103
|
+
|
|
104
|
+
eg: `src/pages/page1.tsx`
|
|
105
|
+
|
|
106
|
+
#### `getStaticPaths`
|
|
107
|
+
The `getStaticPaths()` function should return an array of path
|
|
108
|
+
to determine which paths will be pre-rendered by vite-react-ssg.
|
|
109
|
+
|
|
110
|
+
This function is only valid for dynamic route.
|
|
111
|
+
|
|
112
|
+
```ts
|
|
113
|
+
const route = {
|
|
114
|
+
path: 'nest/:b',
|
|
115
|
+
Component: React.lazy(() => import('./pages/nest/[b]')),
|
|
116
|
+
entry: 'src/pages/nest/[b].tsx',
|
|
117
|
+
// To determine which paths will be pre-rendered
|
|
118
|
+
getStaticPaths: () => ['nest/b1', 'nest/b2'],
|
|
119
|
+
},
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
## lazy
|
|
123
|
+
These options work well with the `lazy` field.
|
|
124
|
+
|
|
125
|
+
```tsx
|
|
126
|
+
// src/pages/[page].tsx
|
|
127
|
+
export function Component() {
|
|
128
|
+
return (
|
|
129
|
+
<div>{/* your component */}</div>
|
|
130
|
+
)
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
export function getStaticPaths() {
|
|
134
|
+
return ['page1', 'page2']
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
export const entry = 'src/pages/[page].tsx'
|
|
138
|
+
```
|
|
139
|
+
```ts
|
|
140
|
+
// src/routes.ts
|
|
141
|
+
const routes = [
|
|
142
|
+
{
|
|
143
|
+
path: '/:page',
|
|
144
|
+
lazy: () => import('./pages/[page]')
|
|
145
|
+
}
|
|
146
|
+
]
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
See [example](./examples/lazy-pages/src/App.tsx).
|
|
150
|
+
|
|
83
151
|
## `<ClientOnly/>`
|
|
84
152
|
|
|
85
153
|
If you need to render some component in browser only, you can wrap your component with `<ClientOnly>`.
|
|
@@ -227,6 +295,110 @@ export default {
|
|
|
227
295
|
}
|
|
228
296
|
```
|
|
229
297
|
|
|
298
|
+
```ts
|
|
299
|
+
interface ViteReactSSGOptions {
|
|
300
|
+
/**
|
|
301
|
+
* Set the scripts' loading mode. Only works for `type="module"`.
|
|
302
|
+
*
|
|
303
|
+
* @default 'sync'
|
|
304
|
+
*/
|
|
305
|
+
script?: 'sync' | 'async' | 'defer' | 'async defer'
|
|
306
|
+
/**
|
|
307
|
+
* Build format.
|
|
308
|
+
*
|
|
309
|
+
* @default 'esm'
|
|
310
|
+
*/
|
|
311
|
+
format?: 'esm' | 'cjs'
|
|
312
|
+
/**
|
|
313
|
+
* The path of the main entry file (relative to the project root).
|
|
314
|
+
*
|
|
315
|
+
* @default 'src/main.ts'
|
|
316
|
+
*/
|
|
317
|
+
entry?: string
|
|
318
|
+
/**
|
|
319
|
+
* Mock browser global variables (window, document, etc...) from SSG.
|
|
320
|
+
*
|
|
321
|
+
* @default false
|
|
322
|
+
*/
|
|
323
|
+
mock?: boolean
|
|
324
|
+
/**
|
|
325
|
+
* Apply formatter to the generated index file.
|
|
326
|
+
*
|
|
327
|
+
* **It will cause Hydration Failed.**
|
|
328
|
+
*
|
|
329
|
+
* @default 'none'
|
|
330
|
+
*/
|
|
331
|
+
formatting?: 'minify' | 'prettify' | 'none'
|
|
332
|
+
/**
|
|
333
|
+
* Vite environmeng mode.
|
|
334
|
+
*/
|
|
335
|
+
mode?: string
|
|
336
|
+
/**
|
|
337
|
+
* Directory style of the output directory.
|
|
338
|
+
*
|
|
339
|
+
* flat: `/foo` -> `/foo.html`
|
|
340
|
+
* nested: `/foo` -> `/foo/index.html`
|
|
341
|
+
*
|
|
342
|
+
* @default 'flat'
|
|
343
|
+
*/
|
|
344
|
+
dirStyle?: 'flat' | 'nested'
|
|
345
|
+
/**
|
|
346
|
+
* Generate for all routes, including dynamic routes.
|
|
347
|
+
* If enabled, you will need to configGure your serve
|
|
348
|
+
* manually to handle dynamic routes properly.
|
|
349
|
+
*
|
|
350
|
+
* @default false
|
|
351
|
+
*/
|
|
352
|
+
includeAllRoutes?: boolean
|
|
353
|
+
/**
|
|
354
|
+
* Options for the critters packages.
|
|
355
|
+
*
|
|
356
|
+
* @see https://github.com/GoogleChromeLabs/critters
|
|
357
|
+
*/
|
|
358
|
+
crittersOptions?: CrittersOptions | false
|
|
359
|
+
/**
|
|
360
|
+
* Custom function to modify the routes to do the SSG.
|
|
361
|
+
*
|
|
362
|
+
* Works only when `includeAllRoutes` is set to false.
|
|
363
|
+
*
|
|
364
|
+
* Defaults to a handler that filters out all the dynamic routes.
|
|
365
|
+
* When passing your custom handler, you should also take care of the dynamic routes yourself.
|
|
366
|
+
*/
|
|
367
|
+
includedRoutes?: (paths: string[], routes: Readonly<RouteRecord[]>) => Promise<string[]> | string[]
|
|
368
|
+
/**
|
|
369
|
+
* Callback to be called before every page render.
|
|
370
|
+
*
|
|
371
|
+
* It can be used to transform the project's `index.html` file before passing it to the renderer.
|
|
372
|
+
*
|
|
373
|
+
* To do so, you can change the 'index.html' file contents (passed in through the `indexHTML` parameter), and return it.
|
|
374
|
+
* The returned value will then be passed to renderer.
|
|
375
|
+
*/
|
|
376
|
+
onBeforePageRender?: (route: string, indexHTML: string, appCtx: ViteReactSSGContext<true>) => Promise<string | null | undefined> | string | null | undefined
|
|
377
|
+
/**
|
|
378
|
+
* Callback to be called on every rendered page.
|
|
379
|
+
*
|
|
380
|
+
* It can be used to transform the current route's rendered HTML.
|
|
381
|
+
*
|
|
382
|
+
* To do so, you can transform the route's rendered HTML (passed in through the `renderedHTML` parameter), and return it.
|
|
383
|
+
* The returned value will be used as the HTML of the route.
|
|
384
|
+
*/
|
|
385
|
+
onPageRendered?: (route: string, renderedHTML: string, appCtx: ViteReactSSGContext<true>) => Promise<string | null | undefined> | string | null | undefined
|
|
386
|
+
|
|
387
|
+
onFinished?: () => Promise<void> | void
|
|
388
|
+
/**
|
|
389
|
+
* The application's root container `id`.
|
|
390
|
+
*
|
|
391
|
+
* @default `root`
|
|
392
|
+
*/
|
|
393
|
+
rootContainerId?: string
|
|
394
|
+
/**
|
|
395
|
+
* The size of the SSG processing queue.
|
|
396
|
+
*
|
|
397
|
+
* @default 20
|
|
398
|
+
*/
|
|
399
|
+
concurrency?: number
|
|
400
|
+
}
|
|
401
|
+
```
|
|
230
402
|
See [src/types.ts](./src/types.ts). for more options available.
|
|
231
403
|
|
|
232
404
|
### Custom Routes to Render
|
|
@@ -301,8 +473,12 @@ Then, you can start the application with CSR in the development environment.
|
|
|
301
473
|
- [x] Preload assets
|
|
302
474
|
- [x] Document head
|
|
303
475
|
- [x] SSR in dev environment
|
|
476
|
+
- [x] More Client components, such as `<ClientOnly />`
|
|
477
|
+
- [x] `getStaticPaths` for dynamic routes
|
|
304
478
|
- [ ] Initial State
|
|
305
|
-
|
|
479
|
+
|
|
480
|
+
## Credits
|
|
481
|
+
This project inspired by [vite-ssg](https://github.com/antfu/vite-ssg), thanks to [@antfu](https://github.com/antfu) for his awesome work.
|
|
306
482
|
|
|
307
483
|
## License
|
|
308
484
|
|
package/dist/index.cjs
CHANGED
|
@@ -157,6 +157,17 @@ function ViteReactSSG(routerOptions, fn, options = {}) {
|
|
|
157
157
|
root.render(app);
|
|
158
158
|
});
|
|
159
159
|
} else {
|
|
160
|
+
const lazeMatches = reactRouterDom.matchRoutes(routerOptions.routes, window.location)?.filter(
|
|
161
|
+
(m) => m.route.lazy
|
|
162
|
+
);
|
|
163
|
+
if (lazeMatches && lazeMatches?.length > 0) {
|
|
164
|
+
await Promise.all(
|
|
165
|
+
lazeMatches.map(async (m) => {
|
|
166
|
+
const routeModule = await m.route.lazy();
|
|
167
|
+
Object.assign(m.route, { ...routeModule, lazy: void 0 });
|
|
168
|
+
})
|
|
169
|
+
);
|
|
170
|
+
}
|
|
160
171
|
React__default.startTransition(() => {
|
|
161
172
|
client.hydrateRoot(container, app);
|
|
162
173
|
});
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { R as RouterOptions, V as ViteReactSSGContext, a as ViteReactSSGClientOptions } from './types-
|
|
2
|
-
export { I as IndexRouteRecord, N as NonIndexRouteRecord, c as RouteRecord, S as StyleCollector, b as ViteReactSSGOptions } from './types-
|
|
1
|
+
import { R as RouterOptions, V as ViteReactSSGContext, a as ViteReactSSGClientOptions } from './types-c03d6a58.js';
|
|
2
|
+
export { I as IndexRouteRecord, N as NonIndexRouteRecord, c as RouteRecord, S as StyleCollector, b as ViteReactSSGOptions } from './types-c03d6a58.js';
|
|
3
3
|
import React, { ReactNode } from 'react';
|
|
4
4
|
import { HelmetProps } from 'react-helmet-async';
|
|
5
5
|
import { LinkProps, NavLinkProps } from 'react-router-dom';
|
package/dist/index.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React, { useState, useEffect, isValidElement, forwardRef } from 'react';
|
|
2
2
|
import { createRoot, hydrateRoot } from 'react-dom/client';
|
|
3
3
|
import { HelmetProvider } from 'react-helmet-async';
|
|
4
|
-
import { useLinkClickHandler, Link as Link$1, NavLink as NavLink$1, createBrowserRouter, RouterProvider } from 'react-router-dom';
|
|
4
|
+
import { useLinkClickHandler, Link as Link$1, NavLink as NavLink$1, matchRoutes, createBrowserRouter, RouterProvider } from 'react-router-dom';
|
|
5
5
|
import { d as deserializeState, S as SiteMetadataDefaults } from './shared/vite-react-ssg.9d005d5e.mjs';
|
|
6
6
|
export { H as Head } from './shared/vite-react-ssg.9d005d5e.mjs';
|
|
7
7
|
|
|
@@ -152,6 +152,17 @@ function ViteReactSSG(routerOptions, fn, options = {}) {
|
|
|
152
152
|
root.render(app);
|
|
153
153
|
});
|
|
154
154
|
} else {
|
|
155
|
+
const lazeMatches = matchRoutes(routerOptions.routes, window.location)?.filter(
|
|
156
|
+
(m) => m.route.lazy
|
|
157
|
+
);
|
|
158
|
+
if (lazeMatches && lazeMatches?.length > 0) {
|
|
159
|
+
await Promise.all(
|
|
160
|
+
lazeMatches.map(async (m) => {
|
|
161
|
+
const routeModule = await m.route.lazy();
|
|
162
|
+
Object.assign(m.route, { ...routeModule, lazy: void 0 });
|
|
163
|
+
})
|
|
164
|
+
);
|
|
165
|
+
}
|
|
155
166
|
React.startTransition(() => {
|
|
156
167
|
hydrateRoot(container, app);
|
|
157
168
|
});
|
package/dist/node/cli.cjs
CHANGED
|
@@ -4,7 +4,7 @@ const kolorist = require('kolorist');
|
|
|
4
4
|
const yargs = require('yargs');
|
|
5
5
|
const helpers = require('yargs/helpers');
|
|
6
6
|
const webFetch = require('@remix-run/web-fetch');
|
|
7
|
-
const dev = require('../shared/vite-react-ssg.
|
|
7
|
+
const dev = require('../shared/vite-react-ssg.9cf631b2.cjs');
|
|
8
8
|
require('node:path');
|
|
9
9
|
require('node:module');
|
|
10
10
|
require('fs-extra');
|
package/dist/node/cli.mjs
CHANGED
|
@@ -2,7 +2,7 @@ import { gray, bold, red, reset, underline } from 'kolorist';
|
|
|
2
2
|
import yargs from 'yargs';
|
|
3
3
|
import { hideBin } from 'yargs/helpers';
|
|
4
4
|
import { Request, Response, fetch as fetch$1, Headers, FormData } from '@remix-run/web-fetch';
|
|
5
|
-
import { b as build, d as dev } from '../shared/vite-react-ssg.
|
|
5
|
+
import { b as build, d as dev } from '../shared/vite-react-ssg.f12aa7be.mjs';
|
|
6
6
|
import 'node:path';
|
|
7
7
|
import 'node:module';
|
|
8
8
|
import 'fs-extra';
|
package/dist/node.cjs
CHANGED
package/dist/node.d.ts
CHANGED
package/dist/node.mjs
CHANGED
|
@@ -872,6 +872,8 @@ function routesToPaths(routes) {
|
|
|
872
872
|
function addEntry(path, entry) {
|
|
873
873
|
if (!entry)
|
|
874
874
|
return;
|
|
875
|
+
if (entry[0] === "/")
|
|
876
|
+
entry = entry.slice(1);
|
|
875
877
|
if (pathToEntry[path])
|
|
876
878
|
pathToEntry[path].add(entry);
|
|
877
879
|
else
|
|
@@ -880,20 +882,22 @@ function routesToPaths(routes) {
|
|
|
880
882
|
if (!routes)
|
|
881
883
|
return { paths: ["/"], pathToEntry };
|
|
882
884
|
const paths = /* @__PURE__ */ new Set();
|
|
885
|
+
const lazyPaths = /* @__PURE__ */ new Set();
|
|
883
886
|
const getPaths = (routes2, prefix = "") => {
|
|
884
|
-
const parentPath = prefix;
|
|
885
887
|
prefix = prefix.replace(/\/$/g, "");
|
|
886
888
|
for (const route of routes2) {
|
|
887
889
|
let path = route.path;
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
890
|
+
path = handlePath(path, prefix, route.entry);
|
|
891
|
+
if (route.getStaticPaths && path?.includes(":")) {
|
|
892
|
+
const staticPaths = route.getStaticPaths();
|
|
893
|
+
for (let staticPath of staticPaths) {
|
|
894
|
+
staticPath = handlePath(staticPath, prefix, route.entry);
|
|
895
|
+
if (Array.isArray(route.children))
|
|
896
|
+
getPaths(route.children, staticPath);
|
|
895
897
|
}
|
|
896
898
|
}
|
|
899
|
+
if (route.lazy)
|
|
900
|
+
lazyPaths.add(route.index ? prefix : path ?? "");
|
|
897
901
|
if (route.index)
|
|
898
902
|
addEntry(prefix, route.entry);
|
|
899
903
|
if (Array.isArray(route.children))
|
|
@@ -901,7 +905,19 @@ function routesToPaths(routes) {
|
|
|
901
905
|
}
|
|
902
906
|
};
|
|
903
907
|
getPaths(routes);
|
|
904
|
-
return { paths: Array.from(paths), pathToEntry };
|
|
908
|
+
return { paths: Array.from(paths), pathToEntry, lazyPaths: Array.from(lazyPaths) };
|
|
909
|
+
function handlePath(path, prefix, entry) {
|
|
910
|
+
if (path != null) {
|
|
911
|
+
path = prefix && !path.startsWith("/") ? `${prefix}${path ? `/${path}` : ""}` : path;
|
|
912
|
+
paths.add(path);
|
|
913
|
+
addEntry(path, entry);
|
|
914
|
+
if (pathToEntry[prefix]) {
|
|
915
|
+
const pathCopy = path;
|
|
916
|
+
pathToEntry[prefix].forEach((entry2) => addEntry(pathCopy, entry2));
|
|
917
|
+
}
|
|
918
|
+
}
|
|
919
|
+
return path;
|
|
920
|
+
}
|
|
905
921
|
}
|
|
906
922
|
function createFetchRequest(req) {
|
|
907
923
|
const origin = `${req.protocol}://${req.get("host")}`;
|
|
@@ -934,8 +950,15 @@ async function resolveAlias(config, entry) {
|
|
|
934
950
|
return result || node_path.join(config.root, entry);
|
|
935
951
|
}
|
|
936
952
|
const { version } = JSON.parse(
|
|
937
|
-
node_fs.readFileSync(new URL("../../package.json", (typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (document.currentScript && document.currentScript.src || new URL('shared/vite-react-ssg.
|
|
953
|
+
node_fs.readFileSync(new URL("../../package.json", (typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (document.currentScript && document.currentScript.src || new URL('shared/vite-react-ssg.9cf631b2.cjs', document.baseURI).href)))).toString()
|
|
938
954
|
);
|
|
955
|
+
function createRequest(path) {
|
|
956
|
+
const url = new URL(path, "http://vite-react-ssg.com");
|
|
957
|
+
url.search = "";
|
|
958
|
+
url.hash = "";
|
|
959
|
+
url.pathname = path;
|
|
960
|
+
return new Request(url.href);
|
|
961
|
+
}
|
|
939
962
|
|
|
940
963
|
async function getCritters(outDir, options = {}) {
|
|
941
964
|
try {
|
|
@@ -1020,7 +1043,17 @@ async function render(routes, request, styleCollector) {
|
|
|
1020
1043
|
];
|
|
1021
1044
|
const styleTag = styleCollector?.toString?.(appHTML) ?? "";
|
|
1022
1045
|
const metaAttributes = metaStrings.filter(Boolean);
|
|
1023
|
-
return { appHTML, htmlAttributes, bodyAttributes, metaAttributes, styleTag };
|
|
1046
|
+
return { appHTML, htmlAttributes, bodyAttributes, metaAttributes, styleTag, routerContext: context };
|
|
1047
|
+
}
|
|
1048
|
+
async function preLoad(routes, paths) {
|
|
1049
|
+
if (!paths || paths.length === 0)
|
|
1050
|
+
return routes;
|
|
1051
|
+
const { dataRoutes, query } = server_js.createStaticHandler(routes);
|
|
1052
|
+
await Promise.all(paths.map(async (path) => {
|
|
1053
|
+
const request = createRequest(path);
|
|
1054
|
+
return query(request);
|
|
1055
|
+
}));
|
|
1056
|
+
return dataRoutes;
|
|
1024
1057
|
}
|
|
1025
1058
|
|
|
1026
1059
|
function renderPreloadLinks(document, modules, ssrManifest) {
|
|
@@ -1200,12 +1233,15 @@ async function build(ssgOptions = {}, viteConfig = {}) {
|
|
|
1200
1233
|
const prefix = format === "esm" && process.platform === "win32" ? "file://" : "";
|
|
1201
1234
|
const ext = format === "esm" ? ".mjs" : ".cjs";
|
|
1202
1235
|
const serverEntry = node_path.join(prefix, ssgOut, node_path.parse(ssrEntry).name + ext);
|
|
1203
|
-
const _require = node_module.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (document.currentScript && document.currentScript.src || new URL('shared/vite-react-ssg.
|
|
1236
|
+
const _require = node_module.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (document.currentScript && document.currentScript.src || new URL('shared/vite-react-ssg.9cf631b2.cjs', document.baseURI).href)));
|
|
1204
1237
|
const { createRoot, includedRoutes: serverEntryIncludedRoutes } = format === "esm" ? await import(serverEntry) : _require(serverEntry);
|
|
1205
1238
|
const includedRoutes = serverEntryIncludedRoutes || configIncludedRoutes;
|
|
1206
1239
|
const { routes } = await createRoot(false);
|
|
1207
|
-
const {
|
|
1240
|
+
const { lazyPaths } = routesToPaths(routes);
|
|
1241
|
+
const dataRoutes = await preLoad([...routes], lazyPaths);
|
|
1242
|
+
const { paths, pathToEntry } = routesToPaths(dataRoutes);
|
|
1208
1243
|
let routesPaths = includeAllRoutes ? paths : await includedRoutes(paths, routes || []);
|
|
1244
|
+
routesPaths = DefaultIncludedRoutes(routesPaths);
|
|
1209
1245
|
routesPaths = Array.from(new Set(routesPaths));
|
|
1210
1246
|
buildLog("Rendering Pages...", routesPaths.length);
|
|
1211
1247
|
const critters = crittersOptions !== false ? await getCritters(outDir, crittersOptions) : void 0;
|
|
@@ -1216,20 +1252,17 @@ async function build(ssgOptions = {}, viteConfig = {}) {
|
|
|
1216
1252
|
let indexHTML = await fs__default.readFile(node_path.join(out, "index.html"), "utf-8");
|
|
1217
1253
|
indexHTML = rewriteScripts(indexHTML, script);
|
|
1218
1254
|
const queue = new PQueue({ concurrency });
|
|
1219
|
-
|
|
1255
|
+
const crittersQueue = new PQueue({ concurrency: 1 });
|
|
1256
|
+
for (const path of routesPaths) {
|
|
1220
1257
|
queue.add(async () => {
|
|
1221
1258
|
try {
|
|
1222
|
-
const appCtx = await createRoot(false,
|
|
1223
|
-
const { routes: routes2,
|
|
1259
|
+
const appCtx = await createRoot(false, path);
|
|
1260
|
+
const { initialState, routes: routes2, triggerOnSSRAppRendered, transformState = SiteMetadataDefaults.serializeState, getStyleCollector } = appCtx;
|
|
1224
1261
|
const styleCollector = getStyleCollector ? await getStyleCollector() : null;
|
|
1225
|
-
const transformedIndexHTML = await onBeforePageRender?.(
|
|
1226
|
-
const
|
|
1227
|
-
url.search = "";
|
|
1228
|
-
url.hash = "";
|
|
1229
|
-
url.pathname = route;
|
|
1230
|
-
const request = new Request(url.href);
|
|
1262
|
+
const transformedIndexHTML = await onBeforePageRender?.(path, indexHTML, appCtx) || indexHTML;
|
|
1263
|
+
const request = createRequest(path);
|
|
1231
1264
|
const { appHTML, bodyAttributes, htmlAttributes, metaAttributes, styleTag } = await render([...routes2], request, styleCollector);
|
|
1232
|
-
await triggerOnSSRAppRendered?.(
|
|
1265
|
+
await triggerOnSSRAppRendered?.(path, appHTML, appCtx);
|
|
1233
1266
|
const renderedHTML = await renderHTML({
|
|
1234
1267
|
rootContainerId,
|
|
1235
1268
|
appHTML,
|
|
@@ -1240,24 +1273,24 @@ async function build(ssgOptions = {}, viteConfig = {}) {
|
|
|
1240
1273
|
initialState: null
|
|
1241
1274
|
});
|
|
1242
1275
|
const jsdom = new JSDOM.JSDOM(renderedHTML);
|
|
1243
|
-
const modules = collectModulesForEntrys(manifest, pathToEntry?.[
|
|
1276
|
+
const modules = collectModulesForEntrys(manifest, pathToEntry?.[path]);
|
|
1244
1277
|
renderPreloadLinks(jsdom.window.document, modules, ssrManifest);
|
|
1245
1278
|
const html = jsdom.serialize();
|
|
1246
|
-
let transformed = await onPageRendered?.(
|
|
1279
|
+
let transformed = await onPageRendered?.(path, html, appCtx) || html;
|
|
1247
1280
|
if (critters)
|
|
1248
|
-
transformed = await critters.process(transformed);
|
|
1281
|
+
transformed = await crittersQueue.add(() => critters.process(transformed));
|
|
1249
1282
|
if (styleTag)
|
|
1250
1283
|
transformed = transformed.replace("<head>", `<head>${styleTag}`);
|
|
1251
1284
|
const formatted = await formatHtml(transformed, formatting);
|
|
1252
|
-
const relativeRouteFile = `${(
|
|
1253
|
-
const filename = dirStyle === "nested" ? node_path.join(
|
|
1285
|
+
const relativeRouteFile = `${(path.endsWith("/") ? `${path}index` : path).replace(/^\//g, "")}.html`;
|
|
1286
|
+
const filename = dirStyle === "nested" ? node_path.join(path.replace(/^\//g, ""), "index.html") : relativeRouteFile;
|
|
1254
1287
|
await fs__default.ensureDir(node_path.join(out, node_path.dirname(filename)));
|
|
1255
1288
|
await fs__default.writeFile(node_path.join(out, filename), formatted, "utf-8");
|
|
1256
1289
|
config.logger.info(
|
|
1257
1290
|
`${kolorist.dim(`${outDir}/`)}${kolorist.cyan(filename.padEnd(15, " "))} ${kolorist.dim(getSize(formatted))}`
|
|
1258
1291
|
);
|
|
1259
1292
|
} catch (err) {
|
|
1260
|
-
throw new Error(`${kolorist.gray("[vite-react-ssg]")} ${kolorist.red(`Error on page: ${kolorist.cyan(
|
|
1293
|
+
throw new Error(`${kolorist.gray("[vite-react-ssg]")} ${kolorist.red(`Error on page: ${kolorist.cyan(path)}`)}
|
|
1261
1294
|
${err.stack}`);
|
|
1262
1295
|
}
|
|
1263
1296
|
});
|
|
@@ -1427,14 +1460,17 @@ async function dev(ssgOptions = {}, viteConfig = {}) {
|
|
|
1427
1460
|
const { routes, getStyleCollector } = appCtx;
|
|
1428
1461
|
const transformedIndexHTML = await onBeforePageRender?.(url, indexHTML, appCtx) || indexHTML;
|
|
1429
1462
|
const styleCollector = getStyleCollector ? await getStyleCollector() : null;
|
|
1430
|
-
const { appHTML, bodyAttributes, htmlAttributes, metaAttributes, styleTag } = await render([...routes], createFetchRequest(req), styleCollector);
|
|
1463
|
+
const { appHTML, bodyAttributes, htmlAttributes, metaAttributes, styleTag, routerContext } = await render([...routes], createFetchRequest(req), styleCollector);
|
|
1431
1464
|
metaAttributes.push(styleTag);
|
|
1432
|
-
const
|
|
1465
|
+
const matchesEntries = routerContext.matches.map((match) => match.route.entry).filter((entry2) => !!entry2).map((entry2) => entry2[0] === "/" ? entry2 : `/${entry2}`);
|
|
1466
|
+
const mods = await Promise.all(
|
|
1467
|
+
[entry, ...matchesEntries].map(async (entry2) => await viteServer.moduleGraph.getModuleByUrl(entry2))
|
|
1468
|
+
);
|
|
1433
1469
|
const assetsUrls = /* @__PURE__ */ new Set();
|
|
1434
|
-
const collectAssets = async (
|
|
1435
|
-
if (!
|
|
1470
|
+
const collectAssets = async (mod) => {
|
|
1471
|
+
if (!mod || !mod?.ssrTransformResult)
|
|
1436
1472
|
return;
|
|
1437
|
-
const { deps = [], dynamicDeps = [] } =
|
|
1473
|
+
const { deps = [], dynamicDeps = [] } = mod?.ssrTransformResult;
|
|
1438
1474
|
const allDeps = [...deps, ...dynamicDeps];
|
|
1439
1475
|
for (const dep of allDeps) {
|
|
1440
1476
|
if (dep.endsWith(".css")) {
|
|
@@ -1445,7 +1481,7 @@ async function dev(ssgOptions = {}, viteConfig = {}) {
|
|
|
1445
1481
|
}
|
|
1446
1482
|
}
|
|
1447
1483
|
};
|
|
1448
|
-
await collectAssets(mod);
|
|
1484
|
+
await Promise.all(mods.map(async (mod) => collectAssets(mod)));
|
|
1449
1485
|
const preloadLink = [...assetsUrls].map((item) => createLink(item));
|
|
1450
1486
|
metaAttributes.push(...preloadLink);
|
|
1451
1487
|
const renderedHTML = await renderHTML({
|
|
@@ -864,6 +864,8 @@ function routesToPaths(routes) {
|
|
|
864
864
|
function addEntry(path, entry) {
|
|
865
865
|
if (!entry)
|
|
866
866
|
return;
|
|
867
|
+
if (entry[0] === "/")
|
|
868
|
+
entry = entry.slice(1);
|
|
867
869
|
if (pathToEntry[path])
|
|
868
870
|
pathToEntry[path].add(entry);
|
|
869
871
|
else
|
|
@@ -872,20 +874,22 @@ function routesToPaths(routes) {
|
|
|
872
874
|
if (!routes)
|
|
873
875
|
return { paths: ["/"], pathToEntry };
|
|
874
876
|
const paths = /* @__PURE__ */ new Set();
|
|
877
|
+
const lazyPaths = /* @__PURE__ */ new Set();
|
|
875
878
|
const getPaths = (routes2, prefix = "") => {
|
|
876
|
-
const parentPath = prefix;
|
|
877
879
|
prefix = prefix.replace(/\/$/g, "");
|
|
878
880
|
for (const route of routes2) {
|
|
879
881
|
let path = route.path;
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
882
|
+
path = handlePath(path, prefix, route.entry);
|
|
883
|
+
if (route.getStaticPaths && path?.includes(":")) {
|
|
884
|
+
const staticPaths = route.getStaticPaths();
|
|
885
|
+
for (let staticPath of staticPaths) {
|
|
886
|
+
staticPath = handlePath(staticPath, prefix, route.entry);
|
|
887
|
+
if (Array.isArray(route.children))
|
|
888
|
+
getPaths(route.children, staticPath);
|
|
887
889
|
}
|
|
888
890
|
}
|
|
891
|
+
if (route.lazy)
|
|
892
|
+
lazyPaths.add(route.index ? prefix : path ?? "");
|
|
889
893
|
if (route.index)
|
|
890
894
|
addEntry(prefix, route.entry);
|
|
891
895
|
if (Array.isArray(route.children))
|
|
@@ -893,7 +897,19 @@ function routesToPaths(routes) {
|
|
|
893
897
|
}
|
|
894
898
|
};
|
|
895
899
|
getPaths(routes);
|
|
896
|
-
return { paths: Array.from(paths), pathToEntry };
|
|
900
|
+
return { paths: Array.from(paths), pathToEntry, lazyPaths: Array.from(lazyPaths) };
|
|
901
|
+
function handlePath(path, prefix, entry) {
|
|
902
|
+
if (path != null) {
|
|
903
|
+
path = prefix && !path.startsWith("/") ? `${prefix}${path ? `/${path}` : ""}` : path;
|
|
904
|
+
paths.add(path);
|
|
905
|
+
addEntry(path, entry);
|
|
906
|
+
if (pathToEntry[prefix]) {
|
|
907
|
+
const pathCopy = path;
|
|
908
|
+
pathToEntry[prefix].forEach((entry2) => addEntry(pathCopy, entry2));
|
|
909
|
+
}
|
|
910
|
+
}
|
|
911
|
+
return path;
|
|
912
|
+
}
|
|
897
913
|
}
|
|
898
914
|
function createFetchRequest(req) {
|
|
899
915
|
const origin = `${req.protocol}://${req.get("host")}`;
|
|
@@ -928,6 +944,13 @@ async function resolveAlias(config, entry) {
|
|
|
928
944
|
const { version } = JSON.parse(
|
|
929
945
|
readFileSync(new URL("../../package.json", import.meta.url)).toString()
|
|
930
946
|
);
|
|
947
|
+
function createRequest(path) {
|
|
948
|
+
const url = new URL(path, "http://vite-react-ssg.com");
|
|
949
|
+
url.search = "";
|
|
950
|
+
url.hash = "";
|
|
951
|
+
url.pathname = path;
|
|
952
|
+
return new Request(url.href);
|
|
953
|
+
}
|
|
931
954
|
|
|
932
955
|
async function getCritters(outDir, options = {}) {
|
|
933
956
|
try {
|
|
@@ -1012,7 +1035,17 @@ async function render(routes, request, styleCollector) {
|
|
|
1012
1035
|
];
|
|
1013
1036
|
const styleTag = styleCollector?.toString?.(appHTML) ?? "";
|
|
1014
1037
|
const metaAttributes = metaStrings.filter(Boolean);
|
|
1015
|
-
return { appHTML, htmlAttributes, bodyAttributes, metaAttributes, styleTag };
|
|
1038
|
+
return { appHTML, htmlAttributes, bodyAttributes, metaAttributes, styleTag, routerContext: context };
|
|
1039
|
+
}
|
|
1040
|
+
async function preLoad(routes, paths) {
|
|
1041
|
+
if (!paths || paths.length === 0)
|
|
1042
|
+
return routes;
|
|
1043
|
+
const { dataRoutes, query } = createStaticHandler(routes);
|
|
1044
|
+
await Promise.all(paths.map(async (path) => {
|
|
1045
|
+
const request = createRequest(path);
|
|
1046
|
+
return query(request);
|
|
1047
|
+
}));
|
|
1048
|
+
return dataRoutes;
|
|
1016
1049
|
}
|
|
1017
1050
|
|
|
1018
1051
|
function renderPreloadLinks(document, modules, ssrManifest) {
|
|
@@ -1196,8 +1229,11 @@ async function build(ssgOptions = {}, viteConfig = {}) {
|
|
|
1196
1229
|
const { createRoot, includedRoutes: serverEntryIncludedRoutes } = format === "esm" ? await import(serverEntry) : _require(serverEntry);
|
|
1197
1230
|
const includedRoutes = serverEntryIncludedRoutes || configIncludedRoutes;
|
|
1198
1231
|
const { routes } = await createRoot(false);
|
|
1199
|
-
const {
|
|
1232
|
+
const { lazyPaths } = routesToPaths(routes);
|
|
1233
|
+
const dataRoutes = await preLoad([...routes], lazyPaths);
|
|
1234
|
+
const { paths, pathToEntry } = routesToPaths(dataRoutes);
|
|
1200
1235
|
let routesPaths = includeAllRoutes ? paths : await includedRoutes(paths, routes || []);
|
|
1236
|
+
routesPaths = DefaultIncludedRoutes(routesPaths);
|
|
1201
1237
|
routesPaths = Array.from(new Set(routesPaths));
|
|
1202
1238
|
buildLog("Rendering Pages...", routesPaths.length);
|
|
1203
1239
|
const critters = crittersOptions !== false ? await getCritters(outDir, crittersOptions) : void 0;
|
|
@@ -1208,20 +1244,17 @@ async function build(ssgOptions = {}, viteConfig = {}) {
|
|
|
1208
1244
|
let indexHTML = await fs.readFile(join(out, "index.html"), "utf-8");
|
|
1209
1245
|
indexHTML = rewriteScripts(indexHTML, script);
|
|
1210
1246
|
const queue = new PQueue({ concurrency });
|
|
1211
|
-
|
|
1247
|
+
const crittersQueue = new PQueue({ concurrency: 1 });
|
|
1248
|
+
for (const path of routesPaths) {
|
|
1212
1249
|
queue.add(async () => {
|
|
1213
1250
|
try {
|
|
1214
|
-
const appCtx = await createRoot(false,
|
|
1215
|
-
const { routes: routes2,
|
|
1251
|
+
const appCtx = await createRoot(false, path);
|
|
1252
|
+
const { initialState, routes: routes2, triggerOnSSRAppRendered, transformState = serializeState, getStyleCollector } = appCtx;
|
|
1216
1253
|
const styleCollector = getStyleCollector ? await getStyleCollector() : null;
|
|
1217
|
-
const transformedIndexHTML = await onBeforePageRender?.(
|
|
1218
|
-
const
|
|
1219
|
-
url.search = "";
|
|
1220
|
-
url.hash = "";
|
|
1221
|
-
url.pathname = route;
|
|
1222
|
-
const request = new Request(url.href);
|
|
1254
|
+
const transformedIndexHTML = await onBeforePageRender?.(path, indexHTML, appCtx) || indexHTML;
|
|
1255
|
+
const request = createRequest(path);
|
|
1223
1256
|
const { appHTML, bodyAttributes, htmlAttributes, metaAttributes, styleTag } = await render([...routes2], request, styleCollector);
|
|
1224
|
-
await triggerOnSSRAppRendered?.(
|
|
1257
|
+
await triggerOnSSRAppRendered?.(path, appHTML, appCtx);
|
|
1225
1258
|
const renderedHTML = await renderHTML({
|
|
1226
1259
|
rootContainerId,
|
|
1227
1260
|
appHTML,
|
|
@@ -1232,24 +1265,24 @@ async function build(ssgOptions = {}, viteConfig = {}) {
|
|
|
1232
1265
|
initialState: null
|
|
1233
1266
|
});
|
|
1234
1267
|
const jsdom = new JSDOM(renderedHTML);
|
|
1235
|
-
const modules = collectModulesForEntrys(manifest, pathToEntry?.[
|
|
1268
|
+
const modules = collectModulesForEntrys(manifest, pathToEntry?.[path]);
|
|
1236
1269
|
renderPreloadLinks(jsdom.window.document, modules, ssrManifest);
|
|
1237
1270
|
const html = jsdom.serialize();
|
|
1238
|
-
let transformed = await onPageRendered?.(
|
|
1271
|
+
let transformed = await onPageRendered?.(path, html, appCtx) || html;
|
|
1239
1272
|
if (critters)
|
|
1240
|
-
transformed = await critters.process(transformed);
|
|
1273
|
+
transformed = await crittersQueue.add(() => critters.process(transformed));
|
|
1241
1274
|
if (styleTag)
|
|
1242
1275
|
transformed = transformed.replace("<head>", `<head>${styleTag}`);
|
|
1243
1276
|
const formatted = await formatHtml(transformed, formatting);
|
|
1244
|
-
const relativeRouteFile = `${(
|
|
1245
|
-
const filename = dirStyle === "nested" ? join(
|
|
1277
|
+
const relativeRouteFile = `${(path.endsWith("/") ? `${path}index` : path).replace(/^\//g, "")}.html`;
|
|
1278
|
+
const filename = dirStyle === "nested" ? join(path.replace(/^\//g, ""), "index.html") : relativeRouteFile;
|
|
1246
1279
|
await fs.ensureDir(join(out, dirname(filename)));
|
|
1247
1280
|
await fs.writeFile(join(out, filename), formatted, "utf-8");
|
|
1248
1281
|
config.logger.info(
|
|
1249
1282
|
`${dim(`${outDir}/`)}${cyan(filename.padEnd(15, " "))} ${dim(getSize(formatted))}`
|
|
1250
1283
|
);
|
|
1251
1284
|
} catch (err) {
|
|
1252
|
-
throw new Error(`${gray("[vite-react-ssg]")} ${red(`Error on page: ${cyan(
|
|
1285
|
+
throw new Error(`${gray("[vite-react-ssg]")} ${red(`Error on page: ${cyan(path)}`)}
|
|
1253
1286
|
${err.stack}`);
|
|
1254
1287
|
}
|
|
1255
1288
|
});
|
|
@@ -1419,14 +1452,17 @@ async function dev(ssgOptions = {}, viteConfig = {}) {
|
|
|
1419
1452
|
const { routes, getStyleCollector } = appCtx;
|
|
1420
1453
|
const transformedIndexHTML = await onBeforePageRender?.(url, indexHTML, appCtx) || indexHTML;
|
|
1421
1454
|
const styleCollector = getStyleCollector ? await getStyleCollector() : null;
|
|
1422
|
-
const { appHTML, bodyAttributes, htmlAttributes, metaAttributes, styleTag } = await render([...routes], createFetchRequest(req), styleCollector);
|
|
1455
|
+
const { appHTML, bodyAttributes, htmlAttributes, metaAttributes, styleTag, routerContext } = await render([...routes], createFetchRequest(req), styleCollector);
|
|
1423
1456
|
metaAttributes.push(styleTag);
|
|
1424
|
-
const
|
|
1457
|
+
const matchesEntries = routerContext.matches.map((match) => match.route.entry).filter((entry2) => !!entry2).map((entry2) => entry2[0] === "/" ? entry2 : `/${entry2}`);
|
|
1458
|
+
const mods = await Promise.all(
|
|
1459
|
+
[entry, ...matchesEntries].map(async (entry2) => await viteServer.moduleGraph.getModuleByUrl(entry2))
|
|
1460
|
+
);
|
|
1425
1461
|
const assetsUrls = /* @__PURE__ */ new Set();
|
|
1426
|
-
const collectAssets = async (
|
|
1427
|
-
if (!
|
|
1462
|
+
const collectAssets = async (mod) => {
|
|
1463
|
+
if (!mod || !mod?.ssrTransformResult)
|
|
1428
1464
|
return;
|
|
1429
|
-
const { deps = [], dynamicDeps = [] } =
|
|
1465
|
+
const { deps = [], dynamicDeps = [] } = mod?.ssrTransformResult;
|
|
1430
1466
|
const allDeps = [...deps, ...dynamicDeps];
|
|
1431
1467
|
for (const dep of allDeps) {
|
|
1432
1468
|
if (dep.endsWith(".css")) {
|
|
@@ -1437,7 +1473,7 @@ async function dev(ssgOptions = {}, viteConfig = {}) {
|
|
|
1437
1473
|
}
|
|
1438
1474
|
}
|
|
1439
1475
|
};
|
|
1440
|
-
await collectAssets(mod);
|
|
1476
|
+
await Promise.all(mods.map(async (mod) => collectAssets(mod)));
|
|
1441
1477
|
const preloadLink = [...assetsUrls].map((item) => createLink(item));
|
|
1442
1478
|
metaAttributes.push(...preloadLink);
|
|
1443
1479
|
const renderedHTML = await renderHTML({
|
|
@@ -92,7 +92,7 @@ interface ViteReactSSGOptions {
|
|
|
92
92
|
onPageRendered?: (route: string, renderedHTML: string, appCtx: ViteReactSSGContext<true>) => Promise<string | null | undefined> | string | null | undefined;
|
|
93
93
|
onFinished?: () => Promise<void> | void;
|
|
94
94
|
/**
|
|
95
|
-
* The application's root container `
|
|
95
|
+
* The application's root container `id`.
|
|
96
96
|
*
|
|
97
97
|
* @default `root`
|
|
98
98
|
*/
|
|
@@ -142,9 +142,18 @@ interface CommonRouteOptions {
|
|
|
142
142
|
/**
|
|
143
143
|
* Used to obtain static resources through manifest
|
|
144
144
|
*
|
|
145
|
-
* @example `src/pages/home.tsx
|
|
145
|
+
* @example `src/pages/home.tsx`
|
|
146
146
|
*/
|
|
147
147
|
entry?: string;
|
|
148
|
+
/**
|
|
149
|
+
* The getStaticPaths() function should return an array of path
|
|
150
|
+
* to determine which paths will be pre-rendered by vite-react-ssg.
|
|
151
|
+
*
|
|
152
|
+
* This function is only valid for dynamic route.
|
|
153
|
+
*
|
|
154
|
+
* @example () => ['path1', 'path2']
|
|
155
|
+
*/
|
|
156
|
+
getStaticPaths?: () => string[];
|
|
148
157
|
}
|
|
149
158
|
type NonIndexRouteRecord = Omit<NonIndexRouteObject, 'children'> & {
|
|
150
159
|
children?: RouteRecord[];
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vite-react-ssg",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.3.1",
|
|
5
5
|
"packageManager": "pnpm@8.6.6",
|
|
6
6
|
"description": "",
|
|
7
7
|
"author": "Riri <Daydreamerriri@outlook.com>",
|
|
@@ -118,7 +118,6 @@
|
|
|
118
118
|
"react-dom": "^18.2.0",
|
|
119
119
|
"react-router-dom": "^6.14.1",
|
|
120
120
|
"rimraf": "5.0.1",
|
|
121
|
-
"simple-git-hooks": "^2.8.1",
|
|
122
121
|
"styled-components": "6.0.5",
|
|
123
122
|
"typescript": "5.1.6",
|
|
124
123
|
"unbuild": "^1.2.1",
|