vitrify 0.10.5 → 0.11.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/bin/build.js +2 -1
- package/dist/bin/cli.js +2 -1
- package/dist/bin/dev.js +5 -1
- package/dist/frameworks/vue/fastify-ssr-plugin.js +40 -22
- package/dist/helpers/utils.js +20 -2
- package/dist/index.js +49 -34
- package/dist/types/bin/build.d.ts +1 -0
- package/dist/types/bin/dev.d.ts +2 -2
- package/dist/types/frameworks/vue/fastify-ssr-plugin.d.ts +0 -1
- package/dist/types/helpers/utils.d.ts +4 -2
- package/dist/types/index.d.ts +2 -1
- package/package.json +3 -3
- package/src/node/bin/build.ts +3 -1
- package/src/node/bin/cli.ts +3 -1
- package/src/node/bin/dev.ts +5 -1
- package/src/node/frameworks/vue/fastify-ssr-plugin.ts +53 -27
- package/src/node/helpers/utils.ts +20 -4
- package/src/node/index.ts +54 -38
- package/src/vite/vue/RootComponent.vue +1 -0
package/dist/bin/build.js
CHANGED
package/dist/bin/cli.js
CHANGED
package/dist/bin/dev.js
CHANGED
|
@@ -101,7 +101,11 @@ ssr, framework = 'vue', host, appDir, publicDir }) {
|
|
|
101
101
|
: new URL(`src/vite/${framework}/ssr/app.ts`, cliDir).pathname;
|
|
102
102
|
({ setup, onRendered, vitrifyConfig } = await vite.ssrLoadModule(entryUrl));
|
|
103
103
|
const app = fastify({
|
|
104
|
-
logger:
|
|
104
|
+
logger: {
|
|
105
|
+
level: process.env.DEBUG
|
|
106
|
+
? 'debug'
|
|
107
|
+
: process.env.PINO_LOG_LEVEL || 'info'
|
|
108
|
+
},
|
|
105
109
|
https: vite.config.server.https,
|
|
106
110
|
...vitrifyConfig.vitrify?.ssr?.fastify
|
|
107
111
|
});
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import fastifyStatic from '@fastify/static';
|
|
2
2
|
import { readFileSync } from 'fs';
|
|
3
|
-
import {
|
|
4
|
-
import { appendToHead } from '../../helpers/utils.js';
|
|
3
|
+
import { addOrReplaceAppDiv, appendToBody, appendToHead } from '../../helpers/utils.js';
|
|
5
4
|
const fastifySsrPlugin = async (fastify, options, done) => {
|
|
6
5
|
options.baseUrl = options.baseUrl || '/';
|
|
7
6
|
options.mode = options.mode || process.env.MODE || import.meta.env.MODE;
|
|
@@ -84,26 +83,34 @@ const fastifySsrPlugin = async (fastify, options, done) => {
|
|
|
84
83
|
catch (e) {
|
|
85
84
|
manifest = {};
|
|
86
85
|
}
|
|
87
|
-
const cssModules = [entryUrl]
|
|
88
|
-
//
|
|
89
|
-
//
|
|
90
|
-
//
|
|
91
|
-
|
|
92
|
-
const css = collectCss({
|
|
93
|
-
mods: matchedModules
|
|
94
|
-
});
|
|
86
|
+
// const cssModules = [entryUrl]
|
|
87
|
+
// const matchedModules = componentsModules(cssModules, vite!)
|
|
88
|
+
// const css = collectCss({
|
|
89
|
+
// mods: matchedModules
|
|
90
|
+
// })
|
|
95
91
|
const [appHtml, preloadLinks] = await render(url, manifest, ssrContext);
|
|
96
92
|
if (!ssrContext.initialState)
|
|
97
93
|
ssrContext.initialState = {};
|
|
98
94
|
ssrContext.initialState.provide = provide;
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
html =
|
|
95
|
+
const initialStateScript = `
|
|
96
|
+
<script>
|
|
97
|
+
__INITIAL_STATE__ = '${JSON.stringify(ssrContext.initialState)}'
|
|
98
|
+
</script>`;
|
|
99
|
+
const renderHtml = (html) => {
|
|
100
|
+
return appendToHead(preloadLinks, appendToBody(initialStateScript, addOrReplaceAppDiv(appHtml, html)));
|
|
101
|
+
};
|
|
102
|
+
let html = renderHtml(template);
|
|
103
|
+
// let html = template
|
|
104
|
+
// .replace(`<!--app-html-->`, appHtml)
|
|
105
|
+
// .replace('<!--product-name-->', options.productName || 'Product name')
|
|
106
|
+
// // .replace('<!--dev-ssr-css-->', css)
|
|
107
|
+
// .replace(
|
|
108
|
+
// '<!--initial-state-->',
|
|
109
|
+
// `<script>
|
|
110
|
+
// __INITIAL_STATE__ = '${JSON.stringify(ssrContext.initialState)}'
|
|
111
|
+
// </script>`
|
|
112
|
+
// )
|
|
113
|
+
// html = appendToHead(preloadLinks, html)
|
|
107
114
|
if (options.onRendered?.length) {
|
|
108
115
|
for (const ssrFunction of options.onRendered) {
|
|
109
116
|
html = ssrFunction(html, ssrContext);
|
|
@@ -145,10 +152,21 @@ const fastifySsrPlugin = async (fastify, options, done) => {
|
|
|
145
152
|
if (!ssrContext.initialState)
|
|
146
153
|
ssrContext.initialState = {};
|
|
147
154
|
ssrContext.initialState.provide = provide;
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
155
|
+
const initialStateScript = `
|
|
156
|
+
<script>
|
|
157
|
+
__INITIAL_STATE__ = '${JSON.stringify(ssrContext.initialState)}'
|
|
158
|
+
</script>`;
|
|
159
|
+
const renderHtml = (html) => {
|
|
160
|
+
return appendToHead(preloadLinks, appendToBody(initialStateScript, addOrReplaceAppDiv(appHtml, html)));
|
|
161
|
+
};
|
|
162
|
+
let html = renderHtml(template);
|
|
163
|
+
// let html = template.replace(`<!--app-html-->`, appHtml).replace(
|
|
164
|
+
// '<!--initial-state-->',
|
|
165
|
+
// `<script>
|
|
166
|
+
// __INITIAL_STATE__ = '${JSON.stringify(ssrContext.initialState)}'
|
|
167
|
+
// </script>`
|
|
168
|
+
// )
|
|
169
|
+
// html = appendToHead(preloadLinks, html)
|
|
152
170
|
if (options.onRendered?.length) {
|
|
153
171
|
for (const ssrFunction of options.onRendered) {
|
|
154
172
|
html = ssrFunction(html, ssrContext);
|
package/dist/helpers/utils.js
CHANGED
|
@@ -22,5 +22,23 @@ export function resolveHostname(optionsHost) {
|
|
|
22
22
|
: host;
|
|
23
23
|
return { host, name };
|
|
24
24
|
}
|
|
25
|
-
export const appendToHead = (
|
|
26
|
-
export const appendToBody = (
|
|
25
|
+
export const appendToHead = (content, html) => html.replace(/<\/head>/, content + '</head>');
|
|
26
|
+
export const appendToBody = (content, html) => html.replace(/<\/body>/, content + '</body>');
|
|
27
|
+
export const addOrReplaceTitle = (title, html) => {
|
|
28
|
+
const currentTitle = html.match(/<title>.*<\/title>/);
|
|
29
|
+
const newTitle = `<title>${title}</title>`;
|
|
30
|
+
if (currentTitle)
|
|
31
|
+
html = html.replace(/<title>.*<\/title>/, newTitle);
|
|
32
|
+
else
|
|
33
|
+
html = appendToHead(newTitle, html);
|
|
34
|
+
return html;
|
|
35
|
+
};
|
|
36
|
+
export const addOrReplaceAppDiv = (content, html) => {
|
|
37
|
+
const currentAppDiv = html.match(/<div id="app">.*<\/div>/);
|
|
38
|
+
const newAppDiv = `<div id="app">${content}</div>`;
|
|
39
|
+
if (currentAppDiv)
|
|
40
|
+
html = html.replace(/<div id="app">.*<\/div>/, newAppDiv);
|
|
41
|
+
else
|
|
42
|
+
html = appendToBody(newAppDiv, html);
|
|
43
|
+
return html;
|
|
44
|
+
};
|
package/dist/index.js
CHANGED
|
@@ -11,6 +11,7 @@ import builtinModules from 'builtin-modules';
|
|
|
11
11
|
import { visualizer } from 'rollup-plugin-visualizer';
|
|
12
12
|
import { resolve } from './app-urls.js';
|
|
13
13
|
import envPlugin from '@vitrify/plugin-env';
|
|
14
|
+
import { addOrReplaceTitle, appendToBody } from './helpers/utils.js';
|
|
14
15
|
const internalServerModules = [
|
|
15
16
|
'util',
|
|
16
17
|
'vitrify',
|
|
@@ -21,7 +22,10 @@ const internalServerModules = [
|
|
|
21
22
|
'@fastify/middie',
|
|
22
23
|
'@fastify',
|
|
23
24
|
'node',
|
|
24
|
-
'critters'
|
|
25
|
+
'critters',
|
|
26
|
+
'node-fetch',
|
|
27
|
+
'ws',
|
|
28
|
+
'abort-controller'
|
|
25
29
|
];
|
|
26
30
|
const configPluginMap = {
|
|
27
31
|
quasar: () => import('./plugins/quasar.js').then((module) => module.QuasarPlugin)
|
|
@@ -108,7 +112,7 @@ async function bundleConfigFile(fileName, isESM = false) {
|
|
|
108
112
|
dependencies: result.metafile ? Object.keys(result.metafile.inputs) : []
|
|
109
113
|
};
|
|
110
114
|
}
|
|
111
|
-
export const baseConfig = async ({ ssr, appDir, publicDir, base = '/', command = 'build', mode = 'production', framework = 'vue', pwa = false, debug = false }) => {
|
|
115
|
+
export const baseConfig = async ({ ssr, appDir, publicDir, base = '/', command = 'build', mode = 'production', framework = 'vue', pwa = false, debug = false, productName }) => {
|
|
112
116
|
const { getAppDir, getCliDir, getCliViteDir, getSrcDir, getCwd } = await import('./app-urls.js');
|
|
113
117
|
if (!appDir) {
|
|
114
118
|
appDir = getAppDir();
|
|
@@ -162,15 +166,19 @@ export const baseConfig = async ({ ssr, appDir, publicDir, base = '/', command =
|
|
|
162
166
|
// new URL(await resolve(val, cliDir!.href))
|
|
163
167
|
// )
|
|
164
168
|
// })()
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
169
|
+
if (!productName) {
|
|
170
|
+
try {
|
|
171
|
+
;
|
|
172
|
+
({ productName } = JSON.parse(readFileSync(new URL('package.json', appDir).pathname, {
|
|
173
|
+
encoding: 'utf-8'
|
|
174
|
+
})));
|
|
175
|
+
}
|
|
176
|
+
catch (e) {
|
|
177
|
+
console.error('package.json not found');
|
|
178
|
+
productName = 'Product name';
|
|
179
|
+
}
|
|
171
180
|
}
|
|
172
|
-
|
|
173
|
-
console.error('package.json not found');
|
|
181
|
+
else {
|
|
174
182
|
}
|
|
175
183
|
const frameworkPlugins = [];
|
|
176
184
|
for (const framework of Object.keys(configPluginMap)) {
|
|
@@ -202,16 +210,21 @@ export const baseConfig = async ({ ssr, appDir, publicDir, base = '/', command =
|
|
|
202
210
|
name: 'vitrify-transforms',
|
|
203
211
|
enforce: 'pre',
|
|
204
212
|
transform: (code, id) => {
|
|
205
|
-
if (['main.ts', 'vitrify'].every((val) => id.includes(val))) {
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
}
|
|
213
|
+
// if (['main.ts', 'vitrify'].every((val) => id.includes(val))) {
|
|
214
|
+
// code =
|
|
215
|
+
// `${globalCss.map((css) => `import '${css}'`).join('\n')}\n` + code
|
|
216
|
+
// }
|
|
209
217
|
if (['RootComponent.vue', 'vitrify'].every((val) => id.includes(val))) {
|
|
218
|
+
const css = `${globalCss
|
|
219
|
+
.map((css) => `@import '${css}';`)
|
|
220
|
+
.join('\n')}\n`;
|
|
210
221
|
const sass = [
|
|
211
222
|
...Object.entries(sassVariables).map(([key, value]) => `${key}: ${value}`),
|
|
212
223
|
...globalSass.map((sass) => `@import '${sass}'`)
|
|
213
224
|
].join('\n');
|
|
214
|
-
code = code
|
|
225
|
+
code = code
|
|
226
|
+
.replace(/<style>(.*?)<\/style>/, '<style>' + css + '</style>')
|
|
227
|
+
.replace(/<style lang="sass">(.*?)<\/style>/, '<style lang="sass">' + sass + '</style>');
|
|
215
228
|
// code = code.replace(/<\/style>/, sass + '</style>')
|
|
216
229
|
}
|
|
217
230
|
return code;
|
|
@@ -347,29 +360,31 @@ export const baseConfig = async ({ ssr, appDir, publicDir, base = '/', command =
|
|
|
347
360
|
entry = new URL('csr/entry.ts', frameworkDir).pathname;
|
|
348
361
|
}
|
|
349
362
|
const entryScript = `<script type="module" src="${entry}"></script>`;
|
|
350
|
-
html = html
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
}
|
|
356
|
-
});
|
|
357
|
-
plugins.unshift({
|
|
358
|
-
name: 'product-name',
|
|
359
|
-
enforce: 'post',
|
|
360
|
-
config: (config, env) => {
|
|
361
|
-
if (config.vitrify?.productName)
|
|
362
|
-
productName = config.vitrify?.productName;
|
|
363
|
-
return;
|
|
364
|
-
},
|
|
365
|
-
transformIndexHtml: {
|
|
366
|
-
enforce: 'post',
|
|
367
|
-
transform: (html) => {
|
|
368
|
-
html = html.replace('<!--product-name-->', productName);
|
|
363
|
+
// html = html.replace('<!--entry-script-->', entryScript)
|
|
364
|
+
html = appendToBody(entryScript, html);
|
|
365
|
+
if (productName)
|
|
366
|
+
html = addOrReplaceTitle(productName, html);
|
|
367
|
+
// html = html.replace('<!--product-name-->', productName)
|
|
369
368
|
return html;
|
|
370
369
|
}
|
|
371
370
|
}
|
|
372
371
|
});
|
|
372
|
+
// plugins.unshift({
|
|
373
|
+
// name: 'product-name',
|
|
374
|
+
// enforce: 'post',
|
|
375
|
+
// config: (config: VitrifyConfig, env) => {
|
|
376
|
+
// if (config.vitrify?.productName)
|
|
377
|
+
// productName = config.vitrify?.productName
|
|
378
|
+
// return
|
|
379
|
+
// },
|
|
380
|
+
// transformIndexHtml: {
|
|
381
|
+
// enforce: 'post',
|
|
382
|
+
// transform: (html) => {
|
|
383
|
+
// html = html.replace('<!--product-name-->', productName)
|
|
384
|
+
// return html
|
|
385
|
+
// }
|
|
386
|
+
// }
|
|
387
|
+
// })
|
|
373
388
|
// @ts-ignore
|
|
374
389
|
if (debug)
|
|
375
390
|
plugins.push(visualizer());
|
package/dist/types/bin/dev.d.ts
CHANGED
|
@@ -34,12 +34,12 @@ export declare function createServer({ port, logLevel, ssr, framework, host, app
|
|
|
34
34
|
isWorker: boolean;
|
|
35
35
|
isProduction: boolean;
|
|
36
36
|
env: Record<string, any>;
|
|
37
|
-
resolve: import("vite").ResolveOptions & {
|
|
37
|
+
resolve: Required<import("vite").ResolveOptions> & {
|
|
38
38
|
alias: import("vite").Alias[];
|
|
39
39
|
};
|
|
40
40
|
plugins: readonly import("vite").Plugin[];
|
|
41
41
|
server: import("vite").ResolvedServerOptions;
|
|
42
|
-
build:
|
|
42
|
+
build: import("vite").ResolvedBuildOptions;
|
|
43
43
|
preview: import("vite").ResolvedPreviewOptions;
|
|
44
44
|
ssr: import("vite").ResolvedSSROptions;
|
|
45
45
|
assetsInclude: (file: string) => boolean;
|
|
@@ -3,5 +3,7 @@ export interface Hostname {
|
|
|
3
3
|
name: string;
|
|
4
4
|
}
|
|
5
5
|
export declare function resolveHostname(optionsHost: string | boolean | undefined): Hostname;
|
|
6
|
-
export declare const appendToHead: (
|
|
7
|
-
export declare const appendToBody: (
|
|
6
|
+
export declare const appendToHead: (content: string, html: string) => string;
|
|
7
|
+
export declare const appendToBody: (content: string, html: string) => string;
|
|
8
|
+
export declare const addOrReplaceTitle: (title: string, html: string) => string;
|
|
9
|
+
export declare const addOrReplaceAppDiv: (content: string, html: string) => string;
|
package/dist/types/index.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ import type { BootFunction, VitrifyConfig } from './vitrify-config.js';
|
|
|
3
3
|
import type { VitrifyContext } from './bin/run.js';
|
|
4
4
|
import type { VitrifyPlugin } from './plugins/index.js';
|
|
5
5
|
export declare const VIRTUAL_MODULES: string[];
|
|
6
|
-
export declare const baseConfig: ({ ssr, appDir, publicDir, base, command, mode, framework, pwa, debug }: {
|
|
6
|
+
export declare const baseConfig: ({ ssr, appDir, publicDir, base, command, mode, framework, pwa, debug, productName }: {
|
|
7
7
|
ssr?: "server" | "client" | "ssg" | "fastify" | undefined;
|
|
8
8
|
appDir?: URL | undefined;
|
|
9
9
|
publicDir?: URL | undefined;
|
|
@@ -13,6 +13,7 @@ export declare const baseConfig: ({ ssr, appDir, publicDir, base, command, mode,
|
|
|
13
13
|
framework?: "vue" | undefined;
|
|
14
14
|
pwa?: boolean | undefined;
|
|
15
15
|
debug?: boolean | undefined;
|
|
16
|
+
productName?: string | undefined;
|
|
16
17
|
}) => Promise<InlineConfig>;
|
|
17
18
|
export declare const vitrifyDir: URL;
|
|
18
19
|
export { prerender } from './frameworks/vue/prerender.js';
|
package/package.json
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vitrify",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.11.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"author": "Stefan van Herwijnen",
|
|
6
6
|
"description": "Vite as your Full Stack development tool",
|
|
7
7
|
"type": "module",
|
|
8
|
-
"types": "./dist/index.d.ts",
|
|
8
|
+
"types": "./dist/types/index.d.ts",
|
|
9
9
|
"bin": {
|
|
10
10
|
"vitrify": "./dist/bin/cli.js"
|
|
11
11
|
},
|
|
12
12
|
"exports": {
|
|
13
13
|
".": {
|
|
14
|
-
"types": "./dist/index.d.ts",
|
|
14
|
+
"types": "./dist/types/index.d.ts",
|
|
15
15
|
"import": "./dist/index.js"
|
|
16
16
|
},
|
|
17
17
|
"./build": {
|
package/src/node/bin/build.ts
CHANGED
|
@@ -9,6 +9,7 @@ export async function build(opts: {
|
|
|
9
9
|
appDir?: URL
|
|
10
10
|
publicDir?: URL
|
|
11
11
|
debug?: boolean
|
|
12
|
+
productName?: string
|
|
12
13
|
}) {
|
|
13
14
|
const config = await baseConfig({
|
|
14
15
|
command: 'build',
|
|
@@ -17,7 +18,8 @@ export async function build(opts: {
|
|
|
17
18
|
appDir: opts.appDir,
|
|
18
19
|
publicDir: opts.publicDir,
|
|
19
20
|
base: opts.base,
|
|
20
|
-
debug: opts.debug
|
|
21
|
+
debug: opts.debug,
|
|
22
|
+
productName: opts.productName
|
|
21
23
|
})
|
|
22
24
|
|
|
23
25
|
config.build = {
|
package/src/node/bin/cli.ts
CHANGED
|
@@ -35,11 +35,13 @@ cli
|
|
|
35
35
|
appDir?: URL
|
|
36
36
|
publicDir?: URL
|
|
37
37
|
debug?: boolean
|
|
38
|
+
productName?: string
|
|
38
39
|
} = {
|
|
39
40
|
base: options.base,
|
|
40
41
|
appDir,
|
|
41
42
|
publicDir: parsePath(options.publicDir, appDir),
|
|
42
|
-
debug: options.debug
|
|
43
|
+
debug: options.debug,
|
|
44
|
+
productName: options.productName
|
|
43
45
|
}
|
|
44
46
|
|
|
45
47
|
switch (options.mode) {
|
package/src/node/bin/dev.ts
CHANGED
|
@@ -159,7 +159,11 @@ export async function createServer({
|
|
|
159
159
|
|
|
160
160
|
;({ setup, onRendered, vitrifyConfig } = await vite.ssrLoadModule(entryUrl))
|
|
161
161
|
const app = fastify({
|
|
162
|
-
logger:
|
|
162
|
+
logger: {
|
|
163
|
+
level: process.env.DEBUG
|
|
164
|
+
? 'debug'
|
|
165
|
+
: process.env.PINO_LOG_LEVEL || 'info'
|
|
166
|
+
},
|
|
163
167
|
https: vite.config.server.https,
|
|
164
168
|
...vitrifyConfig.vitrify?.ssr?.fastify
|
|
165
169
|
} as FastifyServerOptions)
|
|
@@ -6,7 +6,12 @@ import type {
|
|
|
6
6
|
import fastifyStatic from '@fastify/static'
|
|
7
7
|
import { readFileSync } from 'fs'
|
|
8
8
|
import { componentsModules, collectCss } from '../../helpers/collect-css-ssr.js'
|
|
9
|
-
import {
|
|
9
|
+
import {
|
|
10
|
+
addOrReplaceAppDiv,
|
|
11
|
+
addOrReplaceTitle,
|
|
12
|
+
appendToBody,
|
|
13
|
+
appendToHead
|
|
14
|
+
} from '../../helpers/utils.js'
|
|
10
15
|
import type { ViteDevServer } from 'vite'
|
|
11
16
|
import type { OnRenderedHook } from '../../vitrify-config.js'
|
|
12
17
|
export interface FastifySsrOptions {
|
|
@@ -21,7 +26,6 @@ export interface FastifySsrOptions {
|
|
|
21
26
|
onRendered?: OnRenderedHook[]
|
|
22
27
|
appDir?: URL
|
|
23
28
|
publicDir?: URL
|
|
24
|
-
productName?: string
|
|
25
29
|
mode?: string
|
|
26
30
|
host?: string
|
|
27
31
|
}
|
|
@@ -125,32 +129,41 @@ const fastifySsrPlugin: FastifyPluginCallback<FastifySsrOptions> = async (
|
|
|
125
129
|
manifest = {}
|
|
126
130
|
}
|
|
127
131
|
|
|
128
|
-
const cssModules = [entryUrl]
|
|
129
|
-
//
|
|
130
|
-
//
|
|
131
|
-
//
|
|
132
|
-
|
|
133
|
-
const css = collectCss({
|
|
134
|
-
mods: matchedModules
|
|
135
|
-
})
|
|
132
|
+
// const cssModules = [entryUrl]
|
|
133
|
+
// const matchedModules = componentsModules(cssModules, vite!)
|
|
134
|
+
// const css = collectCss({
|
|
135
|
+
// mods: matchedModules
|
|
136
|
+
// })
|
|
136
137
|
|
|
137
138
|
const [appHtml, preloadLinks] = await render(url, manifest, ssrContext)
|
|
138
139
|
|
|
139
140
|
if (!ssrContext.initialState) ssrContext.initialState = {}
|
|
140
141
|
ssrContext.initialState.provide = provide
|
|
141
142
|
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
</script>`
|
|
143
|
+
const initialStateScript = `
|
|
144
|
+
<script>
|
|
145
|
+
__INITIAL_STATE__ = '${JSON.stringify(ssrContext.initialState)}'
|
|
146
|
+
</script>`
|
|
147
|
+
const renderHtml = (html: string) => {
|
|
148
|
+
return appendToHead(
|
|
149
|
+
preloadLinks,
|
|
150
|
+
appendToBody(initialStateScript, addOrReplaceAppDiv(appHtml, html))
|
|
151
151
|
)
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
let html = renderHtml(template)
|
|
155
|
+
// let html = template
|
|
156
|
+
// .replace(`<!--app-html-->`, appHtml)
|
|
157
|
+
// .replace('<!--product-name-->', options.productName || 'Product name')
|
|
158
|
+
// // .replace('<!--dev-ssr-css-->', css)
|
|
159
|
+
// .replace(
|
|
160
|
+
// '<!--initial-state-->',
|
|
161
|
+
// `<script>
|
|
162
|
+
// __INITIAL_STATE__ = '${JSON.stringify(ssrContext.initialState)}'
|
|
163
|
+
// </script>`
|
|
164
|
+
// )
|
|
152
165
|
|
|
153
|
-
html = appendToHead(preloadLinks, html)
|
|
166
|
+
// html = appendToHead(preloadLinks, html)
|
|
154
167
|
|
|
155
168
|
if (options.onRendered?.length) {
|
|
156
169
|
for (const ssrFunction of options.onRendered) {
|
|
@@ -206,14 +219,27 @@ const fastifySsrPlugin: FastifyPluginCallback<FastifySsrOptions> = async (
|
|
|
206
219
|
if (!ssrContext.initialState) ssrContext.initialState = {}
|
|
207
220
|
ssrContext.initialState.provide = provide
|
|
208
221
|
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
222
|
+
const initialStateScript = `
|
|
223
|
+
<script>
|
|
224
|
+
__INITIAL_STATE__ = '${JSON.stringify(ssrContext.initialState)}'
|
|
225
|
+
</script>`
|
|
226
|
+
const renderHtml = (html: string) => {
|
|
227
|
+
return appendToHead(
|
|
228
|
+
preloadLinks,
|
|
229
|
+
appendToBody(initialStateScript, addOrReplaceAppDiv(appHtml, html))
|
|
230
|
+
)
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
let html = renderHtml(template)
|
|
234
|
+
|
|
235
|
+
// let html = template.replace(`<!--app-html-->`, appHtml).replace(
|
|
236
|
+
// '<!--initial-state-->',
|
|
237
|
+
// `<script>
|
|
238
|
+
// __INITIAL_STATE__ = '${JSON.stringify(ssrContext.initialState)}'
|
|
239
|
+
// </script>`
|
|
240
|
+
// )
|
|
215
241
|
|
|
216
|
-
html = appendToHead(preloadLinks, html)
|
|
242
|
+
// html = appendToHead(preloadLinks, html)
|
|
217
243
|
|
|
218
244
|
if (options.onRendered?.length) {
|
|
219
245
|
for (const ssrFunction of options.onRendered) {
|
|
@@ -36,8 +36,24 @@ export function resolveHostname(
|
|
|
36
36
|
return { host, name }
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
-
export const appendToHead = (
|
|
40
|
-
html.replace(/<\/head>/,
|
|
39
|
+
export const appendToHead = (content: string, html: string) =>
|
|
40
|
+
html.replace(/<\/head>/, content + '</head>')
|
|
41
41
|
|
|
42
|
-
export const appendToBody = (
|
|
43
|
-
html.replace(/<\/body>/,
|
|
42
|
+
export const appendToBody = (content: string, html: string) =>
|
|
43
|
+
html.replace(/<\/body>/, content + '</body>')
|
|
44
|
+
|
|
45
|
+
export const addOrReplaceTitle = (title: string, html: string) => {
|
|
46
|
+
const currentTitle = html.match(/<title>.*<\/title>/)
|
|
47
|
+
const newTitle = `<title>${title}</title>`
|
|
48
|
+
if (currentTitle) html = html.replace(/<title>.*<\/title>/, newTitle)
|
|
49
|
+
else html = appendToHead(newTitle, html)
|
|
50
|
+
return html
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export const addOrReplaceAppDiv = (content: string, html: string) => {
|
|
54
|
+
const currentAppDiv = html.match(/<div id="app">.*<\/div>/)
|
|
55
|
+
const newAppDiv = `<div id="app">${content}</div>`
|
|
56
|
+
if (currentAppDiv) html = html.replace(/<div id="app">.*<\/div>/, newAppDiv)
|
|
57
|
+
else html = appendToBody(newAppDiv, html)
|
|
58
|
+
return html
|
|
59
|
+
}
|
package/src/node/index.ts
CHANGED
|
@@ -24,6 +24,7 @@ import type { VitrifyPlugin } from './plugins/index.js'
|
|
|
24
24
|
import { resolve } from './app-urls.js'
|
|
25
25
|
import type { ManualChunksOption, RollupOptions } from 'rollup'
|
|
26
26
|
import envPlugin from '@vitrify/plugin-env'
|
|
27
|
+
import { addOrReplaceTitle, appendToBody } from './helpers/utils.js'
|
|
27
28
|
|
|
28
29
|
const internalServerModules = [
|
|
29
30
|
'util',
|
|
@@ -35,7 +36,10 @@ const internalServerModules = [
|
|
|
35
36
|
'@fastify/middie',
|
|
36
37
|
'@fastify',
|
|
37
38
|
'node',
|
|
38
|
-
'critters'
|
|
39
|
+
'critters',
|
|
40
|
+
'node-fetch',
|
|
41
|
+
'ws',
|
|
42
|
+
'abort-controller'
|
|
39
43
|
]
|
|
40
44
|
|
|
41
45
|
const configPluginMap: Record<string, () => Promise<VitrifyPlugin>> = {
|
|
@@ -149,7 +153,8 @@ export const baseConfig = async ({
|
|
|
149
153
|
mode = 'production',
|
|
150
154
|
framework = 'vue',
|
|
151
155
|
pwa = false,
|
|
152
|
-
debug = false
|
|
156
|
+
debug = false,
|
|
157
|
+
productName
|
|
153
158
|
}: {
|
|
154
159
|
ssr?: 'client' | 'server' | 'ssg' | 'fastify'
|
|
155
160
|
appDir?: URL
|
|
@@ -160,6 +165,7 @@ export const baseConfig = async ({
|
|
|
160
165
|
framework?: 'vue'
|
|
161
166
|
pwa?: boolean
|
|
162
167
|
debug?: boolean
|
|
168
|
+
productName?: string
|
|
163
169
|
}): Promise<InlineConfig> => {
|
|
164
170
|
const { getAppDir, getCliDir, getCliViteDir, getSrcDir, getCwd } =
|
|
165
171
|
await import('./app-urls.js')
|
|
@@ -228,15 +234,18 @@ export const baseConfig = async ({
|
|
|
228
234
|
// )
|
|
229
235
|
// })()
|
|
230
236
|
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
237
|
+
if (!productName) {
|
|
238
|
+
try {
|
|
239
|
+
;({ productName } = JSON.parse(
|
|
240
|
+
readFileSync(new URL('package.json', appDir).pathname, {
|
|
241
|
+
encoding: 'utf-8'
|
|
242
|
+
})
|
|
243
|
+
))
|
|
244
|
+
} catch (e) {
|
|
245
|
+
console.error('package.json not found')
|
|
246
|
+
productName = 'Product name'
|
|
247
|
+
}
|
|
248
|
+
} else {
|
|
240
249
|
}
|
|
241
250
|
|
|
242
251
|
const frameworkPlugins = []
|
|
@@ -274,21 +283,27 @@ export const baseConfig = async ({
|
|
|
274
283
|
name: 'vitrify-transforms',
|
|
275
284
|
enforce: 'pre',
|
|
276
285
|
transform: (code, id) => {
|
|
277
|
-
if (['main.ts', 'vitrify'].every((val) => id.includes(val))) {
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
}
|
|
286
|
+
// if (['main.ts', 'vitrify'].every((val) => id.includes(val))) {
|
|
287
|
+
// code =
|
|
288
|
+
// `${globalCss.map((css) => `import '${css}'`).join('\n')}\n` + code
|
|
289
|
+
// }
|
|
281
290
|
if (['RootComponent.vue', 'vitrify'].every((val) => id.includes(val))) {
|
|
291
|
+
const css = `${globalCss
|
|
292
|
+
.map((css) => `@import '${css}';`)
|
|
293
|
+
.join('\n')}\n`
|
|
294
|
+
|
|
282
295
|
const sass = [
|
|
283
296
|
...Object.entries(sassVariables).map(
|
|
284
297
|
([key, value]) => `${key}: ${value}`
|
|
285
298
|
),
|
|
286
299
|
...globalSass.map((sass) => `@import '${sass}'`)
|
|
287
300
|
].join('\n')
|
|
288
|
-
code = code
|
|
289
|
-
/<style
|
|
290
|
-
|
|
291
|
-
|
|
301
|
+
code = code
|
|
302
|
+
.replace(/<style>(.*?)<\/style>/, '<style>' + css + '</style>')
|
|
303
|
+
.replace(
|
|
304
|
+
/<style lang="sass">(.*?)<\/style>/,
|
|
305
|
+
'<style lang="sass">' + sass + '</style>'
|
|
306
|
+
)
|
|
292
307
|
// code = code.replace(/<\/style>/, sass + '</style>')
|
|
293
308
|
}
|
|
294
309
|
return code
|
|
@@ -422,30 +437,31 @@ export const baseConfig = async ({
|
|
|
422
437
|
entry = new URL('csr/entry.ts', frameworkDir).pathname
|
|
423
438
|
}
|
|
424
439
|
const entryScript = `<script type="module" src="${entry}"></script>`
|
|
425
|
-
html = html
|
|
426
|
-
|
|
427
|
-
|
|
440
|
+
// html = html.replace('<!--entry-script-->', entryScript)
|
|
441
|
+
html = appendToBody(entryScript, html)
|
|
442
|
+
if (productName) html = addOrReplaceTitle(productName, html)
|
|
443
|
+
// html = html.replace('<!--product-name-->', productName)
|
|
428
444
|
return html
|
|
429
445
|
}
|
|
430
446
|
}
|
|
431
447
|
})
|
|
432
448
|
|
|
433
|
-
plugins.unshift({
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
})
|
|
449
|
+
// plugins.unshift({
|
|
450
|
+
// name: 'product-name',
|
|
451
|
+
// enforce: 'post',
|
|
452
|
+
// config: (config: VitrifyConfig, env) => {
|
|
453
|
+
// if (config.vitrify?.productName)
|
|
454
|
+
// productName = config.vitrify?.productName
|
|
455
|
+
// return
|
|
456
|
+
// },
|
|
457
|
+
// transformIndexHtml: {
|
|
458
|
+
// enforce: 'post',
|
|
459
|
+
// transform: (html) => {
|
|
460
|
+
// html = html.replace('<!--product-name-->', productName)
|
|
461
|
+
// return html
|
|
462
|
+
// }
|
|
463
|
+
// }
|
|
464
|
+
// })
|
|
449
465
|
|
|
450
466
|
// @ts-ignore
|
|
451
467
|
if (debug) plugins.push(visualizer())
|