vitrify 0.6.15 → 0.6.18

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
@@ -16,6 +16,7 @@ cli
16
16
  const { build } = await import('./build.js');
17
17
  let appDir;
18
18
  let prerender;
19
+ let onRendered;
19
20
  if (options.appDir) {
20
21
  if (options.appDir.slice(-1) !== '/')
21
22
  options.appDir += '/';
@@ -68,14 +69,15 @@ cli
68
69
  ...args,
69
70
  outDir: new URL('ssr/server/', baseOutDir).pathname
70
71
  });
71
- ({ prerender } = await import(new URL('ssr/server/prerender.mjs', baseOutDir).pathname));
72
+ ({ prerender, onRendered } = await import(new URL('ssr/server/prerender.mjs', baseOutDir).pathname));
72
73
  prerender({
73
74
  outDir: new URL('static/', baseOutDir).pathname,
74
75
  templatePath: new URL('static/index.html', baseOutDir).pathname,
75
76
  manifestPath: new URL('static/ssr-manifest.json', baseOutDir)
76
77
  .pathname,
77
78
  entryServerPath: new URL('ssr/server/entry-server.mjs', baseOutDir)
78
- .pathname
79
+ .pathname,
80
+ onRendered
79
81
  });
80
82
  break;
81
83
  default:
package/dist/bin/dev.js CHANGED
@@ -76,14 +76,15 @@ ssr, framework = 'vue', host, appDir, publicDir }) {
76
76
  });
77
77
  let setup;
78
78
  let server;
79
+ let onRendered;
79
80
  console.log(`Development mode: ${ssr ? ssr : 'csr'}`);
