vitrify 0.10.6 → 0.11.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/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 +35 -13
- package/dist/helpers/utils.js +20 -2
- package/dist/index.js +55 -31
- package/dist/plugins/quasar.js +0 -5
- 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/dist/types/vitrify-config.d.ts +1 -0
- 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 +48 -19
- package/src/node/helpers/utils.ts +20 -4
- package/src/node/index.ts +67 -32
- package/src/node/plugins/quasar.ts +0 -4
- package/src/node/vitrify-config.ts +5 -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,6 +1,6 @@
|
|
|
1
1
|
import fastifyStatic from '@fastify/static';
|
|
2
2
|
import { readFileSync } from 'fs';
|
|
3
|
-
import { appendToHead } from '../../helpers/utils.js';
|
|
3
|
+
import { addOrReplaceAppDiv, appendToBody, appendToHead } from '../../helpers/utils.js';
|
|
4
4
|
const fastifySsrPlugin = async (fastify, options, done) => {
|
|
5
5
|
options.baseUrl = options.baseUrl || '/';
|
|
6
6
|
options.mode = options.mode || process.env.MODE || import.meta.env.MODE;
|
|
@@ -92,14 +92,25 @@ const fastifySsrPlugin = async (fastify, options, done) => {
|
|
|
92
92
|
if (!ssrContext.initialState)
|
|
93
93
|
ssrContext.initialState = {};
|
|
94
94
|
ssrContext.initialState.provide = provide;
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
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)
|
|
103
114
|
if (options.onRendered?.length) {
|
|
104
115
|
for (const ssrFunction of options.onRendered) {
|
|
105
116
|
html = ssrFunction(html, ssrContext);
|
|
@@ -141,10 +152,21 @@ const fastifySsrPlugin = async (fastify, options, done) => {
|
|
|
141
152
|
if (!ssrContext.initialState)
|
|
142
153
|
ssrContext.initialState = {};
|
|
143
154
|
ssrContext.initialState.provide = provide;
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
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)
|
|
148
170
|
if (options.onRendered?.length) {
|
|
149
171
|
for (const ssrFunction of options.onRendered) {
|
|
150
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
|
@@ -7,10 +7,11 @@ import path from 'path';
|
|
|
7
7
|
import { pathToFileURL } from 'url';
|
|
8
8
|
import { readFileSync } from 'fs';
|
|
9
9
|
import builtinModules from 'builtin-modules';
|
|
10
|
-
// import { resolve } from 'import-meta-resolve'
|
|
11
10
|
import { visualizer } from 'rollup-plugin-visualizer';
|
|
12
11
|
import { resolve } from './app-urls.js';
|
|
13
12
|
import envPlugin from '@vitrify/plugin-env';
|
|
13
|
+
import { addOrReplaceTitle, appendToBody } from './helpers/utils.js';
|
|
14
|
+
import Components from 'unplugin-vue-components/vite';
|
|
14
15
|
const internalServerModules = [
|
|
15
16
|
'util',
|
|
16
17
|
'vitrify',
|
|
@@ -21,11 +22,17 @@ 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)
|
|
28
32
|
};
|
|
33
|
+
const configResolverMap = {
|
|
34
|
+
quasar: () => import('unplugin-vue-components/resolvers').then((module) => module.QuasarResolver())
|
|
35
|
+
};
|
|
29
36
|
const manualChunkNames = [
|
|
30
37
|
'prerender',
|
|
31
38
|
'fastify-ssr-plugin',
|
|
@@ -108,7 +115,7 @@ async function bundleConfigFile(fileName, isESM = false) {
|
|
|
108
115
|
dependencies: result.metafile ? Object.keys(result.metafile.inputs) : []
|
|
109
116
|
};
|
|
110
117
|
}
|
|
111
|
-
export const baseConfig = async ({ ssr, appDir, publicDir, base = '/', command = 'build', mode = 'production', framework = 'vue', pwa = false, debug = false }) => {
|
|
118
|
+
export const baseConfig = async ({ ssr, appDir, publicDir, base = '/', command = 'build', mode = 'production', framework = 'vue', pwa = false, debug = false, productName }) => {
|
|
112
119
|
const { getAppDir, getCliDir, getCliViteDir, getSrcDir, getCwd } = await import('./app-urls.js');
|
|
113
120
|
if (!appDir) {
|
|
114
121
|
appDir = getAppDir();
|
|
@@ -162,24 +169,31 @@ export const baseConfig = async ({ ssr, appDir, publicDir, base = '/', command =
|
|
|
162
169
|
// new URL(await resolve(val, cliDir!.href))
|
|
163
170
|
// )
|
|
164
171
|
// })()
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
172
|
+
if (!productName) {
|
|
173
|
+
try {
|
|
174
|
+
;
|
|
175
|
+
({ productName } = JSON.parse(readFileSync(new URL('package.json', appDir).pathname, {
|
|
176
|
+
encoding: 'utf-8'
|
|
177
|
+
})));
|
|
178
|
+
}
|
|
179
|
+
catch (e) {
|
|
180
|
+
console.error('package.json not found');
|
|
181
|
+
productName = 'Product name';
|
|
182
|
+
}
|
|
171
183
|
}
|
|
172
|
-
|
|
173
|
-
console.error('package.json not found');
|
|
184
|
+
else {
|
|
174
185
|
}
|
|
175
186
|
const frameworkPlugins = [];
|
|
187
|
+
const resolvers = [];
|
|
176
188
|
for (const framework of Object.keys(configPluginMap)) {
|
|
177
189
|
if (Object.keys(vitrifyConfig).includes(framework)) {
|
|
178
190
|
const plugin = await configPluginMap[framework]();
|
|
191
|
+
const resolver = await configResolverMap[framework]();
|
|
179
192
|
frameworkPlugins.push(await plugin({
|
|
180
193
|
ssr,
|
|
181
194
|
pwa
|
|
182
195
|
}));
|
|
196
|
+
resolvers.push(resolver);
|
|
183
197
|
}
|
|
184
198
|
}
|
|
185
199
|
let onBootHooks;
|
|
@@ -319,7 +333,15 @@ export const baseConfig = async ({ ssr, appDir, publicDir, base = '/', command =
|
|
|
319
333
|
}
|
|
320
334
|
return null;
|
|
321
335
|
}
|
|
322
|
-
}
|
|
336
|
+
},
|
|
337
|
+
Components({
|
|
338
|
+
exclude: [
|
|
339
|
+
new RegExp(`[\\/]node_modules[\\/].*[\\/]!(${serverModules.join('|')})`),
|
|
340
|
+
/[\\/]\.git[\\/]/,
|
|
341
|
+
/[\\/]\.nuxt[\\/]/
|
|
342
|
+
],
|
|
343
|
+
resolvers
|
|
344
|
+
})
|
|
323
345
|
];
|
|
324
346
|
if (command !== 'test') {
|
|
325
347
|
plugins.unshift({
|
|
@@ -352,29 +374,31 @@ export const baseConfig = async ({ ssr, appDir, publicDir, base = '/', command =
|
|
|
352
374
|
entry = new URL('csr/entry.ts', frameworkDir).pathname;
|
|
353
375
|
}
|
|
354
376
|
const entryScript = `<script type="module" src="${entry}"></script>`;
|
|
355
|
-
html = html
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
}
|
|
361
|
-
});
|
|
362
|
-
plugins.unshift({
|
|
363
|
-
name: 'product-name',
|
|
364
|
-
enforce: 'post',
|
|
365
|
-
config: (config, env) => {
|
|
366
|
-
if (config.vitrify?.productName)
|
|
367
|
-
productName = config.vitrify?.productName;
|
|
368
|
-
return;
|
|
369
|
-
},
|
|
370
|
-
transformIndexHtml: {
|
|
371
|
-
enforce: 'post',
|
|
372
|
-
transform: (html) => {
|
|
373
|
-
html = html.replace('<!--product-name-->', productName);
|
|
377
|
+
// html = html.replace('<!--entry-script-->', entryScript)
|
|
378
|
+
html = appendToBody(entryScript, html);
|
|
379
|
+
if (productName)
|
|
380
|
+
html = addOrReplaceTitle(productName, html);
|
|
381
|
+
// html = html.replace('<!--product-name-->', productName)
|
|
374
382
|
return html;
|
|
375
383
|
}
|
|
376
384
|
}
|
|
377
385
|
});
|
|
386
|
+
// plugins.unshift({
|
|
387
|
+
// name: 'product-name',
|
|
388
|
+
// enforce: 'post',
|
|
389
|
+
// config: (config: VitrifyConfig, env) => {
|
|
390
|
+
// if (config.vitrify?.productName)
|
|
391
|
+
// productName = config.vitrify?.productName
|
|
392
|
+
// return
|
|
393
|
+
// },
|
|
394
|
+
// transformIndexHtml: {
|
|
395
|
+
// enforce: 'post',
|
|
396
|
+
// transform: (html) => {
|
|
397
|
+
// html = html.replace('<!--product-name-->', productName)
|
|
398
|
+
// return html
|
|
399
|
+
// }
|
|
400
|
+
// }
|
|
401
|
+
// })
|
|
378
402
|
// @ts-ignore
|
|
379
403
|
if (debug)
|
|
380
404
|
plugins.push(visualizer());
|
package/dist/plugins/quasar.js
CHANGED
|
@@ -1,6 +1,4 @@
|
|
|
1
1
|
import { resolvePackageData } from 'vite';
|
|
2
|
-
import Components from 'unplugin-vue-components/vite';
|
|
3
|
-
import { QuasarResolver } from 'unplugin-vue-components/resolvers';
|
|
4
2
|
export const injectSsrContext = (html, ssrContext) => html
|
|
5
3
|
.replace(/(<html[^>]*)(>)/i, (found, start, end) => {
|
|
6
4
|
let matches;
|
|
@@ -31,9 +29,6 @@ export const QuasarPlugin = async ({ ssr = false, pwa = false }) => {
|
|
|
31
29
|
let plugins = [];
|
|
32
30
|
let quasarConf;
|
|
33
31
|
return [
|
|
34
|
-
Components({
|
|
35
|
-
resolvers: [QuasarResolver()]
|
|
36
|
-
}),
|
|
37
32
|
{
|
|
38
33
|
name: 'vite-plugin-quasar-transform',
|
|
39
34
|
enforce: 'pre',
|
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';
|
|
@@ -84,4 +84,5 @@ export interface VitrifyConfig extends UserConfig {
|
|
|
84
84
|
};
|
|
85
85
|
quasar?: QuasarConf;
|
|
86
86
|
}
|
|
87
|
+
export declare type VitrifyConfigAsync = VitrifyConfig | ((mode: string, command: string) => Promise<VitrifyConfig>);
|
|
87
88
|
export declare const defineConfig: (config: VitrifyConfig) => VitrifyConfig;
|
package/package.json
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vitrify",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.11.1",
|
|
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
|
}
|
|
@@ -136,18 +140,30 @@ const fastifySsrPlugin: FastifyPluginCallback<FastifySsrOptions> = async (
|
|
|
136
140
|
if (!ssrContext.initialState) ssrContext.initialState = {}
|
|
137
141
|
ssrContext.initialState.provide = provide
|
|
138
142
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
</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))
|
|
148
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
|
+
// )
|
|
149
165
|
|
|
150
|
-
html = appendToHead(preloadLinks, html)
|
|
166
|
+
// html = appendToHead(preloadLinks, html)
|
|
151
167
|
|
|
152
168
|
if (options.onRendered?.length) {
|
|
153
169
|
for (const ssrFunction of options.onRendered) {
|
|
@@ -203,14 +219,27 @@ const fastifySsrPlugin: FastifyPluginCallback<FastifySsrOptions> = async (
|
|
|
203
219
|
if (!ssrContext.initialState) ssrContext.initialState = {}
|
|
204
220
|
ssrContext.initialState.provide = provide
|
|
205
221
|
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
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
|
+
// )
|
|
212
241
|
|
|
213
|
-
html = appendToHead(preloadLinks, html)
|
|
242
|
+
// html = appendToHead(preloadLinks, html)
|
|
214
243
|
|
|
215
244
|
if (options.onRendered?.length) {
|
|
216
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
|
@@ -8,7 +8,6 @@ import path from 'path'
|
|
|
8
8
|
import { pathToFileURL } from 'url'
|
|
9
9
|
import { readFileSync } from 'fs'
|
|
10
10
|
import builtinModules from 'builtin-modules'
|
|
11
|
-
// import { resolve } from 'import-meta-resolve'
|
|
12
11
|
import { visualizer } from 'rollup-plugin-visualizer'
|
|
13
12
|
import type {
|
|
14
13
|
StaticImports,
|
|
@@ -24,6 +23,9 @@ import type { VitrifyPlugin } from './plugins/index.js'
|
|
|
24
23
|
import { resolve } from './app-urls.js'
|
|
25
24
|
import type { ManualChunksOption, RollupOptions } from 'rollup'
|
|
26
25
|
import envPlugin from '@vitrify/plugin-env'
|
|
26
|
+
import { addOrReplaceTitle, appendToBody } from './helpers/utils.js'
|
|
27
|
+
import type { ComponentResolver } from 'unplugin-vue-components'
|
|
28
|
+
import Components from 'unplugin-vue-components/vite'
|
|
27
29
|
|
|
28
30
|
const internalServerModules = [
|
|
29
31
|
'util',
|
|
@@ -35,7 +37,10 @@ const internalServerModules = [
|
|
|
35
37
|
'@fastify/middie',
|
|
36
38
|
'@fastify',
|
|
37
39
|
'node',
|
|
38
|
-
'critters'
|
|
40
|
+
'critters',
|
|
41
|
+
'node-fetch',
|
|
42
|
+
'ws',
|
|
43
|
+
'abort-controller'
|
|
39
44
|
]
|
|
40
45
|
|
|
41
46
|
const configPluginMap: Record<string, () => Promise<VitrifyPlugin>> = {
|
|
@@ -43,6 +48,16 @@ const configPluginMap: Record<string, () => Promise<VitrifyPlugin>> = {
|
|
|
43
48
|
import('./plugins/quasar.js').then((module) => module.QuasarPlugin)
|
|
44
49
|
}
|
|
45
50
|
|
|
51
|
+
const configResolverMap: Record<
|
|
52
|
+
string,
|
|
53
|
+
() => Promise<ComponentResolver | ComponentResolver[]>
|
|
54
|
+
> = {
|
|
55
|
+
quasar: () =>
|
|
56
|
+
import('unplugin-vue-components/resolvers').then((module) =>
|
|
57
|
+
module.QuasarResolver()
|
|
58
|
+
)
|
|
59
|
+
}
|
|
60
|
+
|
|
46
61
|
const manualChunkNames = [
|
|
47
62
|
'prerender',
|
|
48
63
|
'fastify-ssr-plugin',
|
|
@@ -149,7 +164,8 @@ export const baseConfig = async ({
|
|
|
149
164
|
mode = 'production',
|
|
150
165
|
framework = 'vue',
|
|
151
166
|
pwa = false,
|
|
152
|
-
debug = false
|
|
167
|
+
debug = false,
|
|
168
|
+
productName
|
|
153
169
|
}: {
|
|
154
170
|
ssr?: 'client' | 'server' | 'ssg' | 'fastify'
|
|
155
171
|
appDir?: URL
|
|
@@ -160,6 +176,7 @@ export const baseConfig = async ({
|
|
|
160
176
|
framework?: 'vue'
|
|
161
177
|
pwa?: boolean
|
|
162
178
|
debug?: boolean
|
|
179
|
+
productName?: string
|
|
163
180
|
}): Promise<InlineConfig> => {
|
|
164
181
|
const { getAppDir, getCliDir, getCliViteDir, getSrcDir, getCwd } =
|
|
165
182
|
await import('./app-urls.js')
|
|
@@ -228,27 +245,33 @@ export const baseConfig = async ({
|
|
|
228
245
|
// )
|
|
229
246
|
// })()
|
|
230
247
|
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
248
|
+
if (!productName) {
|
|
249
|
+
try {
|
|
250
|
+
;({ productName } = JSON.parse(
|
|
251
|
+
readFileSync(new URL('package.json', appDir).pathname, {
|
|
252
|
+
encoding: 'utf-8'
|
|
253
|
+
})
|
|
254
|
+
))
|
|
255
|
+
} catch (e) {
|
|
256
|
+
console.error('package.json not found')
|
|
257
|
+
productName = 'Product name'
|
|
258
|
+
}
|
|
259
|
+
} else {
|
|
240
260
|
}
|
|
241
261
|
|
|
242
262
|
const frameworkPlugins = []
|
|
263
|
+
const resolvers = []
|
|
243
264
|
for (const framework of Object.keys(configPluginMap)) {
|
|
244
265
|
if (Object.keys(vitrifyConfig).includes(framework)) {
|
|
245
266
|
const plugin = await configPluginMap[framework]()
|
|
267
|
+
const resolver = await configResolverMap[framework]()
|
|
246
268
|
frameworkPlugins.push(
|
|
247
269
|
await plugin({
|
|
248
270
|
ssr,
|
|
249
271
|
pwa
|
|
250
272
|
})
|
|
251
273
|
)
|
|
274
|
+
resolvers.push(resolver)
|
|
252
275
|
}
|
|
253
276
|
}
|
|
254
277
|
|
|
@@ -316,6 +339,7 @@ export const baseConfig = async ({
|
|
|
316
339
|
sassVariables = config.vitrify?.sass?.variables || {}
|
|
317
340
|
globalSass = config.vitrify?.sass?.global || []
|
|
318
341
|
additionalData = config.vitrify?.sass?.additionalData || []
|
|
342
|
+
|
|
319
343
|
return
|
|
320
344
|
},
|
|
321
345
|
configureServer(server) {
|
|
@@ -395,7 +419,17 @@ export const baseConfig = async ({
|
|
|
395
419
|
}
|
|
396
420
|
return null
|
|
397
421
|
}
|
|
398
|
-
}
|
|
422
|
+
},
|
|
423
|
+
Components({
|
|
424
|
+
exclude: [
|
|
425
|
+
new RegExp(
|
|
426
|
+
`[\\/]node_modules[\\/].*[\\/]!(${serverModules.join('|')})`
|
|
427
|
+
),
|
|
428
|
+
/[\\/]\.git[\\/]/,
|
|
429
|
+
/[\\/]\.nuxt[\\/]/
|
|
430
|
+
],
|
|
431
|
+
resolvers
|
|
432
|
+
})
|
|
399
433
|
]
|
|
400
434
|
if (command !== 'test') {
|
|
401
435
|
plugins.unshift({
|
|
@@ -428,30 +462,31 @@ export const baseConfig = async ({
|
|
|
428
462
|
entry = new URL('csr/entry.ts', frameworkDir).pathname
|
|
429
463
|
}
|
|
430
464
|
const entryScript = `<script type="module" src="${entry}"></script>`
|
|
431
|
-
html = html
|
|
432
|
-
|
|
433
|
-
|
|
465
|
+
// html = html.replace('<!--entry-script-->', entryScript)
|
|
466
|
+
html = appendToBody(entryScript, html)
|
|
467
|
+
if (productName) html = addOrReplaceTitle(productName, html)
|
|
468
|
+
// html = html.replace('<!--product-name-->', productName)
|
|
434
469
|
return html
|
|
435
470
|
}
|
|
436
471
|
}
|
|
437
472
|
})
|
|
438
473
|
|
|
439
|
-
plugins.unshift({
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
})
|
|
474
|
+
// plugins.unshift({
|
|
475
|
+
// name: 'product-name',
|
|
476
|
+
// enforce: 'post',
|
|
477
|
+
// config: (config: VitrifyConfig, env) => {
|
|
478
|
+
// if (config.vitrify?.productName)
|
|
479
|
+
// productName = config.vitrify?.productName
|
|
480
|
+
// return
|
|
481
|
+
// },
|
|
482
|
+
// transformIndexHtml: {
|
|
483
|
+
// enforce: 'post',
|
|
484
|
+
// transform: (html) => {
|
|
485
|
+
// html = html.replace('<!--product-name-->', productName)
|
|
486
|
+
// return html
|
|
487
|
+
// }
|
|
488
|
+
// }
|
|
489
|
+
// })
|
|
455
490
|
|
|
456
491
|
// @ts-ignore
|
|
457
492
|
if (debug) plugins.push(visualizer())
|
|
@@ -6,7 +6,6 @@ import type {
|
|
|
6
6
|
OnMountedHook,
|
|
7
7
|
VitrifyConfig
|
|
8
8
|
} from '../vitrify-config.js'
|
|
9
|
-
import { QuasarResolver } from 'unplugin-vue-components/resolvers'
|
|
10
9
|
import type { VitrifyPlugin } from './index.js'
|
|
11
10
|
export interface QuasarConf {
|
|
12
11
|
ctx?: Record<string, any>
|
|
@@ -78,9 +77,6 @@ export const QuasarPlugin: VitrifyPlugin = async ({
|
|
|
78
77
|
let plugins: string[] = []
|
|
79
78
|
let quasarConf: QuasarConf
|
|
80
79
|
return [
|
|
81
|
-
Components({
|
|
82
|
-
resolvers: [QuasarResolver()]
|
|
83
|
-
}),
|
|
84
80
|
{
|
|
85
81
|
name: 'vite-plugin-quasar-transform',
|
|
86
82
|
enforce: 'pre',
|
|
@@ -2,6 +2,7 @@ import type { Alias, UserConfig } from 'vite'
|
|
|
2
2
|
import type { QuasarConf } from './plugins/quasar.js'
|
|
3
3
|
import type { ComponentInternalInstance } from '@vue/runtime-core'
|
|
4
4
|
import type { FastifyServerOptions } from 'fastify'
|
|
5
|
+
import { ComponentResolver } from 'unplugin-vue-components'
|
|
5
6
|
|
|
6
7
|
export type BootFunction = ({
|
|
7
8
|
app,
|
|
@@ -106,4 +107,8 @@ export interface VitrifyConfig extends UserConfig {
|
|
|
106
107
|
quasar?: QuasarConf
|
|
107
108
|
}
|
|
108
109
|
|
|
110
|
+
export type VitrifyConfigAsync =
|
|
111
|
+
| VitrifyConfig
|
|
112
|
+
| ((mode: string, command: string) => Promise<VitrifyConfig>)
|
|
113
|
+
|
|
109
114
|
export const defineConfig = (config: VitrifyConfig) => config
|