vitrify 0.2.5 → 0.5.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/README.md +2 -2
- package/dist/app-urls.js +1 -2
- package/dist/bin/build.js +9 -51
- package/dist/bin/cli.js +31 -9
- package/dist/bin/dev.js +72 -70
- package/dist/frameworks/vue/fastify-csr-plugin.js +38 -0
- package/dist/frameworks/vue/fastify-ssr-plugin.js +83 -25
- package/dist/frameworks/vue/prerender.js +3 -3
- package/dist/frameworks/vue/server.js +10 -11
- package/dist/helpers/collect-css-ssr.js +61 -0
- package/dist/helpers/logger.js +0 -72
- package/dist/index.js +310 -130
- package/dist/plugins/quasar.js +34 -111
- package/dist/types/bin/build.d.ts +2 -2
- package/dist/types/bin/dev.d.ts +42 -4
- package/dist/types/frameworks/vue/fastify-csr-plugin.d.ts +17 -0
- package/dist/types/frameworks/vue/fastify-ssr-plugin.d.ts +6 -3
- package/dist/types/frameworks/vue/prerender.d.ts +3 -3
- package/dist/types/frameworks/vue/server.d.ts +10 -5
- package/dist/types/helpers/collect-css-ssr.d.ts +14 -0
- package/dist/types/helpers/logger.d.ts +0 -19
- package/dist/types/helpers/routes.d.ts +1 -1
- package/dist/types/index.d.ts +4 -2
- package/dist/types/plugins/index.d.ts +1 -1
- package/dist/types/vitrify-config.d.ts +33 -17
- package/package.json +33 -32
- package/src/node/app-urls.ts +1 -2
- package/src/node/bin/build.ts +11 -57
- package/src/node/bin/cli.ts +38 -10
- package/src/node/bin/dev.ts +106 -80
- package/src/node/bin/test.ts +0 -3
- package/src/node/frameworks/vue/fastify-csr-plugin.ts +72 -0
- package/src/node/frameworks/vue/fastify-ssr-plugin.ts +99 -28
- package/src/node/frameworks/vue/prerender.ts +5 -5
- package/src/node/frameworks/vue/server.ts +24 -17
- package/src/node/helpers/collect-css-ssr.ts +85 -0
- package/src/node/helpers/logger.ts +0 -87
- package/src/node/index.ts +353 -146
- package/src/node/plugins/index.ts +1 -1
- package/src/node/plugins/quasar.ts +39 -116
- package/src/node/vitrify-config.ts +44 -17
- package/src/vite/fastify/entry.ts +11 -0
- package/src/vite/fastify/server.ts +12 -0
- package/src/vite/vue/csr/app.ts +25 -0
- package/src/vite/vue/csr/fastify-csr-plugin.ts +3 -0
- package/src/vite/vue/csr/server.ts +8 -0
- package/src/vite/vue/index.html +1 -0
- package/src/vite/vue/main.ts +5 -20
- package/src/vite/vue/ssr/app.ts +25 -0
- package/src/vite/vue/ssr/entry-server.ts +13 -1
- package/src/vite/vue/ssr/fastify-ssr-plugin.ts +2 -118
- package/src/vite/vue/ssr/prerender.ts +2 -2
- package/src/vite/vue/ssr/server.ts +24 -15
- package/src/node/helpers/ssr.ts.bak +0 -52
package/README.md
CHANGED
|
@@ -3,12 +3,12 @@
|
|
|
3
3
|
> Pre-configured Vite CLI for your framework
|
|
4
4
|
|
|
5
5
|
- Use a simple configuration file to configure and integrate required Vite plugins into your project.
|
|
6
|
-
- Client-Side Rendering (CSR)
|
|
6
|
+
- Client-Side Rendering (CSR), Server-Side Rendering (SSR) and Fastify server build and development modes.
|
|
7
7
|
|
|
8
8
|
## Features
|
|
9
9
|
|
|
10
10
|
- Uses [Fastify](https://github.com/fastify/fastify-vite) for the development server and SSR production server.
|
|
11
|
-
|
|
11
|
+
- Generates a Fastify plugin to serve your server-side rendered application.
|
|
12
12
|
- A [`run`](./src/node/bin/run.ts) command which injects context such as application paths into the script which you want to run.
|
|
13
13
|
- A [`test`](./src/node/bin/test.ts) command which runs a pre-configured [Vitest](https://github.com/vitest-dev/vitest) instance.
|
|
14
14
|
- An [extra plugin layer](./src/node/plugins/index.ts) which provides some extra context such as the SSR mode (client or server) and PWA mode. Used for UI frameworks which render differently based on these settings.
|
package/dist/app-urls.js
CHANGED
|
@@ -12,10 +12,9 @@ export const getCliDir = () => getPkgJsonDir(new URL('./', import.meta.url));
|
|
|
12
12
|
export const getCliViteDir = (cliDir) => new URL('src/vite/', cliDir);
|
|
13
13
|
export const getSrcDir = (appDir) => new URL('src/', appDir);
|
|
14
14
|
export const getCwd = () => new URL(`file://${process.cwd()}/`);
|
|
15
|
-
// export const quasarDir = getPkgJsonDir(new URL('./', await resolve('quasar', appDir.href)))
|
|
16
15
|
export const parsePath = (path, basePath) => {
|
|
17
16
|
if (path) {
|
|
18
|
-
if (path.slice(-1) !== '/')
|
|
17
|
+
if (!path.includes('.') && path.slice(-1) !== '/')
|
|
19
18
|
path += '/';
|
|
20
19
|
if (path.startsWith('.')) {
|
|
21
20
|
return new URL(path, basePath);
|
package/dist/bin/build.js
CHANGED
|
@@ -1,56 +1,14 @@
|
|
|
1
1
|
#!/usr/bin/node --experimental-specifier-resolution=node
|
|
2
2
|
import { baseConfig } from '../index.js';
|
|
3
|
-
// import { promises as fs } from 'fs'
|
|
4
|
-
// import { routesToPaths } from '../helpers/routes.js'
|
|
5
3
|
import { build as viteBuild } from 'vite';
|
|
6
|
-
// import { SsrFunction } from '../vitrify-config.js'
|
|
7
|
-
// export const prerender = async ({
|
|
8
|
-
// outDir,
|
|
9
|
-
// templatePath,
|
|
10
|
-
// manifestPath,
|
|
11
|
-
// entryServerPath,
|
|
12
|
-
// injectSsrContext
|
|
13
|
-
// }: {
|
|
14
|
-
// outDir: string
|
|
15
|
-
// templatePath: string
|
|
16
|
-
// manifestPath: string
|
|
17
|
-
// entryServerPath: string
|
|
18
|
-
// injectSsrContext: SsrFunction
|
|
19
|
-
// }) => {
|
|
20
|
-
// let template
|
|
21
|
-
// let manifest
|
|
22
|
-
// const promises = []
|
|
23
|
-
// template = (await fs.readFile(templatePath)).toString()
|
|
24
|
-
// manifest = await fs.readFile(manifestPath)
|
|
25
|
-
// let { render, getRoutes } = await import(entryServerPath)
|
|
26
|
-
// const routes = await getRoutes()
|
|
27
|
-
// const paths = routesToPaths(routes).filter(
|
|
28
|
-
// (i) => !i.includes(':') && !i.includes('*')
|
|
29
|
-
// )
|
|
30
|
-
// for (let url of paths) {
|
|
31
|
-
// const filename =
|
|
32
|
-
// (url.endsWith('/') ? 'index' : url.replace(/^\//g, '')) + '.html'
|
|
33
|
-
// console.log(`Generating ${filename}`)
|
|
34
|
-
// const ssrContext = {
|
|
35
|
-
// req: { headers: {}, url },
|
|
36
|
-
// res: {}
|
|
37
|
-
// }
|
|
38
|
-
// const [appHtml, preloadLinks] = await render(url, manifest, ssrContext)
|
|
39
|
-
// let html = template
|
|
40
|
-
// .replace(`<!--preload-links-->`, preloadLinks)
|
|
41
|
-
// .replace(`<!--app-html-->`, appHtml)
|
|
42
|
-
// html = injectSsrContext(html, ssrContext)
|
|
43
|
-
// promises.push(fs.writeFile(outDir + filename, html, 'utf-8'))
|
|
44
|
-
// }
|
|
45
|
-
// return Promise.all(promises)
|
|
46
|
-
// }
|
|
47
4
|
export async function build(opts) {
|
|
48
5
|
const config = await baseConfig({
|
|
49
6
|
command: 'build',
|
|
50
7
|
mode: 'production',
|
|
51
8
|
ssr: opts?.ssr,
|
|
52
9
|
appDir: opts.appDir,
|
|
53
|
-
publicDir: opts.publicDir
|
|
10
|
+
publicDir: opts.publicDir,
|
|
11
|
+
base: opts.base
|
|
54
12
|
});
|
|
55
13
|
config.build = {
|
|
56
14
|
...config.build,
|
|
@@ -58,15 +16,15 @@ export async function build(opts) {
|
|
|
58
16
|
outDir: opts.outDir,
|
|
59
17
|
emptyOutDir: !!opts.outDir
|
|
60
18
|
};
|
|
61
|
-
if (opts.base) {
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
}
|
|
19
|
+
// if (opts.base) {
|
|
20
|
+
// config.define = {
|
|
21
|
+
// ...config.define,
|
|
22
|
+
// __BASE_URL__: `'${opts.base}'`
|
|
23
|
+
// }
|
|
24
|
+
// }
|
|
67
25
|
return viteBuild({
|
|
68
26
|
configFile: false,
|
|
69
|
-
base: opts.base,
|
|
27
|
+
// base: opts.base,
|
|
70
28
|
// logLevel: 'silent',
|
|
71
29
|
...config
|
|
72
30
|
});
|
package/dist/bin/cli.js
CHANGED
|
@@ -14,7 +14,7 @@ cli
|
|
|
14
14
|
.action(async (options) => {
|
|
15
15
|
const { build } = await import('./build.js');
|
|
16
16
|
let appDir;
|
|
17
|
-
let prerender,
|
|
17
|
+
let prerender, onRenderedHooks;
|
|
18
18
|
if (options.appDir) {
|
|
19
19
|
if (options.appDir.slice(-1) !== '/')
|
|
20
20
|
options.appDir += '/';
|
|
@@ -33,7 +33,14 @@ cli
|
|
|
33
33
|
case 'csr':
|
|
34
34
|
await build({
|
|
35
35
|
...args,
|
|
36
|
-
outDir: new URL('
|
|
36
|
+
outDir: new URL('csr/', baseOutDir).pathname
|
|
37
|
+
});
|
|
38
|
+
break;
|
|
39
|
+
case 'fastify':
|
|
40
|
+
await build({
|
|
41
|
+
ssr: 'fastify',
|
|
42
|
+
...args,
|
|
43
|
+
outDir: new URL('server/', baseOutDir).pathname
|
|
37
44
|
});
|
|
38
45
|
break;
|
|
39
46
|
case 'ssr':
|
|
@@ -59,7 +66,7 @@ cli
|
|
|
59
66
|
...args,
|
|
60
67
|
outDir: new URL('ssr/server/', baseOutDir).pathname
|
|
61
68
|
});
|
|
62
|
-
({ prerender,
|
|
69
|
+
({ prerender, onRenderedHooks } = await import(new URL('ssr/server/prerender.mjs', baseOutDir).pathname));
|
|
63
70
|
prerender({
|
|
64
71
|
outDir: new URL('static/', baseOutDir).pathname,
|
|
65
72
|
templatePath: new URL('static/index.html', baseOutDir).pathname,
|
|
@@ -67,7 +74,7 @@ cli
|
|
|
67
74
|
.pathname,
|
|
68
75
|
entryServerPath: new URL('ssr/server/entry-server.mjs', baseOutDir)
|
|
69
76
|
.pathname,
|
|
70
|
-
|
|
77
|
+
onRenderedHooks
|
|
71
78
|
});
|
|
72
79
|
break;
|
|
73
80
|
default:
|
|
@@ -80,20 +87,35 @@ cli
|
|
|
80
87
|
.option('-m, --mode [mode]', 'Development server mode', { default: 'csr' })
|
|
81
88
|
.option('--host [host]', 'Specify which IP addresses the server should listen on', { default: '127.0.0.1' })
|
|
82
89
|
.option('--appDir [appDir]', 'Application directory')
|
|
90
|
+
.option('--app [app]', 'Fastify app instance path')
|
|
83
91
|
.option('--publicDir [publicDir]', 'Public directory')
|
|
84
92
|
.action(async (options) => {
|
|
85
93
|
let server;
|
|
86
|
-
let
|
|
94
|
+
let config;
|
|
87
95
|
if (options.host === true) {
|
|
88
96
|
options.host = '0.0.0.0';
|
|
89
97
|
}
|
|
90
98
|
const { createServer } = await import('./dev.js');
|
|
91
99
|
const cwd = (await import('../app-urls.js')).getCwd();
|
|
100
|
+
let app;
|
|
101
|
+
const appPath = parsePath(options.app, cwd)?.pathname;
|
|
102
|
+
if (appPath) {
|
|
103
|
+
app = await import(appPath);
|
|
104
|
+
}
|
|
92
105
|
switch (options.mode) {
|
|
93
106
|
case 'ssr':
|
|
94
107
|
;
|
|
95
|
-
({ server,
|
|
96
|
-
|
|
108
|
+
({ server, config } = await createServer({
|
|
109
|
+
ssr: 'ssr',
|
|
110
|
+
host: options.host,
|
|
111
|
+
appDir: parsePath(options.appDir, cwd),
|
|
112
|
+
publicDir: parsePath(options.publicDir, cwd)
|
|
113
|
+
}));
|
|
114
|
+
break;
|
|
115
|
+
case 'fastify':
|
|
116
|
+
;
|
|
117
|
+
({ server, config } = await createServer({
|
|
118
|
+
ssr: 'fastify',
|
|
97
119
|
host: options.host,
|
|
98
120
|
appDir: parsePath(options.appDir, cwd),
|
|
99
121
|
publicDir: parsePath(options.publicDir, cwd)
|
|
@@ -101,7 +123,7 @@ cli
|
|
|
101
123
|
break;
|
|
102
124
|
default:
|
|
103
125
|
;
|
|
104
|
-
({ server,
|
|
126
|
+
({ server, config } = await createServer({
|
|
105
127
|
host: options.host,
|
|
106
128
|
appDir: parsePath(options.appDir, cwd),
|
|
107
129
|
publicDir: parsePath(options.publicDir, cwd)
|
|
@@ -109,7 +131,7 @@ cli
|
|
|
109
131
|
break;
|
|
110
132
|
}
|
|
111
133
|
console.log('Dev server running at:');
|
|
112
|
-
printHttpServerUrls(server,
|
|
134
|
+
printHttpServerUrls(server, config);
|
|
113
135
|
});
|
|
114
136
|
cli.command('test').action(async (options) => {
|
|
115
137
|
const { test } = await import('./test.js');
|
package/dist/bin/dev.js
CHANGED
|
@@ -1,34 +1,46 @@
|
|
|
1
1
|
import { searchForWorkspaceRoot } from 'vite';
|
|
2
2
|
import { baseConfig } from '../index.js';
|
|
3
3
|
import fastify from 'fastify';
|
|
4
|
-
import {
|
|
5
|
-
export async function
|
|
6
|
-
|
|
7
|
-
|
|
4
|
+
import { fastifySsrPlugin } from '../frameworks/vue/fastify-ssr-plugin.js';
|
|
5
|
+
export async function createVitrifyDevServer({ port = 3000, logLevel = 'info',
|
|
6
|
+
// mode = 'csr',
|
|
7
|
+
ssr, framework = 'vue', host, appDir, publicDir, base }) {
|
|
8
|
+
const { getAppDir, getCliDir, getCliViteDir, getCwd } = await import('../app-urls.js');
|
|
8
9
|
const cliDir = getCliDir();
|
|
9
10
|
if (!appDir)
|
|
10
11
|
appDir = getAppDir();
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
12
|
+
let config = {};
|
|
13
|
+
let ssrMode;
|
|
14
|
+
if (ssr === 'ssr')
|
|
15
|
+
ssrMode = 'server';
|
|
16
|
+
if (ssr === 'fastify')
|
|
17
|
+
ssrMode = 'fastify';
|
|
18
|
+
config = await baseConfig({
|
|
19
|
+
framework,
|
|
20
|
+
ssr: ssrMode,
|
|
17
21
|
command: 'dev',
|
|
18
22
|
mode: 'development',
|
|
19
23
|
appDir,
|
|
20
|
-
publicDir
|
|
24
|
+
publicDir,
|
|
25
|
+
base
|
|
21
26
|
});
|
|
22
27
|
config.logLevel = logLevel;
|
|
28
|
+
console.log(searchForWorkspaceRoot(appDir.pathname));
|
|
23
29
|
config.server = {
|
|
30
|
+
https: config.server?.https,
|
|
31
|
+
hmr: {
|
|
32
|
+
protocol: config.server?.https ? 'wss' : 'ws'
|
|
33
|
+
},
|
|
24
34
|
port,
|
|
25
|
-
middlewareMode: mode === 'ssr' ? 'ssr' : undefined,
|
|
35
|
+
// middlewareMode: mode === 'ssr' ? 'ssr' : undefined,
|
|
36
|
+
middlewareMode: ssr ? 'ssr' : false,
|
|
26
37
|
fs: {
|
|
38
|
+
strict: false,
|
|
27
39
|
allow: [
|
|
28
40
|
searchForWorkspaceRoot(process.cwd()),
|
|
29
41
|
searchForWorkspaceRoot(appDir.pathname),
|
|
30
|
-
searchForWorkspaceRoot(cliDir.pathname)
|
|
31
|
-
|
|
42
|
+
searchForWorkspaceRoot(cliDir.pathname),
|
|
43
|
+
appDir.pathname
|
|
32
44
|
]
|
|
33
45
|
},
|
|
34
46
|
watch: {
|
|
@@ -39,70 +51,60 @@ export async function createServer({ port = 3000, logLevel = 'info', mode = 'csr
|
|
|
39
51
|
},
|
|
40
52
|
host
|
|
41
53
|
};
|
|
42
|
-
const
|
|
54
|
+
const vitrifyDevServer = await (await import('vite')).createServer({
|
|
43
55
|
configFile: false,
|
|
44
56
|
...config
|
|
45
57
|
});
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
58
|
+
return vitrifyDevServer;
|
|
59
|
+
}
|
|
60
|
+
export async function createServer({ port = 3000, logLevel = 'info',
|
|
61
|
+
// mode = 'csr',
|
|
62
|
+
ssr, framework = 'vue', host, appDir, publicDir }) {
|
|
63
|
+
const { getAppDir, getCliDir, getCliViteDir, getCwd } = await import('../app-urls.js');
|
|
64
|
+
appDir = appDir || getAppDir();
|
|
65
|
+
const cliDir = getCliDir();
|
|
66
|
+
const vite = await createVitrifyDevServer({
|
|
67
|
+
port,
|
|
68
|
+
logLevel,
|
|
69
|
+
ssr,
|
|
70
|
+
framework,
|
|
71
|
+
host,
|
|
72
|
+
appDir,
|
|
73
|
+
publicDir
|
|
74
|
+
});
|
|
75
|
+
let setup;
|
|
50
76
|
let server;
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
77
|
+
console.log(`Development mode: ${ssr ? ssr : 'csr'}`);
|
|
78
|
+
if (ssr) {
|
|
79
|
+
const entryUrl = ssr === 'fastify'
|
|
80
|
+
? new URL('src/vite/fastify/entry.ts', cliDir).pathname
|
|
81
|
+
: new URL(`src/vite/${framework}/ssr/entry-server.ts`, cliDir).pathname;
|
|
82
|
+
({ setup } = await vite.ssrLoadModule(entryUrl));
|
|
83
|
+
const app = fastify({
|
|
84
|
+
logger: true,
|
|
85
|
+
https: vite.config.server.https
|
|
86
|
+
});
|
|
87
|
+
if (process.env)
|
|
88
|
+
process.env.MODE = 'development';
|
|
89
|
+
if (setup) {
|
|
90
|
+
await setup({
|
|
91
|
+
fastify: app
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
if (ssr === 'ssr') {
|
|
95
|
+
await app.register(fastifySsrPlugin, {
|
|
96
|
+
appDir,
|
|
97
|
+
mode: 'development'
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
await app.listen({
|
|
101
|
+
port: Number(port || 3000),
|
|
102
|
+
host
|
|
59
103
|
});
|
|
60
|
-
// await app.register(middie)
|
|
61
|
-
// app.use(vite.middlewares)
|
|
62
|
-
// app.get('*', async (req, res) => {
|
|
63
|
-
// try {
|
|
64
|
-
// // const url = req.originalUrl
|
|
65
|
-
// const url = req.raw.url
|
|
66
|
-
// let template
|
|
67
|
-
// let render
|
|
68
|
-
// const ssrContext = {
|
|
69
|
-
// req,
|
|
70
|
-
// res
|
|
71
|
-
// }
|
|
72
|
-
// // always read fresh template in dev
|
|
73
|
-
// // template = readFileSync(resolve('index.html'), 'utf-8')
|
|
74
|
-
// template = readFileSync(new URL('index.html', cliDir)).toString()
|
|
75
|
-
// // template = await vite.transformIndexHtml(url, template)
|
|
76
|
-
// const entryUrl = new URL('ssr/entry-server.ts', cliDir).pathname
|
|
77
|
-
// render = (await vite.ssrLoadModule(entryUrl)).render
|
|
78
|
-
// let manifest
|
|
79
|
-
// // TODO: https://github.com/vitejs/vite/issues/2282
|
|
80
|
-
// try {
|
|
81
|
-
// manifest = {}
|
|
82
|
-
// } catch (e) {
|
|
83
|
-
// manifest = {}
|
|
84
|
-
// }
|
|
85
|
-
// const [appHtml, preloadLinks] = await render(url, manifest, ssrContext)
|
|
86
|
-
// const html = template
|
|
87
|
-
// .replace(`<!--preload-links-->`, preloadLinks)
|
|
88
|
-
// .replace(`<!--app-html-->`, appHtml)
|
|
89
|
-
// .replace('<!--product-name-->', productName)
|
|
90
|
-
// res.code(200)
|
|
91
|
-
// res.type('text/html')
|
|
92
|
-
// res.send(html)
|
|
93
|
-
// // res.status(200).set({ 'Content-Type': 'text/html' }).end(html)
|
|
94
|
-
// } catch (e: any) {
|
|
95
|
-
// console.error(e.stack)
|
|
96
|
-
// vite && vite.ssrFixStacktrace(e)
|
|
97
|
-
// res.code(500)
|
|
98
|
-
// res.send(e.stack)
|
|
99
|
-
// }
|
|
100
|
-
// })
|
|
101
|
-
await app.listen(port || 3000, host);
|
|
102
104
|
server = app.server;
|
|
103
105
|
}
|
|
104
106
|
else {
|
|
105
107
|
server = (await vite.listen()).httpServer;
|
|
106
108
|
}
|
|
107
|
-
return { server, vite };
|
|
109
|
+
return { server, config: vite.config };
|
|
108
110
|
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import fastifyStatic from '@fastify/static';
|
|
2
|
+
const fastifyCsrPlugin = async (fastify, options, done) => {
|
|
3
|
+
options.vitrifyDir =
|
|
4
|
+
options.vitrifyDir || (await import('vitrify')).vitrifyDir;
|
|
5
|
+
const frameworkDir = new URL('src/vite/vue/', options.vitrifyDir);
|
|
6
|
+
options.baseUrl = options.baseUrl || '/';
|
|
7
|
+
options.mode = options.mode || process.env.MODE || import.meta.env.MODE;
|
|
8
|
+
options.appDir = options.appDir || new URL('../../..', import.meta.url);
|
|
9
|
+
if (options.baseUrl.charAt(options.baseUrl.length - 1) !== '/' ||
|
|
10
|
+
options.baseUrl.charAt(0) !== '/')
|
|
11
|
+
throw new Error('baseUrl should start and end with a /');
|
|
12
|
+
if (options.mode === 'development') {
|
|
13
|
+
options.appDir = options.appDir || new URL('../..', import.meta.url);
|
|
14
|
+
const { createVitrifyDevServer } = await import('vitrify/dev');
|
|
15
|
+
const vite = await createVitrifyDevServer({
|
|
16
|
+
appDir: options.appDir,
|
|
17
|
+
framework: 'vue',
|
|
18
|
+
base: options.baseUrl
|
|
19
|
+
});
|
|
20
|
+
console.log('Dev mode');
|
|
21
|
+
if (!('use' in fastify)) {
|
|
22
|
+
const middie = (await import('@fastify/middie')).default;
|
|
23
|
+
await fastify.register(middie);
|
|
24
|
+
}
|
|
25
|
+
fastify.use(vite.middlewares);
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
options.appDir = options.appDir || new URL('../../..', import.meta.url);
|
|
29
|
+
fastify.register(fastifyStatic, {
|
|
30
|
+
root: new URL('./dist/csr', options.appDir).pathname,
|
|
31
|
+
wildcard: false,
|
|
32
|
+
index: false,
|
|
33
|
+
prefix: options.baseUrl
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
done();
|
|
37
|
+
};
|
|
38
|
+
export { fastifyCsrPlugin };
|
|
@@ -1,26 +1,78 @@
|
|
|
1
|
-
import fastifyStatic from 'fastify
|
|
1
|
+
import fastifyStatic from '@fastify/static';
|
|
2
2
|
import { readFileSync } from 'fs';
|
|
3
|
+
import { componentsModules, collectCss } from '../../helpers/collect-css-ssr.js';
|
|
3
4
|
const fastifySsrPlugin = async (fastify, options, done) => {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
5
|
+
options.vitrifyDir =
|
|
6
|
+
options.vitrifyDir || (await import('vitrify')).vitrifyDir;
|
|
7
|
+
const frameworkDir = new URL('src/vite/vue/', options.vitrifyDir);
|
|
8
|
+
options.baseUrl = options.baseUrl || '/';
|
|
9
|
+
options.mode = options.mode || process.env.MODE || import.meta.env.MODE;
|
|
10
|
+
options.appDir = options.appDir || new URL('../../..', import.meta.url);
|
|
11
|
+
if (options.baseUrl.charAt(options.baseUrl.length - 1) !== '/' ||
|
|
12
|
+
options.baseUrl.charAt(0) !== '/')
|
|
13
|
+
throw new Error('baseUrl should start and end with a /');
|
|
14
|
+
if (options.mode === 'development') {
|
|
15
|
+
// if (!options.vitrifyDir)
|
|
16
|
+
// throw new Error('Option vitrifyDir cannot be undefined')
|
|
17
|
+
// if (!options.vite) throw new Error('Option vite cannot be undefined')
|
|
18
|
+
// const { resolve } = await import('import-meta-resolve')
|
|
19
|
+
// const cliDir = new URL('../', await resolve('vitrify', import.meta.url))
|
|
20
|
+
options.appDir = options.appDir || new URL('../../..', import.meta.url);
|
|
21
|
+
const { createVitrifyDevServer } = await import('vitrify/dev');
|
|
22
|
+
const vite = await createVitrifyDevServer({
|
|
23
|
+
appDir: options.appDir,
|
|
24
|
+
ssr: 'ssr',
|
|
25
|
+
framework: 'vue',
|
|
26
|
+
base: options.baseUrl
|
|
27
|
+
});
|
|
28
|
+
// const { createServer, searchForWorkspaceRoot } = await import('vite')
|
|
29
|
+
// const { baseConfig } = await import('vitrify')
|
|
30
|
+
// const cliDir = options.vitrifyDir
|
|
31
|
+
// const config = await baseConfig({
|
|
32
|
+
// ssr: 'server',
|
|
33
|
+
// command: 'dev',
|
|
34
|
+
// mode: 'development',
|
|
35
|
+
// appDir: options.appDir,
|
|
36
|
+
// publicDir: options.publicDir || new URL('public', options.appDir)
|
|
37
|
+
// })
|
|
38
|
+
// config.server = {
|
|
39
|
+
// middlewareMode: true,
|
|
40
|
+
// fs: {
|
|
41
|
+
// allow: [
|
|
42
|
+
// searchForWorkspaceRoot(process.cwd()),
|
|
43
|
+
// searchForWorkspaceRoot(options.appDir.pathname),
|
|
44
|
+
// searchForWorkspaceRoot(cliDir.pathname)
|
|
45
|
+
// // appDir.pathname,
|
|
46
|
+
// ]
|
|
47
|
+
// },
|
|
48
|
+
// watch: {
|
|
49
|
+
// // During tests we edit the files too fast and sometimes chokidar
|
|
50
|
+
// // misses change events, so enforce polling for consistency
|
|
51
|
+
// usePolling: true,
|
|
52
|
+
// interval: 100
|
|
53
|
+
// }
|
|
54
|
+
// }
|
|
55
|
+
// const vite = await createServer({
|
|
56
|
+
// configFile: false,
|
|
57
|
+
// ...config
|
|
58
|
+
// })
|
|
59
|
+
console.log('Dev mode');
|
|
60
|
+
if (!('use' in fastify)) {
|
|
61
|
+
const middie = (await import('@fastify/middie')).default;
|
|
62
|
+
await fastify.register(middie);
|
|
63
|
+
}
|
|
64
|
+
fastify.use(vite.middlewares);
|
|
65
|
+
fastify.get(`${options.baseUrl}*`, async (req, res) => {
|
|
11
66
|
try {
|
|
12
|
-
|
|
13
|
-
const url = req.raw.url;
|
|
67
|
+
const url = req.raw.url?.replace(options.baseUrl, '/');
|
|
14
68
|
const ssrContext = {
|
|
15
69
|
req,
|
|
16
70
|
res
|
|
17
71
|
};
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
const
|
|
21
|
-
|
|
22
|
-
const entryUrl = new URL('ssr/entry-server.ts', options.cliDir).pathname;
|
|
23
|
-
const render = (await options.vite.ssrLoadModule(entryUrl)).render;
|
|
72
|
+
let template = readFileSync(new URL('index.html', frameworkDir)).toString();
|
|
73
|
+
template = await vite.transformIndexHtml(url, template);
|
|
74
|
+
const entryUrl = new URL('ssr/entry-server.ts', frameworkDir).pathname;
|
|
75
|
+
const render = (await vite.ssrLoadModule(entryUrl)).render;
|
|
24
76
|
let manifest;
|
|
25
77
|
// TODO: https://github.com/vitejs/vite/issues/2282
|
|
26
78
|
try {
|
|
@@ -29,11 +81,20 @@ const fastifySsrPlugin = async (fastify, options, done) => {
|
|
|
29
81
|
catch (e) {
|
|
30
82
|
manifest = {};
|
|
31
83
|
}
|
|
84
|
+
const cssModules = [entryUrl];
|
|
85
|
+
// // @ts-ignore
|
|
86
|
+
// if (options.vite?.config.vitrify!.globalCss)
|
|
87
|
+
// cssModules.push(...options.vite?.config.vitrify.globalCss)
|
|
88
|
+
const matchedModules = componentsModules(cssModules, vite);
|
|
89
|
+
const css = collectCss({
|
|
90
|
+
mods: matchedModules
|
|
91
|
+
});
|
|
32
92
|
const [appHtml, preloadLinks] = await render(url, manifest, ssrContext);
|
|
33
93
|
const html = template
|
|
34
94
|
.replace(`<!--preload-links-->`, preloadLinks)
|
|
35
95
|
.replace(`<!--app-html-->`, appHtml)
|
|
36
|
-
.replace('<!--product-name-->', options.productName || 'Product name')
|
|
96
|
+
.replace('<!--product-name-->', options.productName || 'Product name')
|
|
97
|
+
.replace('<!--dev-ssr-css-->', css);
|
|
37
98
|
res.code(200);
|
|
38
99
|
res.type('text/html');
|
|
39
100
|
res.send(html);
|
|
@@ -41,14 +102,14 @@ const fastifySsrPlugin = async (fastify, options, done) => {
|
|
|
41
102
|
}
|
|
42
103
|
catch (e) {
|
|
43
104
|
console.error(e.stack);
|
|
44
|
-
|
|
105
|
+
vite && vite.ssrFixStacktrace(e);
|
|
45
106
|
res.code(500);
|
|
46
107
|
res.send(e.stack);
|
|
47
108
|
}
|
|
48
109
|
});
|
|
49
110
|
}
|
|
50
111
|
else {
|
|
51
|
-
options.
|
|
112
|
+
options.appDir = options.appDir || new URL('../../..', import.meta.url);
|
|
52
113
|
fastify.register(fastifyStatic, {
|
|
53
114
|
root: new URL('./dist/ssr/client', options.appDir).pathname,
|
|
54
115
|
wildcard: false,
|
|
@@ -56,16 +117,13 @@ const fastifySsrPlugin = async (fastify, options, done) => {
|
|
|
56
117
|
prefix: options.baseUrl
|
|
57
118
|
});
|
|
58
119
|
fastify.get(`${options.baseUrl}*`, async (req, res) => {
|
|
59
|
-
const url = req.raw.url;
|
|
120
|
+
const url = req.raw.url?.replace(options.baseUrl, '/');
|
|
60
121
|
const provide = options.provide ? await options.provide(req, res) : {};
|
|
61
122
|
const ssrContext = {
|
|
62
123
|
req,
|
|
63
124
|
res,
|
|
64
125
|
provide
|
|
65
126
|
};
|
|
66
|
-
// template = readFileSync(new URL('../client/index.html', import.meta.url).pathname).toString()
|
|
67
|
-
// manifest = JSON.parse(readFileSync(new URL('../client/ssr-manifest.json', import.meta.url)).toString())
|
|
68
|
-
// render = (await import(new URL('./entry-server.mjs', import.meta.url).pathname)).render
|
|
69
127
|
const template = readFileSync(new URL('./dist/ssr/client/index.html', options.appDir).pathname).toString();
|
|
70
128
|
const manifest = JSON.parse(readFileSync(new URL('./dist/ssr/client/ssr-manifest.json', options.appDir)).toString());
|
|
71
129
|
const render = (await import(new URL('./dist/ssr/server/entry-server.mjs', options.appDir).pathname)).render;
|
|
@@ -76,8 +134,8 @@ const fastifySsrPlugin = async (fastify, options, done) => {
|
|
|
76
134
|
let html = template
|
|
77
135
|
.replace(`<!--preload-links-->`, preloadLinks)
|
|
78
136
|
.replace(`<!--app-html-->`, appHtml);
|
|
79
|
-
if (options.
|
|
80
|
-
for (const ssrFunction of options.
|
|
137
|
+
if (options.onRendered?.length) {
|
|
138
|
+
for (const ssrFunction of options.onRendered) {
|
|
81
139
|
html = ssrFunction(html, ssrContext);
|
|
82
140
|
}
|
|
83
141
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { promises as fs } from 'fs';
|
|
2
2
|
import { routesToPaths } from '../../helpers/routes.js';
|
|
3
|
-
export const prerender = async ({ outDir, templatePath, manifestPath, entryServerPath,
|
|
3
|
+
export const prerender = async ({ outDir, templatePath, manifestPath, entryServerPath, onRenderedHooks }) => {
|
|
4
4
|
const promises = [];
|
|
5
5
|
const template = (await fs.readFile(templatePath)).toString();
|
|
6
6
|
const manifest = await fs.readFile(manifestPath);
|
|
@@ -18,8 +18,8 @@ export const prerender = async ({ outDir, templatePath, manifestPath, entryServe
|
|
|
18
18
|
let html = template
|
|
19
19
|
.replace(`<!--preload-links-->`, preloadLinks)
|
|
20
20
|
.replace(`<!--app-html-->`, appHtml);
|
|
21
|
-
if (
|
|
22
|
-
for (const ssrFunction of
|
|
21
|
+
if (onRenderedHooks?.length) {
|
|
22
|
+
for (const ssrFunction of onRenderedHooks) {
|
|
23
23
|
html = ssrFunction(html, ssrContext);
|
|
24
24
|
}
|
|
25
25
|
}
|
|
@@ -1,20 +1,19 @@
|
|
|
1
1
|
import fastify from 'fastify';
|
|
2
|
-
|
|
3
|
-
import { fastifySsrPlugin } from './fastify-ssr-plugin.js';
|
|
4
|
-
// import { getPkgJsonDir } from '../app-urls.js'
|
|
5
|
-
export const createApp = ({ setup, appDir, baseUrl, ssrFunctions }) => {
|
|
2
|
+
export const createApp = ({ onSetup, appDir, baseUrl, onRendered, fastifyPlugin, vitrifyDir, mode }) => {
|
|
6
3
|
const app = fastify({
|
|
7
4
|
logger: true
|
|
8
5
|
});
|
|
9
|
-
app.register(
|
|
6
|
+
app.register(fastifyPlugin, {
|
|
10
7
|
baseUrl,
|
|
11
8
|
appDir,
|
|
12
|
-
|
|
9
|
+
onRendered,
|
|
10
|
+
vitrifyDir,
|
|
11
|
+
mode
|
|
13
12
|
});
|
|
14
|
-
|
|
13
|
+
// if (onSetup?.length) {
|
|
14
|
+
// for (const setup of onSetup) {
|
|
15
|
+
// setup(app)
|
|
16
|
+
// }
|
|
17
|
+
// }
|
|
15
18
|
return app;
|
|
16
19
|
};
|
|
17
|
-
// const app = createApp({
|
|
18
|
-
// setup
|
|
19
|
-
// })
|
|
20
|
-
// app.listen(process.env.PORT || 3000, process.env.HOST || '127.0.0.1')
|