vite-react-ssg 0.0.1 → 0.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/README.md +42 -2
- package/bin/vite-react-ssg.js +0 -0
- package/dist/index.cjs +3 -3
- package/dist/index.d.ts +3 -2
- package/dist/index.mjs +3 -3
- 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 -2
- package/dist/node.mjs +1 -1
- package/dist/shared/{vite-react-ssg.1128b41a.cjs → vite-react-ssg.0e1b881e.cjs} +46 -10
- package/dist/shared/{vite-react-ssg.c2c344c3.mjs → vite-react-ssg.f66e4ba5.mjs} +45 -9
- package/dist/{types-fa5fe9c2.d.ts → types-82f34756.d.ts} +17 -5
- package/package.json +7 -6
package/README.md
CHANGED
|
@@ -31,7 +31,7 @@ Static-site generation for React on Vite.
|
|
|
31
31
|
import { ViteReactSSG } from 'vite-react-ssg'
|
|
32
32
|
import routes from './App.tsx'
|
|
33
33
|
|
|
34
|
-
export const
|
|
34
|
+
export const createRoot = ViteReactSSG(
|
|
35
35
|
// react-router-dom data routes
|
|
36
36
|
{ routes },
|
|
37
37
|
// function to have custom setups
|
|
@@ -41,6 +41,46 @@ export const createApp = ViteReactSSG(
|
|
|
41
41
|
)
|
|
42
42
|
```
|
|
43
43
|
|
|
44
|
+
```tsx
|
|
45
|
+
// src/App.tsx
|
|
46
|
+
import React from 'react'
|
|
47
|
+
import type { RouteRecord } from 'vite-react-ssg'
|
|
48
|
+
import './App.css'
|
|
49
|
+
|
|
50
|
+
const pages = import.meta.glob<any>('./pages/**/*.tsx')
|
|
51
|
+
|
|
52
|
+
const children: RouteRecord[] = Object.entries(pages).map(([filepath, component]) => {
|
|
53
|
+
let path = filepath.split('/pages')[1]
|
|
54
|
+
path = path.split('.')[0].replace('index', '')
|
|
55
|
+
const entry = `src${filepath.slice(1)}`
|
|
56
|
+
|
|
57
|
+
if (path.endsWith('/')) {
|
|
58
|
+
return {
|
|
59
|
+
index: true,
|
|
60
|
+
Component: React.lazy(component),
|
|
61
|
+
entry,
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
return {
|
|
65
|
+
path,
|
|
66
|
+
Component: React.lazy(component),
|
|
67
|
+
// Used to obtain static resources through manifest
|
|
68
|
+
entry,
|
|
69
|
+
}
|
|
70
|
+
})
|
|
71
|
+
|
|
72
|
+
const Layout = React.lazy(() => import('./Layout'))
|
|
73
|
+
export const routes: RouteRecord[] = [
|
|
74
|
+
{
|
|
75
|
+
path: '/',
|
|
76
|
+
element: <Layout />,
|
|
77
|
+
children,
|
|
78
|
+
// Used to obtain static resources through manifest
|
|
79
|
+
entry: 'src/Layout.tsx',
|
|
80
|
+
},
|
|
81
|
+
]
|
|
82
|
+
```
|
|
83
|
+
|
|
44
84
|
## Critical CSS
|
|
45
85
|
|
|
46
86
|
Vite SSG has built-in support for generating [Critical CSS](https://web.dev/extract-critical-css/) inlined in the HTML via the [`critters`](https://github.com/GoogleChromeLabs/critters) package.
|
|
@@ -121,8 +161,8 @@ export default {
|
|
|
121
161
|
|
|
122
162
|
## Roadmap
|
|
123
163
|
|
|
164
|
+
- [x] Preload assets
|
|
124
165
|
- [ ] SSR under dev
|
|
125
|
-
- [ ] Preload assets
|
|
126
166
|
- [ ] Initial State
|
|
127
167
|
- [ ] Document head
|
|
128
168
|
- [ ] More Client components, such as `<ClientOnly />`
|
package/bin/vite-react-ssg.js
CHANGED
|
File without changes
|
package/dist/index.cjs
CHANGED
|
@@ -25,7 +25,7 @@ function ViteReactSSG(routerOptions, fn, options = {}) {
|
|
|
25
25
|
rootContainer = "#root"
|
|
26
26
|
} = options;
|
|
27
27
|
const isClient = typeof window !== "undefined";
|
|
28
|
-
async function
|
|
28
|
+
async function createRoot(client = false, routePath) {
|
|
29
29
|
const browserRouter = client ? reactRouterDom.createBrowserRouter(routerOptions.routes) : void 0;
|
|
30
30
|
const appRenderCallbacks = [];
|
|
31
31
|
const onSSRAppRendered = client ? () => {
|
|
@@ -63,11 +63,11 @@ function ViteReactSSG(routerOptions, fn, options = {}) {
|
|
|
63
63
|
if (isClient) {
|
|
64
64
|
(async () => {
|
|
65
65
|
const container = typeof rootContainer === "string" ? document.querySelector(rootContainer) : rootContainer;
|
|
66
|
-
const { router } = await
|
|
66
|
+
const { router } = await createRoot(true);
|
|
67
67
|
client.hydrateRoot(container, /* @__PURE__ */ React__default.createElement(reactHelmetAsync.HelmetProvider, null, /* @__PURE__ */ React__default.createElement(SiteMetadataDefaults.SiteMetadataDefaults, null), /* @__PURE__ */ React__default.createElement(reactRouterDom.RouterProvider, { router })));
|
|
68
68
|
})();
|
|
69
69
|
}
|
|
70
|
-
return
|
|
70
|
+
return createRoot;
|
|
71
71
|
}
|
|
72
72
|
|
|
73
73
|
exports.Head = SiteMetadataDefaults.Head;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { R as RouterOptions, V as ViteReactSSGContext, a as ViteReactSSGClientOptions } from './types-
|
|
1
|
+
import { R as RouterOptions, V as ViteReactSSGContext, a as ViteReactSSGClientOptions } from './types-82f34756.js';
|
|
2
|
+
export { I as IndexRouteRecord, N as NonIndexRouteRecord, c as RouteRecord, b as ViteReactSSGOptions } from './types-82f34756.js';
|
|
2
3
|
import { ReactNode } from 'react';
|
|
3
4
|
import { HelmetProps } from 'react-helmet-async';
|
|
4
5
|
import 'critters';
|
|
@@ -11,4 +12,4 @@ declare function Head(props: Props): JSX.Element;
|
|
|
11
12
|
|
|
12
13
|
declare function ViteReactSSG(routerOptions: RouterOptions, fn?: (context: ViteReactSSGContext<true>) => Promise<void> | void, options?: ViteReactSSGClientOptions): (client?: boolean, routePath?: string) => Promise<ViteReactSSGContext<true>>;
|
|
13
14
|
|
|
14
|
-
export { Head, ViteReactSSG };
|
|
15
|
+
export { Head, RouterOptions, ViteReactSSG, ViteReactSSGClientOptions, ViteReactSSGContext };
|
package/dist/index.mjs
CHANGED
|
@@ -20,7 +20,7 @@ function ViteReactSSG(routerOptions, fn, options = {}) {
|
|
|
20
20
|
rootContainer = "#root"
|
|
21
21
|
} = options;
|
|
22
22
|
const isClient = typeof window !== "undefined";
|
|
23
|
-
async function
|
|
23
|
+
async function createRoot(client = false, routePath) {
|
|
24
24
|
const browserRouter = client ? createBrowserRouter(routerOptions.routes) : void 0;
|
|
25
25
|
const appRenderCallbacks = [];
|
|
26
26
|
const onSSRAppRendered = client ? () => {
|
|
@@ -58,11 +58,11 @@ function ViteReactSSG(routerOptions, fn, options = {}) {
|
|
|
58
58
|
if (isClient) {
|
|
59
59
|
(async () => {
|
|
60
60
|
const container = typeof rootContainer === "string" ? document.querySelector(rootContainer) : rootContainer;
|
|
61
|
-
const { router } = await
|
|
61
|
+
const { router } = await createRoot(true);
|
|
62
62
|
hydrateRoot(container, /* @__PURE__ */ React.createElement(HelmetProvider, null, /* @__PURE__ */ React.createElement(SiteMetadataDefaults, null), /* @__PURE__ */ React.createElement(RouterProvider, { router })));
|
|
63
63
|
})();
|
|
64
64
|
}
|
|
65
|
-
return
|
|
65
|
+
return createRoot;
|
|
66
66
|
}
|
|
67
67
|
|
|
68
68
|
export { ViteReactSSG };
|
package/dist/node/cli.cjs
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
const kolorist = require('kolorist');
|
|
4
4
|
const yargs = require('yargs');
|
|
5
5
|
const helpers = require('yargs/helpers');
|
|
6
|
-
const build = require('../shared/vite-react-ssg.
|
|
6
|
+
const build = require('../shared/vite-react-ssg.0e1b881e.cjs');
|
|
7
7
|
require('node:path');
|
|
8
8
|
require('node:module');
|
|
9
9
|
require('fs-extra');
|
package/dist/node/cli.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { gray, bold, red, reset, underline } from 'kolorist';
|
|
2
2
|
import yargs from 'yargs';
|
|
3
3
|
import { hideBin } from 'yargs/helpers';
|
|
4
|
-
import { b as build } from '../shared/vite-react-ssg.
|
|
4
|
+
import { b as build } from '../shared/vite-react-ssg.f66e4ba5.mjs';
|
|
5
5
|
import 'node:path';
|
|
6
6
|
import 'node:module';
|
|
7
7
|
import 'fs-extra';
|
package/dist/node.cjs
CHANGED
package/dist/node.d.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { InlineConfig } from 'vite';
|
|
2
|
-
import { b as ViteReactSSGOptions } from './types-
|
|
2
|
+
import { b as ViteReactSSGOptions } from './types-82f34756.js';
|
|
3
3
|
import 'critters';
|
|
4
|
-
import 'react';
|
|
5
4
|
import 'react-router-dom';
|
|
6
5
|
|
|
7
6
|
declare function build(ssgOptions?: Partial<ViteReactSSGOptions>, viteConfig?: InlineConfig): Promise<void>;
|
package/dist/node.mjs
CHANGED
|
@@ -865,8 +865,17 @@ function getSize(str) {
|
|
|
865
865
|
return `${(str.length / 1024).toFixed(2)} KiB`;
|
|
866
866
|
}
|
|
867
867
|
function routesToPaths(routes) {
|
|
868
|
+
const pathToEntry = {};
|
|
869
|
+
function addEntry(path, entry) {
|
|
870
|
+
if (!entry)
|
|
871
|
+
return;
|
|
872
|
+
if (pathToEntry[path])
|
|
873
|
+
pathToEntry[path].add(entry);
|
|
874
|
+
else
|
|
875
|
+
pathToEntry[path] = /* @__PURE__ */ new Set([entry]);
|
|
876
|
+
}
|
|
868
877
|
if (!routes)
|
|
869
|
-
return ["/"];
|
|
878
|
+
return { paths: ["/"] };
|
|
870
879
|
const paths = /* @__PURE__ */ new Set();
|
|
871
880
|
const getPaths = (routes2, prefix = "") => {
|
|
872
881
|
prefix = prefix.replace(/\/$/g, "");
|
|
@@ -875,13 +884,16 @@ function routesToPaths(routes) {
|
|
|
875
884
|
if (route.path != null) {
|
|
876
885
|
path = prefix && !route.path.startsWith("/") ? `${prefix}${route.path ? `/${route.path}` : ""}` : route.path;
|
|
877
886
|
paths.add(path);
|
|
887
|
+
addEntry(path, route.entry);
|
|
878
888
|
}
|
|
889
|
+
if (route.index)
|
|
890
|
+
addEntry(prefix, route.entry);
|
|
879
891
|
if (Array.isArray(route.children))
|
|
880
892
|
getPaths(route.children, path);
|
|
881
893
|
}
|
|
882
894
|
};
|
|
883
895
|
getPaths(routes);
|
|
884
|
-
return Array.from(paths);
|
|
896
|
+
return { paths: Array.from(paths), pathToEntry };
|
|
885
897
|
}
|
|
886
898
|
|
|
887
899
|
async function getCritters(outDir, options = {}) {
|
|
@@ -1048,6 +1060,7 @@ async function build(ssgOptions = {}, viteConfig = {}) {
|
|
|
1048
1060
|
buildLog("Build for client...");
|
|
1049
1061
|
await vite.build(vite.mergeConfig(viteConfig, {
|
|
1050
1062
|
build: {
|
|
1063
|
+
manifest: true,
|
|
1051
1064
|
ssrManifest: true,
|
|
1052
1065
|
rollupOptions: {
|
|
1053
1066
|
input: {
|
|
@@ -1085,26 +1098,27 @@ async function build(ssgOptions = {}, viteConfig = {}) {
|
|
|
1085
1098
|
const prefix = format === "esm" && process.platform === "win32" ? "file://" : "";
|
|
1086
1099
|
const ext = format === "esm" ? ".mjs" : ".cjs";
|
|
1087
1100
|
const serverEntry = node_path.join(prefix, ssgOut, node_path.parse(ssrEntry).name + ext);
|
|
1088
|
-
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.
|
|
1089
|
-
const {
|
|
1101
|
+
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.0e1b881e.cjs', document.baseURI).href)));
|
|
1102
|
+
const { createRoot, includedRoutes: serverEntryIncludedRoutes } = format === "esm" ? await import(serverEntry) : _require(serverEntry);
|
|
1090
1103
|
const includedRoutes = serverEntryIncludedRoutes || configIncludedRoutes;
|
|
1091
|
-
const { routes } = await
|
|
1092
|
-
|
|
1104
|
+
const { routes } = await createRoot(false);
|
|
1105
|
+
const { paths, pathToEntry } = routesToPaths(routes);
|
|
1106
|
+
let routesPaths = includeAllRoutes ? paths : await includedRoutes(paths, routes || []);
|
|
1093
1107
|
routesPaths = Array.from(new Set(routesPaths));
|
|
1094
1108
|
buildLog("Rendering Pages...", routesPaths.length);
|
|
1095
1109
|
const critters = crittersOptions !== false ? await getCritters(outDir, crittersOptions) : void 0;
|
|
1096
1110
|
if (critters)
|
|
1097
1111
|
console.log(`${kolorist.gray("[vite-react-ssg]")} ${kolorist.blue("Critical CSS generation enabled via `critters`")}`);
|
|
1098
1112
|
const ssrManifest = JSON.parse(await fs__default.readFile(node_path.join(out, "ssr-manifest.json"), "utf-8"));
|
|
1113
|
+
const manifest = JSON.parse(await fs__default.readFile(node_path.join(out, "manifest.json"), "utf-8"));
|
|
1099
1114
|
let indexHTML = await fs__default.readFile(node_path.join(out, "index.html"), "utf-8");
|
|
1100
1115
|
indexHTML = rewriteScripts(indexHTML, script);
|
|
1101
1116
|
const queue = new PQueue({ concurrency });
|
|
1102
1117
|
for (const route of routesPaths) {
|
|
1103
|
-
console.log("\u{1F680} ~ file: build.ts:132 ~ build ~ routesPaths:", routesPaths);
|
|
1104
1118
|
queue.add(async () => {
|
|
1105
1119
|
try {
|
|
1106
|
-
const appCtx = await
|
|
1107
|
-
const {
|
|
1120
|
+
const appCtx = await createRoot(false, route);
|
|
1121
|
+
const { routes: routes2, initialState, triggerOnSSRAppRendered, transformState = SiteMetadataDefaults.serializeState } = appCtx;
|
|
1108
1122
|
const transformedIndexHTML = await onBeforePageRender?.(route, indexHTML, appCtx);
|
|
1109
1123
|
const url = new URL(route, "http://vite-react-ssg.com");
|
|
1110
1124
|
url.search = "";
|
|
@@ -1120,7 +1134,8 @@ async function build(ssgOptions = {}, viteConfig = {}) {
|
|
|
1120
1134
|
initialState: null
|
|
1121
1135
|
});
|
|
1122
1136
|
const jsdom = new JSDOM.JSDOM(renderedHTML);
|
|
1123
|
-
|
|
1137
|
+
const modules = collectModulesForEntrys(manifest, pathToEntry?.[route]);
|
|
1138
|
+
renderPreloadLinks(jsdom.window.document, modules, ssrManifest);
|
|
1124
1139
|
const html = jsdom.serialize();
|
|
1125
1140
|
let transformed = await onPageRendered?.(route, html, appCtx) || html;
|
|
1126
1141
|
if (critters)
|
|
@@ -1219,8 +1234,29 @@ async function formatHtml(html, formatting) {
|
|
|
1219
1234
|
minifyJS: true,
|
|
1220
1235
|
minifyCSS: true
|
|
1221
1236
|
});
|
|
1237
|
+
} else if (formatting === "prettify") {
|
|
1238
|
+
const prettier = (await import('prettier/esm/standalone.mjs')).default;
|
|
1239
|
+
const parserHTML = (await import('prettier/esm/parser-html.mjs')).default;
|
|
1240
|
+
return prettier.format(html, { semi: false, parser: "html", plugins: [parserHTML] });
|
|
1222
1241
|
}
|
|
1223
1242
|
return html;
|
|
1224
1243
|
}
|
|
1244
|
+
function collectModulesForEntrys(manifest, entrys) {
|
|
1245
|
+
const mods = /* @__PURE__ */ new Set();
|
|
1246
|
+
if (!entrys)
|
|
1247
|
+
return mods;
|
|
1248
|
+
for (const entry of entrys)
|
|
1249
|
+
collectModules(manifest, entry, mods);
|
|
1250
|
+
return mods;
|
|
1251
|
+
}
|
|
1252
|
+
function collectModules(manifest, entry, mods = /* @__PURE__ */ new Set()) {
|
|
1253
|
+
if (!entry)
|
|
1254
|
+
return mods;
|
|
1255
|
+
mods.add(entry);
|
|
1256
|
+
manifest[entry]?.dynamicImports?.forEach((item) => {
|
|
1257
|
+
collectModules(manifest, item, mods);
|
|
1258
|
+
});
|
|
1259
|
+
return mods;
|
|
1260
|
+
}
|
|
1225
1261
|
|
|
1226
1262
|
exports.build = build;
|
|
@@ -858,8 +858,17 @@ function getSize(str) {
|
|
|
858
858
|
return `${(str.length / 1024).toFixed(2)} KiB`;
|
|
859
859
|
}
|
|
860
860
|
function routesToPaths(routes) {
|
|
861
|
+
const pathToEntry = {};
|
|
862
|
+
function addEntry(path, entry) {
|
|
863
|
+
if (!entry)
|
|
864
|
+
return;
|
|
865
|
+
if (pathToEntry[path])
|
|
866
|
+
pathToEntry[path].add(entry);
|
|
867
|
+
else
|
|
868
|
+
pathToEntry[path] = /* @__PURE__ */ new Set([entry]);
|
|
869
|
+
}
|
|
861
870
|
if (!routes)
|
|
862
|
-
return ["/"];
|
|
871
|
+
return { paths: ["/"] };
|
|
863
872
|
const paths = /* @__PURE__ */ new Set();
|
|
864
873
|
const getPaths = (routes2, prefix = "") => {
|
|
865
874
|
prefix = prefix.replace(/\/$/g, "");
|
|
@@ -868,13 +877,16 @@ function routesToPaths(routes) {
|
|
|
868
877
|
if (route.path != null) {
|
|
869
878
|
path = prefix && !route.path.startsWith("/") ? `${prefix}${route.path ? `/${route.path}` : ""}` : route.path;
|
|
870
879
|
paths.add(path);
|
|
880
|
+
addEntry(path, route.entry);
|
|
871
881
|
}
|
|
882
|
+
if (route.index)
|
|
883
|
+
addEntry(prefix, route.entry);
|
|
872
884
|
if (Array.isArray(route.children))
|
|
873
885
|
getPaths(route.children, path);
|
|
874
886
|
}
|
|
875
887
|
};
|
|
876
888
|
getPaths(routes);
|
|
877
|
-
return Array.from(paths);
|
|
889
|
+
return { paths: Array.from(paths), pathToEntry };
|
|
878
890
|
}
|
|
879
891
|
|
|
880
892
|
async function getCritters(outDir, options = {}) {
|
|
@@ -1041,6 +1053,7 @@ async function build(ssgOptions = {}, viteConfig = {}) {
|
|
|
1041
1053
|
buildLog("Build for client...");
|
|
1042
1054
|
await build$1(mergeConfig(viteConfig, {
|
|
1043
1055
|
build: {
|
|
1056
|
+
manifest: true,
|
|
1044
1057
|
ssrManifest: true,
|
|
1045
1058
|
rollupOptions: {
|
|
1046
1059
|
input: {
|
|
@@ -1079,25 +1092,26 @@ async function build(ssgOptions = {}, viteConfig = {}) {
|
|
|
1079
1092
|
const ext = format === "esm" ? ".mjs" : ".cjs";
|
|
1080
1093
|
const serverEntry = join(prefix, ssgOut, parse(ssrEntry).name + ext);
|
|
1081
1094
|
const _require = createRequire(import.meta.url);
|
|
1082
|
-
const {
|
|
1095
|
+
const { createRoot, includedRoutes: serverEntryIncludedRoutes } = format === "esm" ? await import(serverEntry) : _require(serverEntry);
|
|
1083
1096
|
const includedRoutes = serverEntryIncludedRoutes || configIncludedRoutes;
|
|
1084
|
-
const { routes } = await
|
|
1085
|
-
|
|
1097
|
+
const { routes } = await createRoot(false);
|
|
1098
|
+
const { paths, pathToEntry } = routesToPaths(routes);
|
|
1099
|
+
let routesPaths = includeAllRoutes ? paths : await includedRoutes(paths, routes || []);
|
|
1086
1100
|
routesPaths = Array.from(new Set(routesPaths));
|
|
1087
1101
|
buildLog("Rendering Pages...", routesPaths.length);
|
|
1088
1102
|
const critters = crittersOptions !== false ? await getCritters(outDir, crittersOptions) : void 0;
|
|
1089
1103
|
if (critters)
|
|
1090
1104
|
console.log(`${gray("[vite-react-ssg]")} ${blue("Critical CSS generation enabled via `critters`")}`);
|
|
1091
1105
|
const ssrManifest = JSON.parse(await fs.readFile(join(out, "ssr-manifest.json"), "utf-8"));
|
|
1106
|
+
const manifest = JSON.parse(await fs.readFile(join(out, "manifest.json"), "utf-8"));
|
|
1092
1107
|
let indexHTML = await fs.readFile(join(out, "index.html"), "utf-8");
|
|
1093
1108
|
indexHTML = rewriteScripts(indexHTML, script);
|
|
1094
1109
|
const queue = new PQueue({ concurrency });
|
|
1095
1110
|
for (const route of routesPaths) {
|
|
1096
|
-
console.log("\u{1F680} ~ file: build.ts:132 ~ build ~ routesPaths:", routesPaths);
|
|
1097
1111
|
queue.add(async () => {
|
|
1098
1112
|
try {
|
|
1099
|
-
const appCtx = await
|
|
1100
|
-
const {
|
|
1113
|
+
const appCtx = await createRoot(false, route);
|
|
1114
|
+
const { routes: routes2, initialState, triggerOnSSRAppRendered, transformState = serializeState } = appCtx;
|
|
1101
1115
|
const transformedIndexHTML = await onBeforePageRender?.(route, indexHTML, appCtx);
|
|
1102
1116
|
const url = new URL(route, "http://vite-react-ssg.com");
|
|
1103
1117
|
url.search = "";
|
|
@@ -1113,7 +1127,8 @@ async function build(ssgOptions = {}, viteConfig = {}) {
|
|
|
1113
1127
|
initialState: null
|
|
1114
1128
|
});
|
|
1115
1129
|
const jsdom = new JSDOM(renderedHTML);
|
|
1116
|
-
|
|
1130
|
+
const modules = collectModulesForEntrys(manifest, pathToEntry?.[route]);
|
|
1131
|
+
renderPreloadLinks(jsdom.window.document, modules, ssrManifest);
|
|
1117
1132
|
const html = jsdom.serialize();
|
|
1118
1133
|
let transformed = await onPageRendered?.(route, html, appCtx) || html;
|
|
1119
1134
|
if (critters)
|
|
@@ -1212,8 +1227,29 @@ async function formatHtml(html, formatting) {
|
|
|
1212
1227
|
minifyJS: true,
|
|
1213
1228
|
minifyCSS: true
|
|
1214
1229
|
});
|
|
1230
|
+
} else if (formatting === "prettify") {
|
|
1231
|
+
const prettier = (await import('prettier/esm/standalone.mjs')).default;
|
|
1232
|
+
const parserHTML = (await import('prettier/esm/parser-html.mjs')).default;
|
|
1233
|
+
return prettier.format(html, { semi: false, parser: "html", plugins: [parserHTML] });
|
|
1215
1234
|
}
|
|
1216
1235
|
return html;
|
|
1217
1236
|
}
|
|
1237
|
+
function collectModulesForEntrys(manifest, entrys) {
|
|
1238
|
+
const mods = /* @__PURE__ */ new Set();
|
|
1239
|
+
if (!entrys)
|
|
1240
|
+
return mods;
|
|
1241
|
+
for (const entry of entrys)
|
|
1242
|
+
collectModules(manifest, entry, mods);
|
|
1243
|
+
return mods;
|
|
1244
|
+
}
|
|
1245
|
+
function collectModules(manifest, entry, mods = /* @__PURE__ */ new Set()) {
|
|
1246
|
+
if (!entry)
|
|
1247
|
+
return mods;
|
|
1248
|
+
mods.add(entry);
|
|
1249
|
+
manifest[entry]?.dynamicImports?.forEach((item) => {
|
|
1250
|
+
collectModules(manifest, item, mods);
|
|
1251
|
+
});
|
|
1252
|
+
return mods;
|
|
1253
|
+
}
|
|
1218
1254
|
|
|
1219
1255
|
export { build as b };
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { Options } from 'critters';
|
|
2
|
-
import {
|
|
3
|
-
import { RouteObject, createBrowserRouter } from 'react-router-dom';
|
|
2
|
+
import { NonIndexRouteObject, IndexRouteObject, createBrowserRouter } from 'react-router-dom';
|
|
4
3
|
|
|
5
4
|
type Router = ReturnType<typeof createBrowserRouter>;
|
|
6
5
|
interface ViteReactSSGOptions {
|
|
@@ -31,6 +30,8 @@ interface ViteReactSSGOptions {
|
|
|
31
30
|
/**
|
|
32
31
|
* Apply formatter to the generated index file.
|
|
33
32
|
*
|
|
33
|
+
* **It will cause Hydration Failed.**
|
|
34
|
+
*
|
|
34
35
|
* @default 'none'
|
|
35
36
|
*/
|
|
36
37
|
formatting?: 'minify' | 'prettify' | 'none';
|
|
@@ -103,7 +104,6 @@ interface ViteReactSSGOptions {
|
|
|
103
104
|
concurrency?: number;
|
|
104
105
|
}
|
|
105
106
|
interface ViteReactSSGContext<HasRouter extends boolean = true> {
|
|
106
|
-
app?: ReactNode;
|
|
107
107
|
router?: HasRouter extends true ? Router : undefined;
|
|
108
108
|
routes: HasRouter extends true ? Readonly<RouteRecord[]> : undefined;
|
|
109
109
|
routerOptions: RouterOptions;
|
|
@@ -127,7 +127,19 @@ interface ViteReactSSGClientOptions {
|
|
|
127
127
|
*/
|
|
128
128
|
rootContainer?: string | Element;
|
|
129
129
|
}
|
|
130
|
-
|
|
130
|
+
interface CommonRouteOptions {
|
|
131
|
+
/**
|
|
132
|
+
* Used to obtain static resources through manifest
|
|
133
|
+
*
|
|
134
|
+
* @example `src/pages/home.tsx
|
|
135
|
+
*/
|
|
136
|
+
entry?: string;
|
|
137
|
+
}
|
|
138
|
+
type NonIndexRouteRecord = Omit<NonIndexRouteObject, 'children'> & {
|
|
139
|
+
children?: RouteRecord[];
|
|
140
|
+
} & CommonRouteOptions;
|
|
141
|
+
type IndexRouteRecord = IndexRouteObject & CommonRouteOptions;
|
|
142
|
+
type RouteRecord = NonIndexRouteRecord | IndexRouteRecord;
|
|
131
143
|
interface RouterOptions {
|
|
132
144
|
routes: RouteRecord[];
|
|
133
145
|
createFetchRequest?: <T>(req: T) => Request;
|
|
@@ -138,4 +150,4 @@ declare module 'vite' {
|
|
|
138
150
|
}
|
|
139
151
|
}
|
|
140
152
|
|
|
141
|
-
export { RouterOptions as R, ViteReactSSGContext as V, ViteReactSSGClientOptions as a, ViteReactSSGOptions as b };
|
|
153
|
+
export { IndexRouteRecord as I, NonIndexRouteRecord as N, RouterOptions as R, ViteReactSSGContext as V, ViteReactSSGClientOptions as a, ViteReactSSGOptions as b, RouteRecord as c };
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vite-react-ssg",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.2",
|
|
5
5
|
"packageManager": "pnpm@8.6.6",
|
|
6
6
|
"description": "",
|
|
7
7
|
"author": "Riri <Daydreamerriri@outlook.com>",
|
|
@@ -80,23 +80,24 @@
|
|
|
80
80
|
"html5parser": "^2.0.2",
|
|
81
81
|
"jsdom": "^22.1.0",
|
|
82
82
|
"kolorist": "^1.8.0",
|
|
83
|
+
"prettier": "^3.0.0",
|
|
83
84
|
"react-helmet-async": "^1.3.0",
|
|
84
85
|
"yargs": "^17.7.2"
|
|
85
86
|
},
|
|
86
87
|
"devDependencies": {
|
|
87
|
-
"@ririd/eslint-config": "0.
|
|
88
|
+
"@ririd/eslint-config": "0.6.0",
|
|
88
89
|
"@types/fs-extra": "^11.0.1",
|
|
89
90
|
"@types/html-minifier": "^4.0.2",
|
|
90
91
|
"@types/jsdom": "^21.1.1",
|
|
91
92
|
"@types/node": "^18.15.11",
|
|
93
|
+
"@types/prettier": "^2.7.3",
|
|
92
94
|
"@types/react": "^18.2.14",
|
|
93
95
|
"@types/react-dom": "^18.2.6",
|
|
94
|
-
"@types/react-helmet-async": "^1.0.3",
|
|
95
96
|
"@types/yargs": "^17.0.24",
|
|
96
97
|
"bumpp": "^9.1.0",
|
|
97
98
|
"critters": "^0.0.19",
|
|
98
|
-
"eslint": "^8.
|
|
99
|
-
"esno": "^0.
|
|
99
|
+
"eslint": "^8.45.0",
|
|
100
|
+
"esno": "^0.17.0",
|
|
100
101
|
"p-queue": "^7.3.4",
|
|
101
102
|
"react": "^18.2.0",
|
|
102
103
|
"react-dom": "^18.2.0",
|
|
@@ -105,7 +106,7 @@
|
|
|
105
106
|
"simple-git-hooks": "^2.8.1",
|
|
106
107
|
"typescript": "5.1.6",
|
|
107
108
|
"unbuild": "^1.2.1",
|
|
108
|
-
"vite": "^4.
|
|
109
|
+
"vite": "^4.4.0",
|
|
109
110
|
"vite-plugin-pwa": "^0.16.4",
|
|
110
111
|
"vitest": "0.33.0"
|
|
111
112
|
}
|