80
81
  if (ssr) {
81
82
  const entryUrl = ssr === 'fastify'
82
83
  ? new URL('src/vite/fastify/entry.ts', cliDir).pathname
83
- : new URL(`src/vite/${framework}/ssr/entry-server.ts`, cliDir).pathname;
84
- ({ setup } = await vite.ssrLoadModule(entryUrl));
84
+ : new URL(`src/vite/${framework}/ssr/app.ts`, cliDir).pathname;
85
+ ({ setup, onRendered } = await vite.ssrLoadModule(entryUrl));
85
86
  const app = fastify({
86
- logger: true,
87
+ logger: false,
87
88
  https: vite.config.server.https
88
89
  });
89
90
  if (process.env)
@@ -96,7 +97,8 @@ ssr, framework = 'vue', host, appDir, publicDir }) {
96
97
  if (ssr === 'ssr') {
97
98
  await app.register(fastifySsrPlugin, {
98
99
  appDir,
99
- mode: 'development'
100
+ mode: 'development',
101
+ onRendered
100
102
  });
101
103
  }
102
104
  await app.listen({
@@ -56,7 +56,6 @@ const fastifySsrPlugin = async (fastify, options, done) => {
56
56
  // configFile: false,
57
57
  // ...config
58
58
  // })
59
- console.log('Dev mode');
60
59
  if (!('use' in fastify)) {
61
60
  const middie = (await import('@fastify/middie')).default;
62
61
  await fastify.register(middie);
@@ -65,9 +64,11 @@ const fastifySsrPlugin = async (fastify, options, done) => {
65
64
  fastify.get(`${options.baseUrl}*`, async (req, res) => {
66
65
  try {
67
66
  const url = req.raw.url?.replace(options.baseUrl, '/');
67
+ const provide = options.provide ? await options.provide(req, res) : {};
68
68
  const ssrContext = {
69
69
  req,
70
- res
70
+ res,
71
+ provide
71
72
  };
72
73
  let template = readFileSync(new URL('index.html', frameworkDir)).toString();
73
74
  template = await vite.transformIndexHtml(url, template);
@@ -90,11 +91,16 @@ const fastifySsrPlugin = async (fastify, options, done) => {
90
91
  mods: matchedModules
91
92
  });
92
93
  const [appHtml, preloadLinks] = await render(url, manifest, ssrContext);
93
- const html = template
94
+ let html = template
94
95
  .replace(`<!--preload-links-->`, preloadLinks)
95
96
  .replace(`<!--app-html-->`, appHtml)
96
97
  .replace('<!--product-name-->', options.productName || 'Product name')
97
98
  .replace('<!--dev-ssr-css-->', css);
99
+ if (options.onRendered?.length) {
100
+ for (const ssrFunction of options.onRendered) {
101
+ html = ssrFunction(html, ssrContext);
102
+ }
103
+ }
98
104
  res.code(200);
99
105
  res.type('text/html');
100
106
  res.send(html);
@@ -131,9 +137,14 @@ const fastifySsrPlugin = async (fastify, options, done) => {
131
137
  if (!ssrContext.initialState)
132
138
  ssrContext.initialState = {};
133
139
  ssrContext.initialState.provide = provide;
134
- const html = template
140
+ let html = template
135
141
  .replace(`<!--preload-links-->`, preloadLinks)
136
142
  .replace(`<!--app-html-->`, appHtml);
143
+ if (options.onRendered?.length) {
144
+ for (const ssrFunction of options.onRendered) {
145
+ html = ssrFunction(html, ssrContext);
146
+ }
147
+ }
137
148
  res.code(200);
138
149
  res.type('text/html');
139
150
  res.send(html);
@@ -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, onRendered }) => {
4
4
  const promises = [];
5
5
  const template = (await fs.readFile(templatePath)).toString();
6
6
  const manifest = await fs.readFile(manifestPath);
@@ -25,6 +25,11 @@ export const prerender = async ({ outDir, templatePath, manifestPath, entryServe
25
25
  let html = template
26
26
  .replace(`<!--preload-links-->`, preloadLinks)
27
27
  .replace(`<!--app-html-->`, appHtml);
28
+ if (onRendered?.length) {
29
+ for (const ssrFunction of onRendered) {
30
+ html = ssrFunction(html, ssrContext);
31
+ }
32
+ }
28
33
  html = await critters.process(html);
29
34
  promises.push(fs.writeFile(outDir + filename, html, 'utf-8'));
30
35
  }
@@ -1,5 +1,5 @@
1
1
  import fastify from 'fastify';
2
- export const createApp = ({ onSetup, appDir, baseUrl, fastifyPlugin, vitrifyDir, mode }) => {
2
+ export const createApp = ({ onSetup, appDir, baseUrl, fastifyPlugin, onRendered, vitrifyDir, mode }) => {
3
3
  const app = fastify({
4
4
  logger: true
5
5
  });
@@ -7,6 +7,7 @@ export const createApp = ({ onSetup, appDir, baseUrl, fastifyPlugin, vitrifyDir,
7
7
  baseUrl,
8
8
  appDir,
9
9
  vitrifyDir,
10
+ onRendered,
10
11
  mode
11
12
  });
12
13
  // if (onSetup?.length) {
package/dist/index.js CHANGED
@@ -42,20 +42,20 @@ const manualChunks = (id) => {
42
42
  if (name && manualChunkNames.includes(name))
43
43
  return name;
44
44
  }
45
- else if (matchedModule) {
46
- return matchedModule[0];
47
- }
48
45
  else if (VIRTUAL_MODULES.some((virtualModule) => id.includes(virtualModule))) {
49
46
  return VIRTUAL_MODULES.find((name) => id.includes(name));
50
47
  }
51
48
  else if (id.includes('node_modules')) {
49
+ if (matchedModule) {
50
+ return matchedModule[0];
51
+ }
52
52
  return 'vendor';
53
53
  }
54
54
  };
55
55
  export const VIRTUAL_MODULES = [
56
56
  'virtual:vitrify-hooks',
57
- 'virtual:global-css',
58
57
  'virtual:static-imports',
58
+ 'virtual:vitrify-config',
59
59
  'vitrify.sass',
60
60
  'vitrify.css'
61
61
  ];
@@ -237,21 +237,28 @@ export const baseConfig = async ({ ssr, appDir, publicDir, base = '/', command =
237
237
  globalSass = config.vitrify?.sass?.global || [];
238
238
  additionalData = config.vitrify?.sass?.additionalData || [];
239
239
  return {
240
- css: {
241
- preprocessorOptions: {
242
- // sass: {
243
- // additionalData: [
244
- // ...Object.entries(sassVariables).map(
245
- // ([key, value]) => `${key}: ${value}`
246
- // )
247
- // // ...additionalData
248
- // // config.css?.preprocessorOptions?.sass.additionalData
249
- // ].join('\n')
250
- // }
251
- }
252
- }
240
+ // css: {
241
+ // preprocessorOptions: {
242
+ // sass: {
243
+ // additionalData: [
244
+ // ...Object.entries(sassVariables).map(
245
+ // ([key, value]) => `${key}: ${value}`
246
+ // )
247
+ // // ...additionalData
248
+ // // config.css?.preprocessorOptions?.sass.additionalData
249
+ // ].join('\n')
250
+ // }
251
+ // }
252
+ // }
253
253
  };
254
254
  },
255
+ configureServer(server) {
256
+ server.middlewares.use('/', (req, res, next) => {
257
+ if (req.url?.endsWith('.html'))
258
+ req.url = req.url.replace('.html', '');
259
+ next();
260
+ });
261
+ },
255
262
  configResolved: (config) => {
256
263
  if (process.env.DEBUG) {
257
264
  console.log(config.css?.preprocessorOptions?.sass.additionalData);
@@ -310,7 +317,10 @@ export const baseConfig = async ({ ssr, appDir, publicDir, base = '/', command =
310
317
  ].join('\n');
311
318
  }
312
319
  else if (id === 'vitrify.css') {
313
- return `${globalCss.map((css) => `import '${css}'`).join('\n')}`;
320
+ return `${globalCss.map((css) => `@import '${css}'`).join('\n')}`;
321
+ }
322
+ else if (id === 'virtual:vitrify-config') {
323
+ return `export default ${JSON.stringify(vitrifyConfig)}`;
314
324
  }
315
325
  return null;
316
326
  }
@@ -378,22 +388,22 @@ export const baseConfig = async ({ ssr, appDir, publicDir, base = '/', command =
378
388
  { find: 'cwd', replacement: cwd.pathname },
379
389
  { find: 'boot', replacement: new URL('boot/', srcDir).pathname },
380
390
  { find: 'assets', replacement: new URL('assets/', srcDir).pathname },
381
- ...Object.entries(packageUrls).map(([key, value]) => ({
382
- find: key,
383
- replacement: value.pathname
384
- }))
385
- // {
386
- // find: new RegExp('^vue$'),
387
- // replacement: 'vue/dist/vue.runtime.esm-bundler.js'
388
- // },
391
+ // ...Object.entries(packageUrls).map(([key, value]) => ({
392
+ // find: key,
393
+ // replacement: value.pathname
394
+ // }))
395
+ {
396
+ find: new RegExp('^vue$'),
397
+ replacement: new URL('./dist/vue.runtime.esm-bundler.js', packageUrls['vue']).pathname
398
+ },
389
399
  // {
390
400
  // find: new RegExp('^vue/server-renderer$'),
391
401
  // replacement: 'vue/server-renderer/index.mjs'
392
402
  // },
393
- // {
394
- // find: new RegExp('^vue-router$'),
395
- // replacement: 'vue-router/dist/vue-router.esm-bundler.js'
396
- // }
403
+ {
404
+ find: new RegExp('^vue-router$'),
405
+ replacement: new URL('./dist/vue-router.esm-bundler.js', packageUrls['vue-router']).pathname
406
+ }
397
407
  // { find: 'vue', replacement: packageUrls['vue'].pathname },
398
408
  // { find: 'vue-router', replacement: packageUrls['vue-router'].pathname },
399
409
  // { find: 'vitrify', replacement: cliDir.pathname }
@@ -31,6 +31,7 @@ export const injectSsrContext = (html, ssrContext) => html
31
31
  });
32
32
  export const QuasarPlugin = async ({ ssr = false, pwa = false }) => {
33
33
  let plugins = [];
34
+ let quasarConf;
34
35
  return [
35
36
  Components({
36
37
  resolvers: [QuasarResolver()]
@@ -76,9 +77,13 @@ export const QuasarPlugin = async ({ ssr = false, pwa = false }) => {
76
77
  const quasarPlugins = await import('virtual:quasar-plugins');
77
78
  // @ts-ignore
78
79
  const directives = await import('virtual:quasar-directives');
80
+ // @ts-ignore
81
+ const { default: lang } = await import('virtual:quasar-lang');
82
+ console.log(lang);
79
83
  app.use(staticImports?.Quasar, {
80
84
  plugins: quasarPlugins,
81
- directives
85
+ directives,
86
+ lang
82
87
  }, ssrContext);
83
88
  }
84
89
  ];
@@ -106,7 +111,11 @@ export const QuasarPlugin = async ({ ssr = false, pwa = false }) => {
106
111
  name: 'vite-plugin-quasar',
107
112
  enforce: 'post',
108
113
  config: async (config, env) => {
109
- const { quasar: quasarConf, vitrify: { urls } = {} } = config;
114
+ const { quasar, vitrify: { urls } = {} } = config;
115
+ if (quasar)
116
+ quasarConf = quasar;
117
+ if (!quasarConf.framework.lang && config.vitrify?.lang)
118
+ quasarConf.framework.lang = config.vitrify.lang;
110
119
  // const quasarPkgJsonPath = new URL(
111
120
  // 'package.json',
112
121
  // urls?.packages?.quasar
@@ -195,7 +204,7 @@ export const QuasarPlugin = async ({ ssr = false, pwa = false }) => {
195
204
  // find: new RegExp('^quasar$'),
196
205
  // replacement: new URL('src/index.all.js', urls?.packages?.quasar)
197
206
  // .pathname
198
- // },
207
+ // }
199
208
  // {
200
209
  // find: `@quasar/extras`,
201
210
  // replacement: new URL('.', urls?.packages?.['@quasar/extras'])
@@ -217,10 +226,10 @@ export const QuasarPlugin = async ({ ssr = false, pwa = false }) => {
217
226
  // __QUASAR_SSR_CLIENT__: `!import.meta.env.SSR`,
218
227
  // // __QUASAR_SSR_PWA__: ssr === 'client' && pwa
219
228
  // __QUASAR_SSR_PWA__: pwa ? `!import.meta.env.SSR` : false
229
+ },
230
+ ssr: {
231
+ noExternal: ['quasar']
220
232
  }
221
- // ssr: {
222
- // noExternal: ['quasar']
223
- // }
224
233
  };
225
234
  }
226
235
  },
@@ -244,6 +253,8 @@ export const QuasarPlugin = async ({ ssr = false, pwa = false }) => {
244
253
  return 'virtual:quasar-plugins';
245
254
  case 'virtual:quasar-directives':
246
255
  return 'virtual:quasar-directives';
256
+ case 'virtual:quasar-lang':
257
+ return 'virtual:quasar-lang';
247
258
  case 'virtual:quasar':
248
259
  return { id: 'virtual:quasar', moduleSideEffects: false };
249
260
  default:
@@ -257,6 +268,10 @@ export const QuasarPlugin = async ({ ssr = false, pwa = false }) => {
257
268
  else if (id === 'virtual:quasar-directives') {
258
269
  return `export * from 'quasar/src/directives.js'`;
259
270
  }
271
+ else if (id === 'virtual:quasar-lang') {
272
+ return `import lang from 'quasar/lang/${quasarConf?.framework?.lang || 'en-US'}';
273
+ export default lang`;
274
+ }
260
275
  else if (id === 'virtual:quasar') {
261
276
  return `export * from 'quasar/src/plugins.js';
262
277
  export * from 'quasar/src/components.js';
@@ -42,7 +42,7 @@ export declare function createServer({ port, logLevel, ssr, framework, host, app
42
42
  server: import("vite").ResolvedServerOptions;
43
43
  build: Required<import("vite").BuildOptions>;
44
44
  preview: import("vite").ResolvedPreviewOptions;
45
- ssr: import("vite").ResolvedSSROptions;
45
+ ssr: import("vite").ResolvedSSROptions | undefined;
46
46
  assetsInclude: (file: string) => boolean;
47
47
  logger: import("vite").Logger;
48
48
  createResolver: (options?: Partial<import("vite").InternalResolveOptions> | undefined) => import("vite").ResolveFn;
@@ -1,10 +1,12 @@
1
1
  import type { FastifyPluginCallback, FastifyRequest, FastifyReply } from 'fastify';
2
2
  import type { ViteDevServer } from 'vite';
3
+ import type { OnRenderedHook } from 'src/node/vitrify-config.js';
3
4
  export interface FastifySsrOptions {
4
5
  baseUrl?: string;
5
6
  provide?: (req: FastifyRequest, res: FastifyReply) => Promise<Record<string, unknown>>;
6
7
  vitrifyDir?: URL;
7
8
  vite?: ViteDevServer;
9
+ onRendered?: OnRenderedHook[];
8
10
  appDir?: URL;
9
11
  publicDir?: URL;
10
12
  productName?: string;
@@ -1,6 +1,8 @@
1
- export declare const prerender: ({ outDir, templatePath, manifestPath, entryServerPath }: {
1
+ import type { OnRenderedHook } from 'src/node/vitrify-config.js';
2
+ export declare const prerender: ({ outDir, templatePath, manifestPath, entryServerPath, onRendered }: {
2
3
  outDir: string;
3
4
  templatePath: string;
4
5
  manifestPath: string;
5
6
  entryServerPath: string;
7
+ onRendered: OnRenderedHook[];
6
8
  }) => Promise<void[]>;
@@ -1,13 +1,14 @@
1
1
  /// <reference types="node" />
2
2
  import type { FastifyInstance } from 'fastify';
3
- import type { OnSetupFile } from '../../vitrify-config.js';
3
+ import type { OnRenderedHook, OnSetupFile } from '../../vitrify-config.js';
4
4
  import type { FastifyCsrPlugin } from './fastify-csr-plugin.js';
5
5
  import type { FastifySsrPlugin } from './fastify-ssr-plugin.js';
6
- export declare const createApp: ({ onSetup, appDir, baseUrl, fastifyPlugin, vitrifyDir, mode }: {
6
+ export declare const createApp: ({ onSetup, appDir, baseUrl, fastifyPlugin, onRendered, vitrifyDir, mode }: {
7
7
  onSetup: OnSetupFile[];
8
8
  appDir: URL;
9
9
  baseUrl?: string | undefined;
10
10
  fastifyPlugin: FastifySsrPlugin | FastifyCsrPlugin;
11
+ onRendered: OnRenderedHook[];
11
12
  vitrifyDir?: URL | undefined;
12
13
  mode: string;
13
14
  }) => FastifyInstance<import("http").Server, import("http").IncomingMessage, import("http").ServerResponse, pino.Logger, import("fastify").FastifyTypeProviderDefault> & PromiseLike<FastifyInstance<import("http").Server, import("http").IncomingMessage, import("http").ServerResponse, pino.Logger, import("fastify").FastifyTypeProviderDefault>>;
@@ -7,6 +7,7 @@ export interface QuasarConf {
7
7
  components?: string[];
8
8
  directives?: string[];
9
9
  plugins?: string[];
10
+ lang?: string;
10
11
  };
11
12
  animations: string[];
12
13
  extras: string[];
@@ -18,6 +18,7 @@ export declare type OnRenderedHook = (html: string, ssrContext: Record<string, a
18
18
  export declare type OnSetupFile = URL;
19
19
  export interface VitrifyConfig extends UserConfig {
20
20
  vitrify?: {
21
+ lang?: string;
21
22
  /**
22
23
  * Global CSS imports
23
24
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vitrify",
3
- "version": "0.6.15",
3
+ "version": "0.6.18",
4
4
  "license": "MIT",
5
5
  "author": "Stefan van Herwijnen",
6
6
  "description": "Pre-configured Vite CLI for your framework",
@@ -76,7 +76,7 @@
76
76
  "sass": "1.53.0",
77
77
  "ts-node": "^10.8.2",
78
78
  "unplugin-vue-components": "^0.21.0",
79
- "vite": "^3.0.0-beta.0",
79
+ "vite": "3.0.0-beta.6",
80
80
  "vitest": "^0.17.0"
81
81
  },
82
82
  "devDependencies": {
@@ -25,6 +25,7 @@ cli
25
25
  const { build } = await import('./build.js')
26
26
  let appDir: URL
27
27
  let prerender
28
+ let onRendered
28
29
  if (options.appDir) {
29
30
  if (options.appDir.slice(-1) !== '/') options.appDir += '/'
30
31
  appDir = new URL(`file://${options.appDir}`)
@@ -84,16 +85,18 @@ cli
84
85
  ...args,
85
86
  outDir: new URL('ssr/server/', baseOutDir).pathname
86
87
  })
87
- ;({ prerender } = await import(
88
+ ;({ prerender, onRendered } = await import(
88
89
  new URL('ssr/server/prerender.mjs', baseOutDir).pathname
89
90
  ))
91
+
90
92
  prerender({
91
93
  outDir: new URL('static/', baseOutDir).pathname,
92
94
  templatePath: new URL('static/index.html', baseOutDir).pathname,
93
95
  manifestPath: new URL('static/ssr-manifest.json', baseOutDir)
94
96
  .pathname,
95
97
  entryServerPath: new URL('ssr/server/entry-server.mjs', baseOutDir)
96
- .pathname
98
+ .pathname,
99
+ onRendered
97
100
  })
98
101
  break
99
102
  default:
@@ -7,6 +7,7 @@ import type { FastifyInstance } from 'fastify/types/instance'
7
7
  import fastify from 'fastify'
8
8
  import { fastifySsrPlugin } from '../frameworks/vue/fastify-ssr-plugin.js'
9
9
  import type { ServerOptions } from 'https'
10
+ import type { OnRenderedHook } from '../vitrify-config.js'
10
11
 
11
12
  export async function createVitrifyDevServer({
12
13
  port = 3000,
@@ -128,18 +129,18 @@ export async function createServer({
128
129
 
129
130
  let setup
130
131
  let server: Server
132
+ let onRendered: OnRenderedHook[]
131
133
 
132
134
  console.log(`Development mode: ${ssr ? ssr : 'csr'}`)
133
135
  if (ssr) {
134
136
  const entryUrl =
135
137
  ssr === 'fastify'
136
138
  ? new URL('src/vite/fastify/entry.ts', cliDir).pathname
137
- : new URL(`src/vite/${framework}/ssr/entry-server.ts`, cliDir).pathname
138
-
139
- ;({ setup } = await vite.ssrLoadModule(entryUrl))
139
+ : new URL(`src/vite/${framework}/ssr/app.ts`, cliDir).pathname
140
140
 
141
+ ;({ setup, onRendered } = await vite.ssrLoadModule(entryUrl))
141
142
  const app = fastify({
142
- logger: true,
143
+ logger: false,
143
144
  https: vite.config.server.https as ServerOptions
144
145
  })
145
146
  if (process.env) process.env.MODE = 'development'
@@ -151,7 +152,8 @@ export async function createServer({
151
152
  if (ssr === 'ssr') {
152
153
  await app.register(fastifySsrPlugin, {
153
154
  appDir,
154
- mode: 'development'
155
+ mode: 'development',
156
+ onRendered
155
157
  })
156
158
  }
157
159
  await app.listen({
@@ -7,6 +7,7 @@ import fastifyStatic from '@fastify/static'
7
7
  import { readFileSync } from 'fs'
8
8
  import { componentsModules, collectCss } from '../../helpers/collect-css-ssr.js'
9
9
  import type { ViteDevServer } from 'vite'
10
+ import type { OnRenderedHook } from 'src/node/vitrify-config.js'
10
11
 
11
12
  export interface FastifySsrOptions {
12
13
  baseUrl?: string
@@ -17,6 +18,7 @@ export interface FastifySsrOptions {
17
18
  vitrifyDir?: URL
18
19
  vite?: ViteDevServer
19
20
  // frameworkDir?: URL
21
+ onRendered?: OnRenderedHook[]
20
22
  appDir?: URL
21
23
  publicDir?: URL
22
24
  productName?: string
@@ -88,7 +90,6 @@ const fastifySsrPlugin: FastifyPluginCallback<FastifySsrOptions> = async (
88
90
  // ...config
89
91
  // })
90
92
 
91
- console.log('Dev mode')
92
93
  if (!('use' in fastify)) {
93
94
  const middie = (await import('@fastify/middie')).default
94
95
  await fastify.register(middie)
@@ -98,9 +99,12 @@ const fastifySsrPlugin: FastifyPluginCallback<FastifySsrOptions> = async (
98
99
  fastify.get(`${options.baseUrl}*`, async (req, res) => {
99
100
  try {
100
101
  const url = req.raw.url?.replace(options.baseUrl!, '/')
102
+ const provide = options.provide ? await options.provide(req, res) : {}
103
+
101
104
  const ssrContext = {
102
105
  req,
103
- res
106
+ res,
107
+ provide
104
108
  }
105
109
 
106
110
  let template = readFileSync(
@@ -129,12 +133,18 @@ const fastifySsrPlugin: FastifyPluginCallback<FastifySsrOptions> = async (
129
133
  })
130
134
 
131
135
  const [appHtml, preloadLinks] = await render(url, manifest, ssrContext)
132
- const html = template
136
+ let html = template
133
137
  .replace(`<!--preload-links-->`, preloadLinks)
134
138
  .replace(`<!--app-html-->`, appHtml)
135
139
  .replace('<!--product-name-->', options.productName || 'Product name')
136
140
  .replace('<!--dev-ssr-css-->', css)
137
141
 
142
+ if (options.onRendered?.length) {
143
+ for (const ssrFunction of options.onRendered) {
144
+ html = ssrFunction(html, ssrContext)
145
+ }
146
+ }
147
+
138
148
  res.code(200)
139
149
  res.type('text/html')
140
150
  res.send(html)
@@ -183,10 +193,16 @@ const fastifySsrPlugin: FastifyPluginCallback<FastifySsrOptions> = async (
183
193
  if (!ssrContext.initialState) ssrContext.initialState = {}
184
194
  ssrContext.initialState.provide = provide
185
195
 
186
- const html = template
196
+ let html = template
187
197
  .replace(`<!--preload-links-->`, preloadLinks)
188
198
  .replace(`<!--app-html-->`, appHtml)
189
199
 
200
+ if (options.onRendered?.length) {
201
+ for (const ssrFunction of options.onRendered) {
202
+ html = ssrFunction(html, ssrContext)
203
+ }
204
+ }
205
+
190
206
  res.code(200)
191
207
  res.type('text/html')
192
208
  res.send(html)
@@ -1,16 +1,19 @@
1
1
  import { promises as fs } from 'fs'
2
+ import type { OnRenderedHook } from 'src/node/vitrify-config.js'
2
3
  import { routesToPaths } from '../../helpers/routes.js'
3
4
 
4
5
  export const prerender = async ({
5
6
  outDir,
6
7
  templatePath,
7
8
  manifestPath,
8
- entryServerPath
9
+ entryServerPath,
10
+ onRendered
9
11
  }: {
10
12
  outDir: string
11
13
  templatePath: string
12
14
  manifestPath: string
13
15
  entryServerPath: string
16
+ onRendered: OnRenderedHook[]
14
17
  }) => {
15
18
  const promises = []
16
19
  const template = (await fs.readFile(templatePath)).toString()
@@ -41,6 +44,12 @@ export const prerender = async ({
41
44
  .replace(`<!--preload-links-->`, preloadLinks)
42
45
  .replace(`<!--app-html-->`, appHtml)
43
46
 
47
+ if (onRendered?.length) {
48
+ for (const ssrFunction of onRendered) {
49
+ html = ssrFunction(html, ssrContext)
50
+ }
51
+ }
52
+
44
53
  html = await critters.process(html)
45
54
 
46
55
  promises.push(fs.writeFile(outDir + filename, html, 'utf-8'))
@@ -2,7 +2,7 @@ import type { FastifyInstance } from 'fastify'
2
2
  import fastify from 'fastify'
3
3
  import type { ViteDevServer } from 'vite'
4
4
  import { getCliDir, getCliViteDir } from '../../app-urls.js'
5
- import type { OnSetupFile } from '../../vitrify-config.js'
5
+ import type { OnRenderedHook, OnSetupFile } from '../../vitrify-config.js'
6
6
  import type { FastifyCsrPlugin } from './fastify-csr-plugin.js'
7
7
  import type { FastifySsrPlugin } from './fastify-ssr-plugin.js'
8
8
 
@@ -11,6 +11,7 @@ export const createApp = ({
11
11
  appDir,
12
12
  baseUrl,
13
13
  fastifyPlugin,
14
+ onRendered,
14
15
  vitrifyDir,
15
16
  mode
16
17
  }: {
@@ -18,6 +19,7 @@ export const createApp = ({
18
19
  appDir: URL
19
20
  baseUrl?: string
20
21
  fastifyPlugin: FastifySsrPlugin | FastifyCsrPlugin
22
+ onRendered: OnRenderedHook[]
21
23
  vitrifyDir?: URL
22
24
  mode: string
23
25
  }) => {
@@ -29,6 +31,7 @@ export const createApp = ({
29
31
  baseUrl,
30
32
  appDir,
31
33
  vitrifyDir,
34
+ onRendered,
32
35
  mode
33
36
  })
34
37
 
package/src/node/index.ts CHANGED
@@ -61,21 +61,22 @@ const manualChunks: ManualChunksOption = (id: string) => {
61
61
  if (id.includes('vitrify/src/')) {
62
62
  const name = id.split('/').at(-1)?.split('.').at(0)
63
63
  if (name && manualChunkNames.includes(name)) return name
64
- } else if (matchedModule) {
65
- return matchedModule[0]
66
64
  } else if (
67
65
  VIRTUAL_MODULES.some((virtualModule) => id.includes(virtualModule))
68
66
  ) {
69
67
  return VIRTUAL_MODULES.find((name) => id.includes(name))
70
68
  } else if (id.includes('node_modules')) {
69
+ if (matchedModule) {
70
+ return matchedModule[0]
71
+ }
71
72
  return 'vendor'
72
73
  }
73
74
  }
74
75
 
75
76
  export const VIRTUAL_MODULES = [
76
77
  'virtual:vitrify-hooks',
77
- 'virtual:global-css',
78
78
  'virtual:static-imports',
79
+ 'virtual:vitrify-config',
79
80
  'vitrify.sass',
80
81
  'vitrify.css'
81
82
  ]
@@ -311,21 +312,27 @@ export const baseConfig = async ({
311
312
  additionalData = config.vitrify?.sass?.additionalData || []
312
313
 
313
314
  return {
314
- css: {
315
- preprocessorOptions: {
316
- // sass: {
317
- // additionalData: [
318
- // ...Object.entries(sassVariables).map(
319
- // ([key, value]) => `${key}: ${value}`
320
- // )
321
- // // ...additionalData
322
- // // config.css?.preprocessorOptions?.sass.additionalData
323
- // ].join('\n')
324
- // }
325
- }
326
- }
315
+ // css: {
316
+ // preprocessorOptions: {
317
+ // sass: {
318
+ // additionalData: [
319
+ // ...Object.entries(sassVariables).map(
320
+ // ([key, value]) => `${key}: ${value}`
321
+ // )
322
+ // // ...additionalData
323
+ // // config.css?.preprocessorOptions?.sass.additionalData
324
+ // ].join('\n')
325
+ // }
326
+ // }
327
+ // }
327
328
  }
328
329
  },
330
+ configureServer(server) {
331
+ server.middlewares.use('/', (req, res, next) => {
332
+ if (req.url?.endsWith('.html')) req.url = req.url.replace('.html', '')
333
+ next()
334
+ })
335
+ },
329
336
  configResolved: (config) => {
330
337
  if (process.env.DEBUG) {
331
338
  console.log(config.css?.preprocessorOptions?.sass.additionalData)
@@ -389,7 +396,9 @@ export const baseConfig = async ({
389
396
  ...globalSass.map((sass) => `@import '${sass}'`)
390
397
  ].join('\n')
391
398
  } else if (id === 'vitrify.css') {
392
- return `${globalCss.map((css) => `import '${css}'`).join('\n')}`
399
+ return `${globalCss.map((css) => `@import '${css}'`).join('\n')}`
400
+ } else if (id === 'virtual:vitrify-config') {
401
+ return `export default ${JSON.stringify(vitrifyConfig)}`
393
402
  }
394
403
  return null
395
404
  }
@@ -459,22 +468,28 @@ export const baseConfig = async ({
459
468
  { find: 'cwd', replacement: cwd.pathname },
460
469
  { find: 'boot', replacement: new URL('boot/', srcDir).pathname },
461
470
  { find: 'assets', replacement: new URL('assets/', srcDir).pathname },
462
- ...Object.entries(packageUrls).map(([key, value]) => ({
463
- find: key,
464
- replacement: value.pathname
465
- }))
466
- // {
467
- // find: new RegExp('^vue$'),
468
- // replacement: 'vue/dist/vue.runtime.esm-bundler.js'
469
- // },
471
+ // ...Object.entries(packageUrls).map(([key, value]) => ({
472
+ // find: key,
473
+ // replacement: value.pathname
474
+ // }))
475
+ {
476
+ find: new RegExp('^vue$'),
477
+ replacement: new URL(
478
+ './dist/vue.runtime.esm-bundler.js',
479
+ packageUrls['vue']
480
+ ).pathname
481
+ },
470
482
  // {
471
483
  // find: new RegExp('^vue/server-renderer$'),
472
484
  // replacement: 'vue/server-renderer/index.mjs'
473
485
  // },
474
- // {
475
- // find: new RegExp('^vue-router$'),
476
- // replacement: 'vue-router/dist/vue-router.esm-bundler.js'
477
- // }
486
+ {
487
+ find: new RegExp('^vue-router$'),
488
+ replacement: new URL(
489
+ './dist/vue-router.esm-bundler.js',
490
+ packageUrls['vue-router']
491
+ ).pathname
492
+ }
478
493
  // { find: 'vue', replacement: packageUrls['vue'].pathname },
479
494
  // { find: 'vue-router', replacement: packageUrls['vue-router'].pathname },
480
495
  // { find: 'vitrify', replacement: cliDir.pathname }
@@ -25,6 +25,7 @@ export interface QuasarConf {
25
25
  components?: string[]
26
26
  directives?: string[]
27
27
  plugins?: string[]
28
+ lang?: string
28
29
  }
29
30
  animations: string[]
30
31
  extras: string[]
@@ -83,6 +84,7 @@ export const QuasarPlugin: VitrifyPlugin = async ({
83
84
  pwa = false
84
85
  }): Promise<Plugin[]> => {
85
86
  let plugins: string[] = []
87
+ let quasarConf: QuasarConf
86
88
  return [
87
89
  Components({
88
90
  resolvers: [QuasarResolver()]
@@ -148,12 +150,15 @@ export const QuasarPlugin: VitrifyPlugin = async ({
148
150
  const quasarPlugins = await import('virtual:quasar-plugins')
149
151
  // @ts-ignore
150
152
  const directives = await import('virtual:quasar-directives')
151
-
153
+ // @ts-ignore
154
+ const { default: lang } = await import('virtual:quasar-lang')
155
+ console.log(lang)
152
156
  app.use(
153
157
  staticImports?.Quasar,
154
158
  {
155
159
  plugins: quasarPlugins,
156
- directives
160
+ directives,
161
+ lang
157
162
  },
158
163
  ssrContext
159
164
  )
@@ -184,8 +189,10 @@ export const QuasarPlugin: VitrifyPlugin = async ({
184
189
  name: 'vite-plugin-quasar',
185
190
  enforce: 'post',
186
191
  config: async (config: VitrifyConfig, env) => {
187
- const { quasar: quasarConf, vitrify: { urls } = {} } = config
188
-
192
+ const { quasar, vitrify: { urls } = {} } = config
193
+ if (quasar) quasarConf = quasar
194
+ if (!quasarConf.framework.lang && config.vitrify?.lang)
195
+ quasarConf.framework.lang = config.vitrify.lang
189
196
  // const quasarPkgJsonPath = new URL(
190
197
  // 'package.json',
191
198
  // urls?.packages?.quasar
@@ -278,7 +285,7 @@ export const QuasarPlugin: VitrifyPlugin = async ({
278
285
  // find: new RegExp('^quasar$'),
279
286
  // replacement: new URL('src/index.all.js', urls?.packages?.quasar)
280
287
  // .pathname
281
- // },
288
+ // }
282
289
  // {
283
290
  // find: `@quasar/extras`,
284
291
  // replacement: new URL('.', urls?.packages?.['@quasar/extras'])
@@ -300,10 +307,10 @@ export const QuasarPlugin: VitrifyPlugin = async ({
300
307
  // __QUASAR_SSR_CLIENT__: `!import.meta.env.SSR`,
301
308
  // // __QUASAR_SSR_PWA__: ssr === 'client' && pwa
302
309
  // __QUASAR_SSR_PWA__: pwa ? `!import.meta.env.SSR` : false
310
+ },
311
+ ssr: {
312
+ noExternal: ['quasar']
303
313
  }
304
- // ssr: {
305
- // noExternal: ['quasar']
306
- // }
307
314
  }
308
315
  }
309
316
  },
@@ -327,6 +334,8 @@ export const QuasarPlugin: VitrifyPlugin = async ({
327
334
  return 'virtual:quasar-plugins'
328
335
  case 'virtual:quasar-directives':
329
336
  return 'virtual:quasar-directives'
337
+ case 'virtual:quasar-lang':
338
+ return 'virtual:quasar-lang'
330
339
  case 'virtual:quasar':
331
340
  return { id: 'virtual:quasar', moduleSideEffects: false }
332
341
  default:
@@ -338,6 +347,11 @@ export const QuasarPlugin: VitrifyPlugin = async ({
338
347
  return `export { ${plugins.join(',')} } from 'quasar'`
339
348
  } else if (id === 'virtual:quasar-directives') {
340
349
  return `export * from 'quasar/src/directives.js'`
350
+ } else if (id === 'virtual:quasar-lang') {
351
+ return `import lang from 'quasar/lang/${
352
+ quasarConf?.framework?.lang || 'en-US'
353
+ }';
354
+ export default lang`
341
355
  } else if (id === 'virtual:quasar') {
342
356
  return `export * from 'quasar/src/plugins.js';
343
357
  export * from 'quasar/src/components.js';
@@ -39,6 +39,7 @@ export type OnRenderedHook = (
39
39
  export type OnSetupFile = URL
40
40
  export interface VitrifyConfig extends UserConfig {
41
41
  vitrify?: {
42
+ lang?: string
42
43
  /**
43
44
  * Global CSS imports
44
45
  */
@@ -49,7 +49,7 @@ export async function createApp(
49
49
  // Workaround to fix hydration errors when serving html files directly
50
50
  router.beforeEach((to, from, next) => {
51
51
  if (to.path.endsWith('.html')) {
52
- next({ path: to.path.replace('.html', '') })
52
+ return next({ path: to.path.replace('.html', '') })
53
53
  }
54
54
 
55
55
  next()
@@ -1,7 +1,7 @@
1
1
  import { createApp } from '../../../node/frameworks/vue/server.js'
2
2
  import { getAppDir } from '../../../node/app-urls.js'
3
3
  // import { setup } from 'virtual:fastify-setup'
4
- import { onSetup } from 'virtual:vitrify-hooks'
4
+ import { onSetup, onRendered } from 'virtual:vitrify-hooks'
5
5
  import { fastifySsrPlugin } from './fastify-ssr-plugin.js'
6
6
  import type { ViteDevServer } from 'vite'
7
7
 
@@ -17,7 +17,10 @@ export const setupApp = async () => {
17
17
  appDir,
18
18
  baseUrl,
19
19
  fastifyPlugin: fastifySsrPlugin,
20
+ onRendered,
20
21
  // vitrifyDir,
21
22
  mode: import.meta.env.MODE
22
23
  })
23
24
  }
25
+
26
+ export { onRendered }
@@ -1,7 +1,7 @@
1
1
  import { createApp } from '../main.js'
2
2
  // import { renderToString } from 'vue/server-renderer'
3
3
 
4
- import { onRendered } from 'virtual:vitrify-hooks'
4
+ // import { onRendered } from 'virtual:vitrify-hooks'
5
5
 
6
6
  const initializeApp = async (url, ssrContext) => {
7
7
  const onRenderedList = []
@@ -49,12 +49,6 @@ export async function render(url, manifest, ssrContext, renderToString) {
49
49
 
50
50
  const preloadLinks = renderPreloadLinks(ctx.modules, manifest)
51
51
 
52
- if (onRendered?.length) {
53
- for (const ssrFunction of onRendered) {
54
- html = ssrFunction(html, ssrContext)
55
- }
56
- }
57
-
58
52
  return [html, preloadLinks]
59
53
  }
60
54
 
@@ -1,3 +1,4 @@
1
1
  import { prerender } from '../../../node/frameworks/vue/prerender.js'
2
+ import { onRendered } from 'virtual:vitrify-hooks'
2
3
 
3
- export { prerender }
4
+ export { prerender, onRendered }