vitrify 0.2.0 → 0.2.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/cli.js CHANGED
@@ -13,8 +13,8 @@ cli
13
13
  .option('--productName [productName]', 'Product name')
14
14
  .action(async (options) => {
15
15
  const { build } = await import('./build.js');
16
- let prerender;
17
16
  let appDir;
17
+ let prerender, ssrFunctions;
18
18
  if (options.appDir) {
19
19
  if (options.appDir.slice(-1) !== '/')
20
20
  options.appDir += '/';
@@ -59,14 +59,15 @@ cli
59
59
  ...args,
60
60
  outDir: new URL('ssr/server/', baseOutDir).pathname
61
61
  });
62
- prerender = (await import(new URL('ssr/server/prerender.js', appDir).pathname)).prerender;
62
+ ({ prerender, ssrFunctions } = await import(new URL('ssr/server/prerender.mjs', baseOutDir).pathname));
63
63
  prerender({
64
64
  outDir: new URL('static/', baseOutDir).pathname,
65
65
  templatePath: new URL('static/index.html', baseOutDir).pathname,
66
66
  manifestPath: new URL('static/ssr-manifest.json', baseOutDir)
67
67
  .pathname,
68
68
  entryServerPath: new URL('ssr/server/entry-server.mjs', baseOutDir)
69
- .pathname
69
+ .pathname,
70
+ ssrFunctions
70
71
  });
71
72
  break;
72
73
  default:
@@ -1,5 +1,5 @@
1
1
  import { promises as fs } from 'fs';
2
- import { routesToPaths } from '../helpers/routes.js';
2
+ import { routesToPaths } from '../../helpers/routes.js';
3
3
  export const prerender = async ({ outDir, templatePath, manifestPath, entryServerPath, ssrFunctions }) => {
4
4
  const promises = [];
5
5
  const template = (await fs.readFile(templatePath)).toString();
File without changes
package/dist/index.js CHANGED
@@ -197,10 +197,6 @@ export const baseConfig = async ({ ssr, appDir, publicDir, command = 'build', mo
197
197
  plugins.unshift({
198
198
  name: 'html-transform',
199
199
  enforce: 'pre',
200
- config: (config, env) => {
201
- if (config.vitrify?.productName)
202
- productName = config.vitrify?.productName;
203
- },
204
200
  transform: (code, id) => {
205
201
  if (id.endsWith('App.vue')) {
206
202
  code =
@@ -232,6 +228,21 @@ export const baseConfig = async ({ ssr, appDir, publicDir, command = 'build', mo
232
228
  }
233
229
  }
234
230
  });
231
+ plugins.unshift({
232
+ name: 'product-name',
233
+ enforce: 'post',
234
+ config: (config, env) => {
235
+ if (config.vitrify?.productName)
236
+ productName = config.vitrify?.productName;
237
+ },
238
+ transformIndexHtml: {
239
+ enforce: 'post',
240
+ transform: (html) => {
241
+ html = html.replace('<!--product-name-->', productName);
242
+ return html;
243
+ }
244
+ }
245
+ });
235
246
  }
236
247
  const alias = [
237
248
  { find: 'src', replacement: srcDir.pathname },
@@ -285,6 +296,7 @@ export const baseConfig = async ({ ssr, appDir, publicDir, command = 'build', mo
285
296
  ? {
286
297
  input: [
287
298
  new URL('ssr/entry-server.ts', frameworkDir).pathname,
299
+ new URL('ssr/prerender.ts', frameworkDir).pathname,
288
300
  new URL('ssr/server.ts', frameworkDir).pathname
289
301
  ],
290
302
  output: {
@@ -289,7 +289,7 @@ export const QuasarPlugin = async ({ ssr = false, pwa = false }) => {
289
289
  export * from 'quasar/src/composables.js';
290
290
  export * from 'quasar/src/directives.js';
291
291
  export * from 'quasar/src/utils.js';
292
- export { default as Quasar } from 'quasar/src/vue-plugin.js'`;
292
+ export { default as Quasar } from 'quasar/src/install-quasar.js'`;
293
293
  }
294
294
  return null;
295
295
  }
@@ -1,6 +1,6 @@
1
1
  import type { FastifyPluginCallback, FastifyRequest, FastifyReply } from 'fastify';
2
2
  import type { ViteDevServer } from 'vite';
3
- import type { SsrFunction } from '../vitrify-config.js';
3
+ import type { SsrFunction } from '../../vitrify-config.js';
4
4
  export interface FastifySsrOptions {
5
5
  baseUrl?: string;
6
6
  provide?: (req: FastifyRequest, res: FastifyReply) => Promise<Record<string, unknown>>;
@@ -1,4 +1,4 @@
1
- import type { SsrFunction } from '../vitrify-config.js';
1
+ import type { SsrFunction } from '../../vitrify-config.js';
2
2
  export declare const prerender: ({ outDir, templatePath, manifestPath, entryServerPath, ssrFunctions }: {
3
3
  outDir: string;
4
4
  templatePath: string;
@@ -1,6 +1,6 @@
1
1
  /// <reference types="node" />
2
2
  import type { FastifyInstance } from 'fastify';
3
- import type { SsrFunction } from '../vitrify-config.js';
3
+ import type { SsrFunction } from '../../vitrify-config.js';
4
4
  export declare const createApp: ({ setup, appDir, baseUrl, ssrFunctions }: {
5
5
  setup: (fastify: FastifyInstance) => any;
6
6
  appDir: URL;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vitrify",
3
- "version": "0.2.0",
3
+ "version": "0.2.1",
4
4
  "license": "MIT",
5
5
  "author": "Stefan van Herwijnen",
6
6
  "description": "Pre-configured Vite CLI for your framework",
@@ -103,7 +103,7 @@
103
103
  },
104
104
  "files": [
105
105
  "dist",
106
- "src/node/helpers/ssr.ts",
106
+ "src/node/frameworks",
107
107
  "src/vite",
108
108
  "!dist/**/*.test.js",
109
109
  "!dist/**/test.js"
@@ -0,0 +1,137 @@
1
+ import type {
2
+ FastifyPluginCallback,
3
+ FastifyRequest,
4
+ FastifyReply
5
+ } from 'fastify'
6
+ import fastifyStatic from 'fastify-static'
7
+ import { readFileSync } from 'fs'
8
+ // import { injectSsrContext } from '../helpers/ssr.js'
9
+ import type { ViteDevServer } from 'vite'
10
+ import type { SsrFunction } from '../../vitrify-config.js'
11
+
12
+ export interface FastifySsrOptions {
13
+ baseUrl?: string
14
+ provide?: (
15
+ req: FastifyRequest,
16
+ res: FastifyReply
17
+ ) => Promise<Record<string, unknown>>
18
+ vite?: ViteDevServer
19
+ cliDir?: URL
20
+ appDir?: URL
21
+ productName?: string
22
+ ssrFunctions?: SsrFunction[]
23
+ }
24
+
25
+ const fastifySsrPlugin: FastifyPluginCallback<FastifySsrOptions> = async (
26
+ fastify,
27
+ options,
28
+ done
29
+ ) => {
30
+ if (import.meta.env.MODE === 'development') {
31
+ if (!options.vite) throw new Error('Option vite cannot be undefined')
32
+ const middie = (await import('middie')).default
33
+ await fastify.register(middie)
34
+ fastify.use(options.vite.middlewares)
35
+
36
+ fastify.get('*', async (req, res) => {
37
+ try {
38
+ // const url = req.originalUrl
39
+ const url = req.raw.url
40
+ const ssrContext = {
41
+ req,
42
+ res
43
+ }
44
+ // always read fresh template in dev
45
+ // template = readFileSync(resolve('index.html'), 'utf-8')
46
+ const template = readFileSync(
47
+ new URL('index.html', options.cliDir)
48
+ ).toString()
49
+
50
+ // template = await vite.transformIndexHtml(url, template)
51
+ const entryUrl = new URL('ssr/entry-server.ts', options.cliDir).pathname
52
+ const render = (await options.vite!.ssrLoadModule(entryUrl)).render
53
+ let manifest
54
+ // TODO: https://github.com/vitejs/vite/issues/2282
55
+ try {
56
+ manifest = {}
57
+ } catch (e) {
58
+ manifest = {}
59
+ }
60
+
61
+ const [appHtml, preloadLinks] = await render(url, manifest, ssrContext)
62
+ const html = template
63
+ .replace(`<!--preload-links-->`, preloadLinks)
64
+ .replace(`<!--app-html-->`, appHtml)
65
+ .replace('<!--product-name-->', options.productName || 'Product name')
66
+
67
+ res.code(200)
68
+ res.type('text/html')
69
+ res.send(html)
70
+ // res.status(200).set({ 'Content-Type': 'text/html' }).end(html)
71
+ } catch (e: any) {
72
+ console.error(e.stack)
73
+ options.vite && options.vite.ssrFixStacktrace(e)
74
+ res.code(500)
75
+ res.send(e.stack)
76
+ }
77
+ })
78
+ } else {
79
+ options.baseUrl = options.baseUrl || '/'
80
+ fastify.register(fastifyStatic, {
81
+ root: new URL('./dist/ssr/client', options.appDir).pathname,
82
+ wildcard: false,
83
+ index: false,
84
+ prefix: options.baseUrl
85
+ })
86
+
87
+ fastify.get(`${options.baseUrl}*`, async (req, res) => {
88
+ const url = req.raw.url
89
+ const provide = options.provide ? await options.provide(req, res) : {}
90
+ const ssrContext: Record<string, any> = {
91
+ req,
92
+ res,
93
+ provide
94
+ }
95
+
96
+ // template = readFileSync(new URL('../client/index.html', import.meta.url).pathname).toString()
97
+ // manifest = JSON.parse(readFileSync(new URL('../client/ssr-manifest.json', import.meta.url)).toString())
98
+ // render = (await import(new URL('./entry-server.mjs', import.meta.url).pathname)).render
99
+ const template = readFileSync(
100
+ new URL('./dist/ssr/client/index.html', options.appDir).pathname
101
+ ).toString()
102
+ const manifest = JSON.parse(
103
+ readFileSync(
104
+ new URL('./dist/ssr/client/ssr-manifest.json', options.appDir)
105
+ ).toString()
106
+ )
107
+ const render = (
108
+ await import(
109
+ new URL('./dist/ssr/server/entry-server.mjs', options.appDir).pathname
110
+ )
111
+ ).render
112
+
113
+ const [appHtml, preloadLinks] = await render(url, manifest, ssrContext)
114
+
115
+ if (!ssrContext.initialState) ssrContext.initialState = {}
116
+ ssrContext.initialState.provide = provide
117
+
118
+ let html = template
119
+ .replace(`<!--preload-links-->`, preloadLinks)
120
+ .replace(`<!--app-html-->`, appHtml)
121
+
122
+ if (options.ssrFunctions?.length) {
123
+ for (const ssrFunction of options.ssrFunctions) {
124
+ html = ssrFunction(html, ssrContext)
125
+ }
126
+ }
127
+
128
+ res.code(200)
129
+ res.type('text/html')
130
+ res.send(html)
131
+ })
132
+ }
133
+
134
+ done()
135
+ }
136
+
137
+ export { fastifySsrPlugin }
@@ -0,0 +1,49 @@
1
+ import { promises as fs } from 'fs'
2
+ import { routesToPaths } from '../../helpers/routes.js'
3
+ import type { SsrFunction } from '../../vitrify-config.js'
4
+
5
+ export const prerender = async ({
6
+ outDir,
7
+ templatePath,
8
+ manifestPath,
9
+ entryServerPath,
10
+ ssrFunctions
11
+ }: {
12
+ outDir: string
13
+ templatePath: string
14
+ manifestPath: string
15
+ entryServerPath: string
16
+ ssrFunctions: SsrFunction[]
17
+ }) => {
18
+ const promises = []
19
+ const template = (await fs.readFile(templatePath)).toString()
20
+ const manifest = await fs.readFile(manifestPath)
21
+ const { render, getRoutes } = await import(entryServerPath)
22
+ const routes = await getRoutes()
23
+ const paths = routesToPaths(routes).filter(
24
+ (i) => !i.includes(':') && !i.includes('*')
25
+ )
26
+ for (const url of paths) {
27
+ const filename =
28
+ (url.endsWith('/') ? 'index' : url.replace(/^\//g, '')) + '.html'
29
+ console.log(`Generating ${filename}`)
30
+ const ssrContext = {
31
+ req: { headers: {}, url },
32
+ res: {}
33
+ }
34
+ const [appHtml, preloadLinks] = await render(url, manifest, ssrContext)
35
+
36
+ let html = template
37
+ .replace(`<!--preload-links-->`, preloadLinks)
38
+ .replace(`<!--app-html-->`, appHtml)
39
+
40
+ if (ssrFunctions?.length) {
41
+ for (const ssrFunction of ssrFunctions) {
42
+ html = ssrFunction(html, ssrContext)
43
+ }
44
+ }
45
+
46
+ promises.push(fs.writeFile(outDir + filename, html, 'utf-8'))
47
+ }
48
+ return Promise.all(promises)
49
+ }
@@ -0,0 +1,38 @@
1
+ import type { FastifyInstance } from 'fastify'
2
+ import fastify from 'fastify'
3
+ import type { SsrFunction } from '../../vitrify-config.js'
4
+ // import { setup } from 'virtual:fastify-setup'
5
+ import { fastifySsrPlugin } from './fastify-ssr-plugin.js'
6
+ // import { getPkgJsonDir } from '../app-urls.js'
7
+
8
+ export const createApp = ({
9
+ setup,
10
+ appDir,
11
+ baseUrl,
12
+ ssrFunctions
13
+ }: {
14
+ setup: (fastify: FastifyInstance) => any
15
+ appDir: URL
16
+ baseUrl?: string
17
+ ssrFunctions?: SsrFunction[]
18
+ }) => {
19
+ const app = fastify({
20
+ logger: true
21
+ })
22
+
23
+ app.register(fastifySsrPlugin, {
24
+ baseUrl,
25
+ appDir,
26
+ ssrFunctions
27
+ })
28
+
29
+ setup(app)
30
+
31
+ return app
32
+ }
33
+
34
+ // const app = createApp({
35
+ // setup
36
+ // })
37
+
38
+ // app.listen(process.env.PORT || 3000, process.env.HOST || '127.0.0.1')
@@ -1,4 +1,4 @@
1
- import { fastifySsrPlugin } from '../../../node/vue/fastify-ssr-plugin.js'
1
+ import { fastifySsrPlugin } from '../../../node/frameworks/vue/fastify-ssr-plugin.js'
2
2
  import ssrFunctions from 'virtual:ssr-functions'
3
3
 
4
4
  export { fastifySsrPlugin, ssrFunctions }
@@ -1,4 +1,4 @@
1
- import { prerender } from '../../../node/vue/prerender.js'
1
+ import { prerender } from '../../../node/frameworks/vue/prerender.js'
2
2
  import ssrFunctions from 'virtual:ssr-functions'
3
3
 
4
4
  export { prerender, ssrFunctions }
@@ -1,15 +1,18 @@
1
- import { createApp } from '../../../node/vue/server.js'
2
- import { appDir } from '../../../node/app-urls.js'
1
+ import { createApp } from '../../../node/frameworks/vue/server.js'
2
+ import { getAppDir } from '../../../node/app-urls.js'
3
3
  import { setup } from 'virtual:fastify-setup'
4
+ import ssrFunctions from 'virtual:ssr-functions'
4
5
 
5
6
  // const appDir = getPkgJsonDir(import.meta.url)
6
7
  const getString = (str?: string) => str
7
8
  let baseUrl = getString(__BASE_URL__)
9
+ const appDir = getAppDir()
8
10
 
9
11
  const app = createApp({
10
12
  setup,
11
13
  appDir,
12
- baseUrl
14
+ baseUrl,
15
+ ssrFunctions
13
16
  })
14
17
 
15
18
  app.listen(process.env.PORT || 3000, process.env.HOST || '127.0.0.1')