vitrify 0.19.1 → 0.20.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/dist/frameworks/vue/fastify-ssr-plugin.js +53 -68
- package/dist/frameworks/vue/prerender.js +11 -13
- package/dist/index.js +1 -0
- package/dist/types/frameworks/vue/fastify-ssr-plugin.d.ts +18 -4
- package/package.json +5 -5
- package/src/node/frameworks/vue/fastify-ssr-plugin.ts +101 -87
- package/src/node/frameworks/vue/prerender.ts +11 -15
- package/src/node/index.ts +1 -0
- package/src/vite/vue/csr/app.ts +0 -1
- package/src/vite/vue/main.ts +1 -2
- package/src/vite/vue/ssr/entry-server.ts +29 -9
- package/src/vite/vue/ssr/fastify-ssr-plugin.ts +5 -2
|
@@ -32,11 +32,6 @@ const fastifySsrPlugin = async (fastify, options) => {
|
|
|
32
32
|
try {
|
|
33
33
|
const url = req.raw.url?.replace(options.baseUrl, '/');
|
|
34
34
|
const provide = options.provide ? await options.provide(req, res) : {};
|
|
35
|
-
const ssrContext = {
|
|
36
|
-
req,
|
|
37
|
-
res,
|
|
38
|
-
provide
|
|
39
|
-
};
|
|
40
35
|
let template = readFileSync(new URL('index.html', frameworkDir)).toString();
|
|
41
36
|
template = await vite.transformIndexHtml(url, template);
|
|
42
37
|
const entryUrl = fileURLToPath(new URL('ssr/entry-server.ts', frameworkDir));
|
|
@@ -49,39 +44,16 @@ const fastifySsrPlugin = async (fastify, options) => {
|
|
|
49
44
|
catch (e) {
|
|
50
45
|
manifest = {};
|
|
51
46
|
}
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
<script>
|
|
63
|
-
__INITIAL_STATE__ = '${JSON.stringify(ssrContext.initialState)}'
|
|
64
|
-
</script>`;
|
|
65
|
-
const renderHtml = (html) => {
|
|
66
|
-
return appendToHead(preloadLinks, appendToBody(initialStateScript, addOrReplaceAppDiv(appHtml, html)));
|
|
67
|
-
};
|
|
68
|
-
let html = renderHtml(template);
|
|
69
|
-
// let html = template
|
|
70
|
-
// .replace(`<!--app-html-->`, appHtml)
|
|
71
|
-
// .replace('<!--product-name-->', options.productName || 'Product name')
|
|
72
|
-
// // .replace('<!--dev-ssr-css-->', css)
|
|
73
|
-
// .replace(
|
|
74
|
-
// '<!--initial-state-->',
|
|
75
|
-
// `<script>
|
|
76
|
-
// __INITIAL_STATE__ = '${JSON.stringify(ssrContext.initialState)}'
|
|
77
|
-
// </script>`
|
|
78
|
-
// )
|
|
79
|
-
// html = appendToHead(preloadLinks, html)
|
|
80
|
-
if (options.onRendered?.length) {
|
|
81
|
-
for (const ssrFunction of options.onRendered) {
|
|
82
|
-
html = ssrFunction(html, ssrContext);
|
|
83
|
-
}
|
|
84
|
-
}
|
|
47
|
+
const html = await renderHtml({
|
|
48
|
+
request: req,
|
|
49
|
+
reply: res,
|
|
50
|
+
url: url ?? '/',
|
|
51
|
+
provide,
|
|
52
|
+
onRendered: options.onRendered,
|
|
53
|
+
template,
|
|
54
|
+
manifest,
|
|
55
|
+
render
|
|
56
|
+
});
|
|
85
57
|
res.code(200);
|
|
86
58
|
res.type('text/html');
|
|
87
59
|
res.send(html);
|
|
@@ -108,42 +80,55 @@ const fastifySsrPlugin = async (fastify, options) => {
|
|
|
108
80
|
fastify.get(`${options.baseUrl}*`, async (req, res) => {
|
|
109
81
|
const url = req.raw.url?.replace(options.baseUrl, '/');
|
|
110
82
|
const provide = options.provide ? await options.provide(req, res) : {};
|
|
111
|
-
const ssrContext = {
|
|
112
|
-
req,
|
|
113
|
-
res,
|
|
114
|
-
provide
|
|
115
|
-
};
|
|
116
83
|
const template = readFileSync(fileURLToPath(new URL('./dist/ssr/client/index.html', options.appDir))).toString();
|
|
117
84
|
const manifest = JSON.parse(readFileSync(new URL('./dist/ssr/client/.vite/ssr-manifest.json', options.appDir)).toString());
|
|
118
85
|
const render = (await import(fileURLToPath(new URL('./dist/ssr/server/entry-server.mjs', options.appDir)))).render;
|
|
119
|
-
const
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
};
|
|
130
|
-
let html = renderHtml(template);
|
|
131
|
-
// let html = template.replace(`<!--app-html-->`, appHtml).replace(
|
|
132
|
-
// '<!--initial-state-->',
|
|
133
|
-
// `<script>
|
|
134
|
-
// __INITIAL_STATE__ = '${JSON.stringify(ssrContext.initialState)}'
|
|
135
|
-
// </script>`
|
|
136
|
-
// )
|
|
137
|
-
// html = appendToHead(preloadLinks, html)
|
|
138
|
-
if (options.onRendered?.length) {
|
|
139
|
-
for (const ssrFunction of options.onRendered) {
|
|
140
|
-
html = ssrFunction(html, ssrContext);
|
|
141
|
-
}
|
|
142
|
-
}
|
|
86
|
+
const onRendered = (await import(fileURLToPath(new URL('./dist/ssr/server/virtual_vitrify-hooks.mjs', options.appDir)))).onRendered;
|
|
87
|
+
const html = await renderHtml({
|
|
88
|
+
request: req,
|
|
89
|
+
reply: res,
|
|
90
|
+
url: url ?? '/',
|
|
91
|
+
provide,
|
|
92
|
+
onRendered,
|
|
93
|
+
template,
|
|
94
|
+
manifest,
|
|
95
|
+
render
|
|
96
|
+
});
|
|
143
97
|
res.code(200);
|
|
144
98
|
res.type('text/html');
|
|
145
99
|
res.send(html);
|
|
146
100
|
});
|
|
147
101
|
}
|
|
148
102
|
};
|
|
149
|
-
|
|
103
|
+
const renderTemplate = ({ template, initialStateScript, appHtml, preloadLinks }) => {
|
|
104
|
+
return appendToHead(preloadLinks, appendToBody(initialStateScript, addOrReplaceAppDiv(appHtml, template)));
|
|
105
|
+
};
|
|
106
|
+
const renderHtml = async (options) => {
|
|
107
|
+
const ssrContext = {
|
|
108
|
+
req: options.request,
|
|
109
|
+
res: options.reply,
|
|
110
|
+
provide: options.provide
|
|
111
|
+
};
|
|
112
|
+
const onRendered = options.onRendered ?? [];
|
|
113
|
+
const [appHtml, preloadLinks] = await options.render(options.url, options.manifest, ssrContext);
|
|
114
|
+
if (!ssrContext.initialState)
|
|
115
|
+
ssrContext.initialState = {};
|
|
116
|
+
ssrContext.initialState.provide = options.provide;
|
|
117
|
+
const initialStateScript = `
|
|
118
|
+
<script>
|
|
119
|
+
__INITIAL_STATE__ = '${JSON.stringify(ssrContext.initialState)}'
|
|
120
|
+
</script>`;
|
|
121
|
+
let html = renderTemplate({
|
|
122
|
+
template: options.template,
|
|
123
|
+
appHtml,
|
|
124
|
+
initialStateScript,
|
|
125
|
+
preloadLinks
|
|
126
|
+
});
|
|
127
|
+
if (onRendered?.length) {
|
|
128
|
+
for (const ssrFunction of onRendered) {
|
|
129
|
+
html = ssrFunction(html, ssrContext);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
return html;
|
|
133
|
+
};
|
|
134
|
+
export { fastifySsrPlugin, renderHtml };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { existsSync, promises as fs, mkdirSync } from 'fs';
|
|
2
2
|
import { routesToPaths } from '../../helpers/routes.js';
|
|
3
|
-
import {
|
|
3
|
+
import { renderHtml } from './fastify-ssr-plugin.js';
|
|
4
4
|
export const prerender = async ({ outDir, templatePath, manifestPath, entryServerPath, onRendered }) => {
|
|
5
5
|
const promises = [];
|
|
6
6
|
const template = (await fs.readFile(templatePath)).toString();
|
|
@@ -22,18 +22,16 @@ export const prerender = async ({ outDir, templatePath, manifestPath, entryServe
|
|
|
22
22
|
}
|
|
23
23
|
const filename = (url.endsWith('/') ? 'index' : url.replace(/^\//g, '')) + '.html';
|
|
24
24
|
console.log(`Generating ${filename}`);
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
}
|
|
36
|
-
}
|
|
25
|
+
let html = await renderHtml({
|
|
26
|
+
url,
|
|
27
|
+
manifest,
|
|
28
|
+
provide: {},
|
|
29
|
+
render,
|
|
30
|
+
request: { headers: {}, url },
|
|
31
|
+
reply: {},
|
|
32
|
+
template,
|
|
33
|
+
onRendered
|
|
34
|
+
});
|
|
37
35
|
html = await beasties.process(html);
|
|
38
36
|
promises.push(fs.writeFile(outDir + filename, html, 'utf-8'));
|
|
39
37
|
}
|
package/dist/index.js
CHANGED
|
@@ -528,6 +528,7 @@ export const baseConfig = async ({ ssr, appDir, publicDir, base = '/', command =
|
|
|
528
528
|
input: [
|
|
529
529
|
fileURLToPath(new URL('ssr/entry-server.ts', frameworkDir)),
|
|
530
530
|
fileURLToPath(new URL('ssr/prerender.ts', frameworkDir)),
|
|
531
|
+
fileURLToPath(new URL('ssr/fastify-ssr-plugin.ts', frameworkDir)),
|
|
531
532
|
fileURLToPath(new URL('ssr/server.ts', frameworkDir))
|
|
532
533
|
],
|
|
533
534
|
external,
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import type { FastifyPluginAsync, FastifyRequest, FastifyReply } from 'fastify';
|
|
2
2
|
import type { ViteDevServer } from 'vite';
|
|
3
3
|
import type { OnRenderedHook } from '../../vitrify-config.js';
|
|
4
|
+
type ProvideFn = (req: FastifyRequest, res: FastifyReply) => Promise<Record<string, unknown | {
|
|
5
|
+
value: unknown;
|
|
6
|
+
}>>;
|
|
4
7
|
export interface FastifySsrOptions {
|
|
5
8
|
baseUrl?: string;
|
|
6
|
-
provide?:
|
|
7
|
-
value: unknown;
|
|
8
|
-
}>>;
|
|
9
|
+
provide?: ProvideFn;
|
|
9
10
|
vitrifyDir?: URL;
|
|
10
11
|
vite?: ViteDevServer;
|
|
11
12
|
onRendered?: OnRenderedHook[];
|
|
@@ -15,5 +16,18 @@ export interface FastifySsrOptions {
|
|
|
15
16
|
host?: string;
|
|
16
17
|
}
|
|
17
18
|
declare const fastifySsrPlugin: FastifyPluginAsync<FastifySsrOptions>;
|
|
18
|
-
|
|
19
|
+
declare const renderHtml: (options: {
|
|
20
|
+
url: string;
|
|
21
|
+
request: FastifyRequest | {
|
|
22
|
+
headers: Record<string, unknown>;
|
|
23
|
+
url: string;
|
|
24
|
+
};
|
|
25
|
+
reply: FastifyReply | Record<string, unknown>;
|
|
26
|
+
provide: Record<string, unknown>;
|
|
27
|
+
onRendered?: OnRenderedHook[];
|
|
28
|
+
template: string;
|
|
29
|
+
manifest: Record<string, unknown>;
|
|
30
|
+
render: any;
|
|
31
|
+
}) => Promise<string>;
|
|
32
|
+
export { fastifySsrPlugin, renderHtml };
|
|
19
33
|
export type FastifySsrPlugin = typeof fastifySsrPlugin;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vitrify",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.20.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"author": "Stefan van Herwijnen",
|
|
6
6
|
"description": "Vite as your Full Stack development tool",
|
|
@@ -91,7 +91,7 @@
|
|
|
91
91
|
"@types/ws": "^8.18.1",
|
|
92
92
|
"@unocss/preset-icons": "^66.0.0",
|
|
93
93
|
"@vue/runtime-core": "^3.5.13",
|
|
94
|
-
"beasties": "^0.3.
|
|
94
|
+
"beasties": "^0.3.2",
|
|
95
95
|
"css": "^3.0.0",
|
|
96
96
|
"css-to-tailwind-translator": "^1.2.8",
|
|
97
97
|
"quasar": "^2.18.1",
|
|
@@ -101,9 +101,9 @@
|
|
|
101
101
|
"vue-router": "^4.5.0"
|
|
102
102
|
},
|
|
103
103
|
"peerDependencies": {
|
|
104
|
-
"@fastify/static": "^8.1.
|
|
105
|
-
"fastify": "^5.2.
|
|
106
|
-
"quasar": "^2.
|
|
104
|
+
"@fastify/static": "^8.1.1",
|
|
105
|
+
"fastify": "^5.2.2",
|
|
106
|
+
"quasar": "^2.18.1",
|
|
107
107
|
"vue": "^3.5.13",
|
|
108
108
|
"vue-router": "^4.5.0"
|
|
109
109
|
},
|
|
@@ -9,12 +9,15 @@ import {
|
|
|
9
9
|
} from '../../helpers/utils.js'
|
|
10
10
|
import type { ViteDevServer } from 'vite'
|
|
11
11
|
import type { OnRenderedHook } from '../../vitrify-config.js'
|
|
12
|
+
|
|
13
|
+
type ProvideFn = (
|
|
14
|
+
req: FastifyRequest,
|
|
15
|
+
res: FastifyReply
|
|
16
|
+
) => Promise<Record<string, unknown | { value: unknown }>>
|
|
17
|
+
|
|
12
18
|
export interface FastifySsrOptions {
|
|
13
19
|
baseUrl?: string
|
|
14
|
-
provide?:
|
|
15
|
-
req: FastifyRequest,
|
|
16
|
-
res: FastifyReply
|
|
17
|
-
) => Promise<Record<string, unknown | { value: unknown }>>
|
|
20
|
+
provide?: ProvideFn
|
|
18
21
|
vitrifyDir?: URL
|
|
19
22
|
vite?: ViteDevServer
|
|
20
23
|
// frameworkDir?: URL
|
|
@@ -66,12 +69,6 @@ const fastifySsrPlugin: FastifyPluginAsync<FastifySsrOptions> = async (
|
|
|
66
69
|
const url = req.raw.url?.replace(options.baseUrl!, '/')
|
|
67
70
|
const provide = options.provide ? await options.provide(req, res) : {}
|
|
68
71
|
|
|
69
|
-
const ssrContext: Record<string, any> = {
|
|
70
|
-
req,
|
|
71
|
-
res,
|
|
72
|
-
provide
|
|
73
|
-
}
|
|
74
|
-
|
|
75
72
|
let template = readFileSync(
|
|
76
73
|
new URL('index.html', frameworkDir)
|
|
77
74
|
).toString()
|
|
@@ -90,47 +87,16 @@ const fastifySsrPlugin: FastifyPluginAsync<FastifySsrOptions> = async (
|
|
|
90
87
|
manifest = {}
|
|
91
88
|
}
|
|
92
89
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
const initialStateScript = `
|
|
105
|
-
<script>
|
|
106
|
-
__INITIAL_STATE__ = '${JSON.stringify(ssrContext.initialState)}'
|
|
107
|
-
</script>`
|
|
108
|
-
const renderHtml = (html: string) => {
|
|
109
|
-
return appendToHead(
|
|
110
|
-
preloadLinks,
|
|
111
|
-
appendToBody(initialStateScript, addOrReplaceAppDiv(appHtml, html))
|
|
112
|
-
)
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
let html = renderHtml(template)
|
|
116
|
-
// let html = template
|
|
117
|
-
// .replace(`<!--app-html-->`, appHtml)
|
|
118
|
-
// .replace('<!--product-name-->', options.productName || 'Product name')
|
|
119
|
-
// // .replace('<!--dev-ssr-css-->', css)
|
|
120
|
-
// .replace(
|
|
121
|
-
// '<!--initial-state-->',
|
|
122
|
-
// `<script>
|
|
123
|
-
// __INITIAL_STATE__ = '${JSON.stringify(ssrContext.initialState)}'
|
|
124
|
-
// </script>`
|
|
125
|
-
// )
|
|
126
|
-
|
|
127
|
-
// html = appendToHead(preloadLinks, html)
|
|
128
|
-
|
|
129
|
-
if (options.onRendered?.length) {
|
|
130
|
-
for (const ssrFunction of options.onRendered) {
|
|
131
|
-
html = ssrFunction(html, ssrContext)
|
|
132
|
-
}
|
|
133
|
-
}
|
|
90
|
+
const html = await renderHtml({
|
|
91
|
+
request: req,
|
|
92
|
+
reply: res,
|
|
93
|
+
url: url ?? '/',
|
|
94
|
+
provide,
|
|
95
|
+
onRendered: options.onRendered,
|
|
96
|
+
template,
|
|
97
|
+
manifest,
|
|
98
|
+
render
|
|
99
|
+
})
|
|
134
100
|
|
|
135
101
|
res.code(200)
|
|
136
102
|
res.type('text/html')
|
|
@@ -156,11 +122,6 @@ const fastifySsrPlugin: FastifyPluginAsync<FastifySsrOptions> = async (
|
|
|
156
122
|
fastify.get(`${options.baseUrl}*`, async (req, res) => {
|
|
157
123
|
const url = req.raw.url?.replace(options.baseUrl!, '/')
|
|
158
124
|
const provide = options.provide ? await options.provide(req, res) : {}
|
|
159
|
-
const ssrContext: Record<string, any> = {
|
|
160
|
-
req,
|
|
161
|
-
res,
|
|
162
|
-
provide
|
|
163
|
-
}
|
|
164
125
|
|
|
165
126
|
const template = readFileSync(
|
|
166
127
|
fileURLToPath(new URL('./dist/ssr/client/index.html', options.appDir))
|
|
@@ -177,46 +138,99 @@ const fastifySsrPlugin: FastifyPluginAsync<FastifySsrOptions> = async (
|
|
|
177
138
|
)
|
|
178
139
|
)
|
|
179
140
|
).render
|
|
141
|
+
const onRendered = (
|
|
142
|
+
await import(
|
|
143
|
+
fileURLToPath(
|
|
144
|
+
new URL(
|
|
145
|
+
'./dist/ssr/server/virtual_vitrify-hooks.mjs',
|
|
146
|
+
options.appDir
|
|
147
|
+
)
|
|
148
|
+
)
|
|
149
|
+
)
|
|
150
|
+
).onRendered
|
|
151
|
+
|
|
152
|
+
const html = await renderHtml({
|
|
153
|
+
request: req,
|
|
154
|
+
reply: res,
|
|
155
|
+
url: url ?? '/',
|
|
156
|
+
provide,
|
|
157
|
+
onRendered,
|
|
158
|
+
template,
|
|
159
|
+
manifest,
|
|
160
|
+
render
|
|
161
|
+
})
|
|
180
162
|
|
|
181
|
-
|
|
163
|
+
res.code(200)
|
|
164
|
+
res.type('text/html')
|
|
165
|
+
res.send(html)
|
|
166
|
+
})
|
|
167
|
+
}
|
|
168
|
+
}
|
|
182
169
|
|
|
183
|
-
|
|
184
|
-
|
|
170
|
+
const renderTemplate = ({
|
|
171
|
+
template,
|
|
172
|
+
initialStateScript,
|
|
173
|
+
appHtml,
|
|
174
|
+
preloadLinks
|
|
175
|
+
}: {
|
|
176
|
+
template: string
|
|
177
|
+
initialStateScript: string
|
|
178
|
+
appHtml: string
|
|
179
|
+
preloadLinks: string
|
|
180
|
+
}) => {
|
|
181
|
+
return appendToHead(
|
|
182
|
+
preloadLinks,
|
|
183
|
+
appendToBody(initialStateScript, addOrReplaceAppDiv(appHtml, template))
|
|
184
|
+
)
|
|
185
|
+
}
|
|
185
186
|
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
187
|
+
const renderHtml = async (options: {
|
|
188
|
+
url: string
|
|
189
|
+
request: FastifyRequest | { headers: Record<string, unknown>; url: string }
|
|
190
|
+
reply: FastifyReply | Record<string, unknown>
|
|
191
|
+
provide: Record<string, unknown>
|
|
192
|
+
onRendered?: OnRenderedHook[]
|
|
193
|
+
template: string
|
|
194
|
+
manifest: Record<string, unknown>
|
|
195
|
+
render: any
|
|
196
|
+
}) => {
|
|
197
|
+
const ssrContext: Record<string, any> = {
|
|
198
|
+
req: options.request,
|
|
199
|
+
res: options.reply,
|
|
200
|
+
provide: options.provide
|
|
201
|
+
}
|
|
196
202
|
|
|
197
|
-
|
|
203
|
+
const onRendered = options.onRendered ?? []
|
|
198
204
|
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
// )
|
|
205
|
+
const [appHtml, preloadLinks] = await options.render(
|
|
206
|
+
options.url,
|
|
207
|
+
options.manifest,
|
|
208
|
+
ssrContext
|
|
209
|
+
)
|
|
205
210
|
|
|
206
|
-
|
|
211
|
+
if (!ssrContext.initialState) ssrContext.initialState = {}
|
|
212
|
+
ssrContext.initialState.provide = options.provide
|
|
207
213
|
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
}
|
|
214
|
+
const initialStateScript = `
|
|
215
|
+
<script>
|
|
216
|
+
__INITIAL_STATE__ = '${JSON.stringify(ssrContext.initialState)}'
|
|
217
|
+
</script>`
|
|
213
218
|
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
219
|
+
let html = renderTemplate({
|
|
220
|
+
template: options.template,
|
|
221
|
+
appHtml,
|
|
222
|
+
initialStateScript,
|
|
223
|
+
preloadLinks
|
|
224
|
+
})
|
|
225
|
+
|
|
226
|
+
if (onRendered?.length) {
|
|
227
|
+
for (const ssrFunction of onRendered) {
|
|
228
|
+
html = ssrFunction(html, ssrContext)
|
|
229
|
+
}
|
|
218
230
|
}
|
|
231
|
+
|
|
232
|
+
return html
|
|
219
233
|
}
|
|
220
234
|
|
|
221
|
-
export { fastifySsrPlugin }
|
|
235
|
+
export { fastifySsrPlugin, renderHtml }
|
|
222
236
|
export type FastifySsrPlugin = typeof fastifySsrPlugin
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { existsSync, promises as fs, mkdirSync } from 'fs'
|
|
2
2
|
import type { OnRenderedHook } from 'src/node/vitrify-config.js'
|
|
3
3
|
import { routesToPaths } from '../../helpers/routes.js'
|
|
4
|
-
import {
|
|
4
|
+
import { renderHtml } from './fastify-ssr-plugin.js'
|
|
5
5
|
|
|
6
6
|
export const prerender = async ({
|
|
7
7
|
outDir,
|
|
@@ -44,21 +44,17 @@ export const prerender = async ({
|
|
|
44
44
|
const filename =
|
|
45
45
|
(url.endsWith('/') ? 'index' : url.replace(/^\//g, '')) + '.html'
|
|
46
46
|
console.log(`Generating ${filename}`)
|
|
47
|
-
const ssrContext = {
|
|
48
|
-
req: { headers: {}, url },
|
|
49
|
-
res: {}
|
|
50
|
-
}
|
|
51
|
-
const [appHtml, preloadLinks] = await render(url, manifest, ssrContext)
|
|
52
|
-
|
|
53
|
-
let html = addOrReplaceAppDiv(appHtml, template)
|
|
54
|
-
html = appendToHead(preloadLinks, html)
|
|
55
|
-
|
|
56
|
-
if (onRendered?.length) {
|
|
57
|
-
for (const ssrFunction of onRendered) {
|
|
58
|
-
html = ssrFunction(html, ssrContext)
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
47
|
|
|
48
|
+
let html = await renderHtml({
|
|
49
|
+
url,
|
|
50
|
+
manifest,
|
|
51
|
+
provide: {},
|
|
52
|
+
render,
|
|
53
|
+
request: { headers: {}, url },
|
|
54
|
+
reply: {},
|
|
55
|
+
template,
|
|
56
|
+
onRendered
|
|
57
|
+
})
|
|
62
58
|
html = await beasties.process(html)
|
|
63
59
|
|
|
64
60
|
promises.push(fs.writeFile(outDir + filename, html, 'utf-8'))
|
package/src/node/index.ts
CHANGED
|
@@ -652,6 +652,7 @@ export const baseConfig = async ({
|
|
|
652
652
|
input: [
|
|
653
653
|
fileURLToPath(new URL('ssr/entry-server.ts', frameworkDir)),
|
|
654
654
|
fileURLToPath(new URL('ssr/prerender.ts', frameworkDir)),
|
|
655
|
+
fileURLToPath(new URL('ssr/fastify-ssr-plugin.ts', frameworkDir)),
|
|
655
656
|
fileURLToPath(new URL('ssr/server.ts', frameworkDir))
|
|
656
657
|
],
|
|
657
658
|
external,
|
package/src/vite/vue/csr/app.ts
CHANGED
|
@@ -3,7 +3,6 @@ import { getAppDir } from '../../../node/app-urls.js'
|
|
|
3
3
|
// import { setup } from 'virtual:fastify-setup'
|
|
4
4
|
import { onSetup } from 'virtual:vitrify-hooks'
|
|
5
5
|
import { fastifyCsrPlugin } from './fastify-csr-plugin'
|
|
6
|
-
import type { ViteDevServer } from 'vite'
|
|
7
6
|
|
|
8
7
|
// const appDir = getPkgJsonDir(import.meta.url)
|
|
9
8
|
const getString = (str?: string) => str
|
package/src/vite/vue/main.ts
CHANGED
|
@@ -7,12 +7,11 @@ import 'virtual:uno.css'
|
|
|
7
7
|
|
|
8
8
|
import RootComponent from './RootComponent.vue'
|
|
9
9
|
interface ssrContext {
|
|
10
|
-
ssr: boolean
|
|
11
10
|
provide?: Record<string, unknown>
|
|
12
11
|
[key: string]: unknown
|
|
13
12
|
}
|
|
14
13
|
|
|
15
|
-
function capitalizeFirstLetter(string) {
|
|
14
|
+
function capitalizeFirstLetter(string: string) {
|
|
16
15
|
return string.charAt(0).toUpperCase() + string.slice(1)
|
|
17
16
|
}
|
|
18
17
|
|
|
@@ -1,11 +1,16 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { type FastifyReply, type FastifyRequest } from 'fastify'
|
|
2
|
+
import { createApp } from '../main.js'
|
|
3
|
+
import { renderToString as renderToStringVue } from 'vue/server-renderer'
|
|
2
4
|
|
|
3
|
-
const initializeApp = async (
|
|
4
|
-
|
|
5
|
+
const initializeApp = async (
|
|
6
|
+
url: string,
|
|
7
|
+
ssrContext: Record<string, unknown>
|
|
8
|
+
) => {
|
|
9
|
+
const onRenderedList: (() => unknown)[] = []
|
|
5
10
|
Object.assign(ssrContext, {
|
|
6
11
|
_modules: new Set(),
|
|
7
12
|
_meta: {},
|
|
8
|
-
onRendered: (fn) => {
|
|
13
|
+
onRendered: (fn: () => unknown) => {
|
|
9
14
|
onRenderedList.push(fn)
|
|
10
15
|
}
|
|
11
16
|
})
|
|
@@ -27,28 +32,43 @@ const initializeApp = async (url, ssrContext) => {
|
|
|
27
32
|
export const getRoutes = async () =>
|
|
28
33
|
(
|
|
29
34
|
await initializeApp('/', {
|
|
30
|
-
ssr: false,
|
|
31
35
|
req: { headers: {}, url: '/' },
|
|
32
36
|
res: {}
|
|
33
37
|
})
|
|
34
38
|
).routes
|
|
35
39
|
|
|
36
|
-
export async function render(
|
|
40
|
+
export async function render(
|
|
41
|
+
url: string,
|
|
42
|
+
manifest: Record<string, unknown>,
|
|
43
|
+
ssrContext: {
|
|
44
|
+
request: FastifyRequest | { headers: Record<string, unknown>; url: string }
|
|
45
|
+
reply: FastifyReply | Record<string, unknown>
|
|
46
|
+
provide: Record<string, unknown>
|
|
47
|
+
},
|
|
48
|
+
renderToString: typeof renderToStringVue
|
|
49
|
+
) {
|
|
37
50
|
if (!renderToString)
|
|
38
51
|
renderToString = (await import('vue/server-renderer')).renderToString
|
|
39
52
|
const { app, router } = await initializeApp(url, ssrContext)
|
|
40
53
|
|
|
41
|
-
const ctx
|
|
54
|
+
const ctx: {
|
|
55
|
+
modules?: Map<unknown, unknown>
|
|
56
|
+
transports?: Record<string, unknown>
|
|
57
|
+
__qMetaList: unknown[]
|
|
58
|
+
} = {
|
|
42
59
|
__qMetaList: []
|
|
43
60
|
}
|
|
44
61
|
const html = await renderToString(app, ctx)
|
|
45
62
|
|
|
46
|
-
const preloadLinks = renderPreloadLinks(ctx.modules
|
|
63
|
+
const preloadLinks = renderPreloadLinks(ctx.modules!, manifest)
|
|
47
64
|
|
|
48
65
|
return [html, preloadLinks]
|
|
49
66
|
}
|
|
50
67
|
|
|
51
|
-
function renderPreloadLinks(
|
|
68
|
+
function renderPreloadLinks(
|
|
69
|
+
modules: Map<unknown, unknown>,
|
|
70
|
+
manifest: Record<string, unknown>
|
|
71
|
+
) {
|
|
52
72
|
let links = ''
|
|
53
73
|
const seen = new Set()
|
|
54
74
|
modules.forEach((id) => {
|