vitrify 0.6.16 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/bin/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
@@ -77,15 +77,18 @@ ssr, framework = 'vue', host, appDir, publicDir }) {
77
77
  let setup;
78
78
  let server;
79
79
  let onRendered;
80
+ let vitrifyConfig;
80
81
  console.log(`Development mode: ${ssr ? ssr : 'csr'}`);
81
82
  if (ssr) {
82
83
  const entryUrl = ssr === 'fastify'
83
84
  ? new URL('src/vite/fastify/entry.ts', cliDir).pathname
84
85
  : new URL(`src/vite/${framework}/ssr/app.ts`, cliDir).pathname;
85
- ({ setup, onRendered } = await vite.ssrLoadModule(entryUrl));
86
+ ({ setup, onRendered, vitrifyConfig } = await vite.ssrLoadModule(entryUrl));
87
+ console.log(vitrifyConfig);
86
88
  const app = fastify({
87
89
  logger: false,
88
- https: vite.config.server.https
90
+ https: vite.config.server.https,
91
+ ...vitrifyConfig.vitrify?.ssr?.fastify
89
92
  });
90
93
  if (process.env)
91
94
  process.env.MODE = 'development';
@@ -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
  }
package/dist/index.js CHANGED
@@ -54,8 +54,8 @@ const manualChunks = (id) => {
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
  ];
@@ -169,12 +169,6 @@ export const baseConfig = async ({ ssr, appDir, publicDir, base = '/', command =
169
169
  catch (e) {
170
170
  console.error('package.json not found');
171
171
  }
172
- const ssrTransformCustomDir = () => {
173
- return {
174
- props: [],
175
- needRuntime: true
176
- };
177
- };
178
172
  const frameworkPlugins = [];
179
173
  for (const framework of Object.keys(configPluginMap)) {
180
174
  if (Object.keys(vitrifyConfig).includes(framework)) {
@@ -201,27 +195,7 @@ export const baseConfig = async ({ ssr, appDir, publicDir, base = '/', command =
201
195
  ...vitrifyConfig.vitrify.ssr.serverModules
202
196
  ];
203
197
  const plugins = [
204
- vuePlugin({
205
- // compiler: await import('vue/compiler-sfc'),
206
- // template: {
207
- // ssr: !!ssr,
208
- // compilerOptions: {
209
- // directiveTransforms: {
210
- // 'close-popup': ssrTransformCustomDir,
211
- // intersection: ssrTransformCustomDir,
212
- // ripple: ssrTransformCustomDir,
213
- // mutation: ssrTransformCustomDir,
214
- // morph: ssrTransformCustomDir,
215
- // scroll: ssrTransformCustomDir,
216
- // 'scroll-fire': ssrTransformCustomDir,
217
- // 'touch-hold': ssrTransformCustomDir,
218
- // 'touch-pan': ssrTransformCustomDir,
219
- // 'touch-repeat': ssrTransformCustomDir,
220
- // 'touch-swipe': ssrTransformCustomDir
221
- // }
222
- // }
223
- // }
224
- }),
198
+ vuePlugin(),
225
199
  ...frameworkPlugins,
226
200
  {
227
201
  name: 'vitrify-setup',
@@ -236,21 +210,14 @@ export const baseConfig = async ({ ssr, appDir, publicDir, base = '/', command =
236
210
  sassVariables = config.vitrify?.sass?.variables || {};
237
211
  globalSass = config.vitrify?.sass?.global || [];
238
212
  additionalData = config.vitrify?.sass?.additionalData || [];
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
- }
253
- };
213
+ return {};
214
+ },
215
+ configureServer(server) {
216
+ server.middlewares.use('/', (req, res, next) => {
217
+ if (req.url?.endsWith('.html'))
218
+ req.url = req.url.replace('.html', '');
219
+ next();
220
+ });
254
221
  },
255
222
  configResolved: (config) => {
256
223
  if (process.env.DEBUG) {
@@ -283,24 +250,21 @@ export const baseConfig = async ({ ssr, appDir, publicDir, base = '/', command =
283
250
  .join(', ')}]
284
251
  export const onSetup = []
285
252
  ${onSetupFiles
286
- .map((url, index) => `import ${url.pathname
287
- .replaceAll('/', '')
288
- .replaceAll('.', '')} from '${url.pathname}'; onSetup.push(${url.pathname
289
- .replaceAll('/', '')
290
- .replaceAll('.', '')})`)
253
+ .map((url, index) => {
254
+ const varName = url.pathname
255
+ .replaceAll('/', '')
256
+ .replaceAll('.', '')
257
+ .replaceAll('-', '');
258
+ return `import ${varName} from '${url.pathname}'; onSetup.push(${varName})`;
259
+ })
291
260
  .join('\n')}`;
292
- // export const onSetup = [${onSetupHooks
293
- // .map((fn) => `${String(fn)}`)
294
- // .join(', ')}]`
295
- /**
296
- * CSS imports in virtual files do not seem to work. Using transform() instead
297
- */
298
- // } else if (id === 'virtual:global-css') {
299
- // return `${globalCss.map((css) => `import '${css}'`).join('\n')}`
300
261
  }
301
262
  else if (id === 'virtual:static-imports') {
302
263
  return `${Object.entries(staticImports)
303
- .map(([key, value]) => `export { ${value.join(',')} } from '${key}';`)
264
+ .map(([key, value]) => {
265
+ const deduped = [...new Set(value)];
266
+ return `export { ${deduped.join(',')} } from '${key}';`;
267
+ })
304
268
  .join('\n')}`;
305
269
  }
306
270
  else if (id === 'vitrify.sass') {
@@ -310,7 +274,10 @@ export const baseConfig = async ({ ssr, appDir, publicDir, base = '/', command =
310
274
  ].join('\n');
311
275
  }
312
276
  else if (id === 'vitrify.css') {
313
- return `${globalCss.map((css) => `import '${css}'`).join('\n')}`;
277
+ return `${globalCss.map((css) => `@import '${css}'`).join('\n')}`;
278
+ }
279
+ else if (id === 'virtual:vitrify-config') {
280
+ return `export default ${JSON.stringify(vitrifyConfig)}`;
314
281
  }
315
282
  return null;
316
283
  }
@@ -320,16 +287,16 @@ export const baseConfig = async ({ ssr, appDir, publicDir, base = '/', command =
320
287
  plugins.unshift({
321
288
  name: 'html-transform',
322
289
  enforce: 'pre',
323
- transform: (code, id) => {
324
- if (id.endsWith('App.vue')) {
325
- code =
326
- code +
327
- `<style lang="sass">
328
- // do not remove, required for additionalData import
329
- </style>`;
330
- }
331
- return code;
332
- },
290
+ // transform: (code, id) => {
291
+ // if (id.endsWith('App.vue')) {
292
+ // code =
293
+ // code +
294
+ // `<style lang="sass">
295
+ // // do not remove, required for additionalData import
296
+ // </style>`
297
+ // }
298
+ // return code
299
+ // },
333
300
  transformIndexHtml: {
334
301
  enforce: 'pre',
335
302
  transform: (html) => {
@@ -386,17 +353,10 @@ export const baseConfig = async ({ ssr, appDir, publicDir, base = '/', command =
386
353
  find: new RegExp('^vue$'),
387
354
  replacement: new URL('./dist/vue.runtime.esm-bundler.js', packageUrls['vue']).pathname
388
355
  },
389
- // {
390
- // find: new RegExp('^vue/server-renderer$'),
391
- // replacement: 'vue/server-renderer/index.mjs'
392
- // },
393
356
  {
394
357
  find: new RegExp('^vue-router$'),
395
358
  replacement: new URL('./dist/vue-router.esm-bundler.js', packageUrls['vue-router']).pathname
396
359
  }
397
- // { find: 'vue', replacement: packageUrls['vue'].pathname },
398
- // { find: 'vue-router', replacement: packageUrls['vue-router'].pathname },
399
- // { find: 'vitrify', replacement: cliDir.pathname }
400
360
  ];
401
361
  if (mode === 'development' && vitrifyConfig.vitrify?.dev?.alias)
402
362
  alias.push(...vitrifyConfig.vitrify.dev.alias);
@@ -420,25 +380,16 @@ export const baseConfig = async ({ ssr, appDir, publicDir, base = '/', command =
420
380
  ],
421
381
  external,
422
382
  output: {
423
- minifyInternalExports: !debug,
383
+ minifyInternalExports: false,
424
384
  entryFileNames: '[name].mjs',
425
385
  chunkFileNames: '[name].mjs',
426
386
  format: 'es',
427
387
  manualChunks
428
- // manualChunks: (id) => {
429
- // if (id.includes('vitrify/src/vite/')) {
430
- // const name = id.split('/').at(-1)?.split('.').at(0)
431
- // if (name && manualChunks.includes(name)) return name
432
- // } else if (id.includes('node_modules')) {
433
- // return 'vendor'
434
- // }
435
- // }
436
388
  }
437
389
  };
438
390
  // Create a SSR bundle
439
391
  noExternal = [
440
392
  new RegExp(`^(?!(${[...builtinModules, ...serverModules].join('|')}))`)
441
- // new RegExp(`^(?!.*(${[...builtinModules, ...serverModules].join('|')}))`)
442
393
  ];
443
394
  }
444
395
  else if (ssr === 'fastify') {
@@ -452,14 +403,6 @@ export const baseConfig = async ({ ssr, appDir, publicDir, base = '/', command =
452
403
  chunkFileNames: '[name].mjs',
453
404
  format: 'es',
454
405
  manualChunks
455
- // manualChunks: (id) => {
456
- // if (id.includes('vitrify/src/vite/')) {
457
- // const name = id.split('/').at(-1)?.split('.').at(0)
458
- // if (name && manualChunks.includes(name)) return name
459
- // } else if (id.includes('node_modules')) {
460
- // return 'vendor'
461
- // }
462
- // }
463
406
  }
464
407
  };
465
408
  // Create a SSR bundle
@@ -470,13 +413,9 @@ export const baseConfig = async ({ ssr, appDir, publicDir, base = '/', command =
470
413
  else {
471
414
  rollupOptions = {
472
415
  ...rollupOptions,
473
- // input: [
474
- // new URL('index.html', frameworkDir).pathname
475
- // // new URL('csr/server.ts', frameworkDir).pathname
476
- // ],
477
416
  external,
478
417
  output: {
479
- minifyInternalExports: !debug,
418
+ minifyInternalExports: false,
480
419
  entryFileNames: '[name].mjs',
481
420
  chunkFileNames: '[name].mjs',
482
421
  format: 'es',
@@ -485,7 +424,6 @@ export const baseConfig = async ({ ssr, appDir, publicDir, base = '/', command =
485
424
  };
486
425
  }
487
426
  const config = {
488
- // root: ssr === 'fastify' ? appDir.pathname : frameworkDir.pathname,
489
427
  root: appDir.pathname,
490
428
  publicDir: publicDir.pathname,
491
429
  base,
@@ -513,33 +451,6 @@ export const baseConfig = async ({ ssr, appDir, publicDir, base = '/', command =
513
451
  ssr: ssr === 'server' || ssr === 'fastify' ? true : false,
514
452
  ssrManifest: ssr === 'client' || ssr === 'ssg',
515
453
  rollupOptions
516
- // ssr === 'server'
517
- // ? {
518
- // input: [
519
- // new URL('ssr/entry-server.ts', frameworkDir).pathname,
520
- // new URL('ssr/prerender.ts', frameworkDir).pathname,
521
- // new URL('ssr/server.ts', frameworkDir).pathname
522
- // ],
523
- // output: {
524
- // minifyInternalExports: false,
525
- // entryFileNames: '[name].mjs',
526
- // chunkFileNames: '[name].mjs',
527
- // format: 'es',
528
- // manualChunks: (id) => {
529
- // if (id.includes('vitrify/src/vite/')) {
530
- // const name = id.split('/').at(-1)?.split('.').at(0)
531
- // if (name && manualChunks.includes(name)) return name
532
- // } else if (id.includes('node_modules')) {
533
- // return 'vendor'
534
- // }
535
- // }
536
- // }
537
- // }
538
- // : {
539
- // output: {
540
- // format: 'es'
541
- // }
542
- // }
543
454
  },
544
455
  ssr: {
545
456
  // Create a SSR bundle
@@ -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,12 @@ 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');
79
82
  app.use(staticImports?.Quasar, {
80
83
  plugins: quasarPlugins,
81
- directives
84
+ directives,
85
+ lang
82
86
  }, ssrContext);
83
87
  }
84
88
  ];
@@ -106,7 +110,11 @@ export const QuasarPlugin = async ({ ssr = false, pwa = false }) => {
106
110
  name: 'vite-plugin-quasar',
107
111
  enforce: 'post',
108
112
  config: async (config, env) => {
109
- const { quasar: quasarConf, vitrify: { urls } = {} } = config;
113
+ const { quasar, vitrify: { urls } = {} } = config;
114
+ if (quasar)
115
+ quasarConf = quasar;
116
+ if (!quasarConf.framework.lang && config.vitrify?.lang)
117
+ quasarConf.framework.lang = config.vitrify.lang;
110
118
  // const quasarPkgJsonPath = new URL(
111
119
  // 'package.json',
112
120
  // urls?.packages?.quasar
@@ -244,6 +252,8 @@ export const QuasarPlugin = async ({ ssr = false, pwa = false }) => {
244
252
  return 'virtual:quasar-plugins';
245
253
  case 'virtual:quasar-directives':
246
254
  return 'virtual:quasar-directives';
255
+ case 'virtual:quasar-lang':
256
+ return 'virtual:quasar-lang';
247
257
  case 'virtual:quasar':
248
258
  return { id: 'virtual:quasar', moduleSideEffects: false };
249
259
  default:
@@ -257,6 +267,10 @@ export const QuasarPlugin = async ({ ssr = false, pwa = false }) => {
257
267
  else if (id === 'virtual:quasar-directives') {
258
268
  return `export * from 'quasar/src/directives.js'`;
259
269
  }
270
+ else if (id === 'virtual:quasar-lang') {
271
+ return `import lang from 'quasar/lang/${quasarConf?.framework?.lang || 'en-US'}';
272
+ export default lang`;
273
+ }
260
274
  else if (id === 'virtual:quasar') {
261
275
  return `export * from 'quasar/src/plugins.js';
262
276
  export * from 'quasar/src/components.js';
@@ -1,6 +1,5 @@
1
1
  /// <reference types="node" />
2
2
  import type { LogLevel, InlineConfig } from 'vite';
3
- import { ViteDevServer } from 'vite';
4
3
  import type { Server } from 'net';
5
4
  export declare function createVitrifyDevServer({ port, logLevel, ssr, framework, host, appDir, publicDir, base }: {
6
5
  port?: number;
@@ -11,7 +10,7 @@ export declare function createVitrifyDevServer({ port, logLevel, ssr, framework,
11
10
  appDir?: URL;
12
11
  publicDir?: URL;
13
12
  base?: string;
14
- }): Promise<ViteDevServer>;
13
+ }): Promise<import("vite").ViteDevServer>;
15
14
  export declare function createServer({ port, logLevel, ssr, framework, host, appDir, publicDir }: {
16
15
  port?: number;
17
16
  logLevel?: LogLevel;
@@ -42,7 +41,7 @@ export declare function createServer({ port, logLevel, ssr, framework, host, app
42
41
  server: import("vite").ResolvedServerOptions;
43
42
  build: Required<import("vite").BuildOptions>;
44
43
  preview: import("vite").ResolvedPreviewOptions;
45
- ssr: import("vite").ResolvedSSROptions | undefined;
44
+ ssr: import("vite").ResolvedSSROptions;
46
45
  assetsInclude: (file: string) => boolean;
47
46
  logger: import("vite").Logger;
48
47
  createResolver: (options?: Partial<import("vite").InternalResolveOptions> | undefined) => import("vite").ResolveFn;
@@ -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[]>;
@@ -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[];
@@ -1,6 +1,7 @@
1
1
  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
+ import type { FastifyServerOptions } from 'fastify';
4
5
  export declare type BootFunction = ({ app, ssrContext, staticImports }: {
5
6
  app: any;
6
7
  ssrContext: Record<string, unknown>;
@@ -18,6 +19,7 @@ export declare type OnRenderedHook = (html: string, ssrContext: Record<string, a
18
19
  export declare type OnSetupFile = URL;
19
20
  export interface VitrifyConfig extends UserConfig {
20
21
  vitrify?: {
22
+ lang?: string;
21
23
  /**
22
24
  * Global CSS imports
23
25
  */
@@ -71,6 +73,7 @@ export interface VitrifyConfig extends UserConfig {
71
73
  */
72
74
  ssr?: {
73
75
  serverModules?: string[];
76
+ fastify?: FastifyServerOptions;
74
77
  };
75
78
  /**
76
79
  * Development only configuration
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vitrify",
3
- "version": "0.6.16",
3
+ "version": "0.7.0",
4
4
  "license": "MIT",
5
5
  "author": "Stefan van Herwijnen",
6
6
  "description": "Pre-configured Vite CLI for your framework",
@@ -57,47 +57,47 @@
57
57
  },
58
58
  "dependencies": {
59
59
  "@fastify/middie": "^8.0.0",
60
- "@fastify/static": "^6.4.0",
61
- "@quasar/extras": "^1.14.2",
62
- "@vitejs/plugin-vue": "^3.0.0-alpha.1",
60
+ "@fastify/static": "^6.5.0",
61
+ "@quasar/extras": "^1.15.1",
62
+ "@vitejs/plugin-vue": "^3.0.1",
63
63
  "builtin-modules": "^3.3.0",
64
64
  "cac": "^6.7.12",
65
65
  "chalk": "^5.0.1",
66
66
  "critters": "^0.0.16",
67
67
  "cross-env": "^7.0.3",
68
- "esbuild": "^0.14.48",
69
- "fastify": "^4.2.0",
68
+ "esbuild": "^0.14.51",
69
+ "fastify": "^4.3.0",
70
70
  "glob": "^8.0.3",
71
- "happy-dom": "^6.0.0",
71
+ "happy-dom": "^6.0.4",
72
72
  "magic-string": "^0.26.2",
73
73
  "merge-deep": "^3.0.3",
74
74
  "readline": "^1.3.0",
75
- "rollup-plugin-visualizer": "^5.6.0",
76
- "sass": "1.53.0",
77
- "ts-node": "^10.8.2",
78
- "unplugin-vue-components": "^0.21.0",
79
- "vite": "3.0.0-beta.6",
80
- "vitest": "^0.17.0"
75
+ "rollup-plugin-visualizer": "^5.7.1",
76
+ "sass": "1.54.0",
77
+ "ts-node": "^10.9.1",
78
+ "unplugin-vue-components": "^0.21.2",
79
+ "vite": "^3.0.4",
80
+ "vitest": "^0.20.2"
81
81
  },
82
82
  "devDependencies": {
83
83
  "@types/connect": "^3.4.35",
84
84
  "@types/glob": "^7.2.0",
85
85
  "@types/merge-deep": "^3.0.0",
86
- "@types/node": "^18.0.1",
86
+ "@types/node": "^18.6.3",
87
87
  "@types/ws": "^8.5.3",
88
88
  "@vue/runtime-core": "^3.2.37",
89
- "quasar": "^2.7.5",
90
- "rollup": "^2.75.7",
89
+ "quasar": "^2.7.6",
90
+ "rollup": "^2.77.2",
91
91
  "typescript": "^4.7.4",
92
92
  "vue": "^3.2.37",
93
- "vue-router": "^4.1.0"
93
+ "vue-router": "^4.1.3"
94
94
  },
95
95
  "peerDependencies": {
96
- "@fastify/static": "^6.4.0",
97
- "fastify": "^4.2.0",
98
- "quasar": "^2.7.5",
96
+ "@fastify/static": "^6.5.0",
97
+ "fastify": "^4.3.0",
98
+ "quasar": "^2.7.6",
99
99
  "vue": "^3.2.37",
100
- "vue-router": "^4.1.0"
100
+ "vue-router": "^4.1.3"
101
101
  },
102
102
  "publishConfig": {
103
103
  "access": "public",
@@ -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:
@@ -1,13 +1,11 @@
1
1
  import type { LogLevel, InlineConfig } from 'vite'
2
- import { ViteDevServer, mergeConfig } from 'vite'
3
2
  import { searchForWorkspaceRoot } from 'vite'
4
3
  import { baseConfig } from '../index.js'
5
4
  import type { Server } from 'net'
6
- import type { FastifyInstance } from 'fastify/types/instance'
7
5
  import fastify from 'fastify'
6
+ import type { FastifyServerOptions } from 'fastify'
8
7
  import { fastifySsrPlugin } from '../frameworks/vue/fastify-ssr-plugin.js'
9
- import type { ServerOptions } from 'https'
10
- import type { OnRenderedHook } from '../vitrify-config.js'
8
+ import type { OnRenderedHook, VitrifyConfig } from '../vitrify-config.js'
11
9
 
12
10
  export async function createVitrifyDevServer({
13
11
  port = 3000,
@@ -130,6 +128,7 @@ export async function createServer({
130
128
  let setup
131
129
  let server: Server
132
130
  let onRendered: OnRenderedHook[]
131
+ let vitrifyConfig: VitrifyConfig
133
132
 
134
133
  console.log(`Development mode: ${ssr ? ssr : 'csr'}`)
135
134
  if (ssr) {
@@ -138,11 +137,13 @@ export async function createServer({
138
137
  ? new URL('src/vite/fastify/entry.ts', cliDir).pathname
139
138
  : new URL(`src/vite/${framework}/ssr/app.ts`, cliDir).pathname
140
139
 
141
- ;({ setup, onRendered } = await vite.ssrLoadModule(entryUrl))
140
+ ;({ setup, onRendered, vitrifyConfig } = await vite.ssrLoadModule(entryUrl))
141
+ console.log(vitrifyConfig)
142
142
  const app = fastify({
143
143
  logger: false,
144
- https: vite.config.server.https as ServerOptions
145
- })
144
+ https: vite.config.server.https,
145
+ ...vitrifyConfig.vitrify?.ssr?.fastify
146
+ } as FastifyServerOptions)
146
147
  if (process.env) process.env.MODE = 'development'
147
148
  if (setup) {
148
149
  await setup({
@@ -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'))
package/src/node/index.ts CHANGED
@@ -21,7 +21,7 @@ import type {
21
21
  } from './vitrify-config.js'
22
22
  import type { VitrifyContext } from './bin/run.js'
23
23
  import type { VitrifyPlugin } from './plugins/index.js'
24
- import { getPkgJsonDir, resolve } from './app-urls.js'
24
+ import { resolve } from './app-urls.js'
25
25
  import type { ManualChunksOption, RollupOptions } from 'rollup'
26
26
 
27
27
  const internalServerModules = [
@@ -75,8 +75,8 @@ const manualChunks: ManualChunksOption = (id: string) => {
75
75
 
76
76
  export const VIRTUAL_MODULES = [
77
77
  'virtual:vitrify-hooks',
78
- 'virtual:global-css',
79
78
  'virtual:static-imports',
79
+ 'virtual:vitrify-config',
80
80
  'vitrify.sass',
81
81
  'vitrify.css'
82
82
  ]
@@ -237,13 +237,6 @@ export const baseConfig = async ({
237
237
  console.error('package.json not found')
238
238
  }
239
239
 
240
- const ssrTransformCustomDir = () => {
241
- return {
242
- props: [],
243
- needRuntime: true
244
- }
245
- }
246
-
247
240
  const frameworkPlugins = []
248
241
  for (const framework of Object.keys(configPluginMap)) {
249
242
  if (Object.keys(vitrifyConfig).includes(framework)) {
@@ -275,27 +268,7 @@ export const baseConfig = async ({
275
268
  ]
276
269
 
277
270
  const plugins: UserConfig['plugins'] = [
278
- vuePlugin({
279
- // compiler: await import('vue/compiler-sfc'),
280
- // template: {
281
- // ssr: !!ssr,
282
- // compilerOptions: {
283
- // directiveTransforms: {
284
- // 'close-popup': ssrTransformCustomDir,
285
- // intersection: ssrTransformCustomDir,
286
- // ripple: ssrTransformCustomDir,
287
- // mutation: ssrTransformCustomDir,
288
- // morph: ssrTransformCustomDir,
289
- // scroll: ssrTransformCustomDir,
290
- // 'scroll-fire': ssrTransformCustomDir,
291
- // 'touch-hold': ssrTransformCustomDir,
292
- // 'touch-pan': ssrTransformCustomDir,
293
- // 'touch-repeat': ssrTransformCustomDir,
294
- // 'touch-swipe': ssrTransformCustomDir
295
- // }
296
- // }
297
- // }
298
- }),
271
+ vuePlugin(),
299
272
  ...frameworkPlugins,
300
273
  {
301
274
  name: 'vitrify-setup',
@@ -311,21 +284,13 @@ export const baseConfig = async ({
311
284
  globalSass = config.vitrify?.sass?.global || []
312
285
  additionalData = config.vitrify?.sass?.additionalData || []
313
286
 
314
- return {
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
- }
328
- }
287
+ return {}
288
+ },
289
+ configureServer(server) {
290
+ server.middlewares.use('/', (req, res, next) => {
291
+ if (req.url?.endsWith('.html')) req.url = req.url.replace('.html', '')
292
+ next()
293
+ })
329
294
  },
330
295
  configResolved: (config) => {
331
296
  if (process.env.DEBUG) {
@@ -357,30 +322,20 @@ export const baseConfig = async ({
357
322
  .join(', ')}]
358
323
  export const onSetup = []
359
324
  ${onSetupFiles
360
- .map(
361
- (url, index) =>
362
- `import ${url.pathname
363
- .replaceAll('/', '')
364
- .replaceAll('.', '')} from '${
365
- url.pathname
366
- }'; onSetup.push(${url.pathname
367
- .replaceAll('/', '')
368
- .replaceAll('.', '')})`
369
- )
325
+ .map((url, index) => {
326
+ const varName = url.pathname
327
+ .replaceAll('/', '')
328
+ .replaceAll('.', '')
329
+ .replaceAll('-', '')
330
+ return `import ${varName} from '${url.pathname}'; onSetup.push(${varName})`
331
+ })
370
332
  .join('\n')}`
371
- // export const onSetup = [${onSetupHooks
372
- // .map((fn) => `${String(fn)}`)
373
- // .join(', ')}]`
374
- /**
375
- * CSS imports in virtual files do not seem to work. Using transform() instead
376
- */
377
- // } else if (id === 'virtual:global-css') {
378
- // return `${globalCss.map((css) => `import '${css}'`).join('\n')}`
379
333
  } else if (id === 'virtual:static-imports') {
380
334
  return `${Object.entries(staticImports)
381
- .map(
382
- ([key, value]) => `export { ${value.join(',')} } from '${key}';`
383
- )
335
+ .map(([key, value]) => {
336
+ const deduped = [...new Set(value)]
337
+ return `export { ${deduped.join(',')} } from '${key}';`
338
+ })
384
339
  .join('\n')}`
385
340
  } else if (id === 'vitrify.sass') {
386
341
  return [
@@ -390,7 +345,9 @@ export const baseConfig = async ({
390
345
  ...globalSass.map((sass) => `@import '${sass}'`)
391
346
  ].join('\n')
392
347
  } else if (id === 'vitrify.css') {
393
- return `${globalCss.map((css) => `import '${css}'`).join('\n')}`
348
+ return `${globalCss.map((css) => `@import '${css}'`).join('\n')}`
349
+ } else if (id === 'virtual:vitrify-config') {
350
+ return `export default ${JSON.stringify(vitrifyConfig)}`
394
351
  }
395
352
  return null
396
353
  }
@@ -400,16 +357,16 @@ export const baseConfig = async ({
400
357
  plugins.unshift({
401
358
  name: 'html-transform',
402
359
  enforce: 'pre',
403
- transform: (code, id) => {
404
- if (id.endsWith('App.vue')) {
405
- code =
406
- code +
407
- `<style lang="sass">
408
- // do not remove, required for additionalData import
409
- </style>`
410
- }
411
- return code
412
- },
360
+ // transform: (code, id) => {
361
+ // if (id.endsWith('App.vue')) {
362
+ // code =
363
+ // code +
364
+ // `<style lang="sass">
365
+ // // do not remove, required for additionalData import
366
+ // </style>`
367
+ // }
368
+ // return code
369
+ // },
413
370
  transformIndexHtml: {
414
371
  enforce: 'pre',
415
372
  transform: (html) => {
@@ -471,10 +428,6 @@ export const baseConfig = async ({
471
428
  packageUrls['vue']
472
429
  ).pathname
473
430
  },
474
- // {
475
- // find: new RegExp('^vue/server-renderer$'),
476
- // replacement: 'vue/server-renderer/index.mjs'
477
- // },
478
431
  {
479
432
  find: new RegExp('^vue-router$'),
480
433
  replacement: new URL(
@@ -482,9 +435,6 @@ export const baseConfig = async ({
482
435
  packageUrls['vue-router']
483
436
  ).pathname
484
437
  }
485
- // { find: 'vue', replacement: packageUrls['vue'].pathname },
486
- // { find: 'vue-router', replacement: packageUrls['vue-router'].pathname },
487
- // { find: 'vitrify', replacement: cliDir.pathname }
488
438
  ]
489
439
  if (mode === 'development' && vitrifyConfig.vitrify?.dev?.alias)
490
440
  alias.push(...vitrifyConfig.vitrify.dev.alias)
@@ -511,25 +461,16 @@ export const baseConfig = async ({
511
461
  ],
512
462
  external,
513
463
  output: {
514
- minifyInternalExports: !debug,
464
+ minifyInternalExports: false,
515
465
  entryFileNames: '[name].mjs',
516
466
  chunkFileNames: '[name].mjs',
517
467
  format: 'es',
518
468
  manualChunks
519
- // manualChunks: (id) => {
520
- // if (id.includes('vitrify/src/vite/')) {
521
- // const name = id.split('/').at(-1)?.split('.').at(0)
522
- // if (name && manualChunks.includes(name)) return name
523
- // } else if (id.includes('node_modules')) {
524
- // return 'vendor'
525
- // }
526
- // }
527
469
  }
528
470
  }
529
471
  // Create a SSR bundle
530
472
  noExternal = [
531
473
  new RegExp(`^(?!(${[...builtinModules, ...serverModules].join('|')}))`)
532
- // new RegExp(`^(?!.*(${[...builtinModules, ...serverModules].join('|')}))`)
533
474
  ]
534
475
  } else if (ssr === 'fastify') {
535
476
  rollupOptions = {
@@ -542,14 +483,6 @@ export const baseConfig = async ({
542
483
  chunkFileNames: '[name].mjs',
543
484
  format: 'es',
544
485
  manualChunks
545
- // manualChunks: (id) => {
546
- // if (id.includes('vitrify/src/vite/')) {
547
- // const name = id.split('/').at(-1)?.split('.').at(0)
548
- // if (name && manualChunks.includes(name)) return name
549
- // } else if (id.includes('node_modules')) {
550
- // return 'vendor'
551
- // }
552
- // }
553
486
  }
554
487
  }
555
488
  // Create a SSR bundle
@@ -559,13 +492,9 @@ export const baseConfig = async ({
559
492
  } else {
560
493
  rollupOptions = {
561
494
  ...rollupOptions,
562
- // input: [
563
- // new URL('index.html', frameworkDir).pathname
564
- // // new URL('csr/server.ts', frameworkDir).pathname
565
- // ],
566
495
  external,
567
496
  output: {
568
- minifyInternalExports: !debug,
497
+ minifyInternalExports: false,
569
498
  entryFileNames: '[name].mjs',
570
499
  chunkFileNames: '[name].mjs',
571
500
  format: 'es',
@@ -575,7 +504,6 @@ export const baseConfig = async ({
575
504
  }
576
505
 
577
506
  const config = {
578
- // root: ssr === 'fastify' ? appDir.pathname : frameworkDir.pathname,
579
507
  root: appDir.pathname,
580
508
  publicDir: publicDir.pathname,
581
509
  base,
@@ -603,33 +531,6 @@ export const baseConfig = async ({
603
531
  ssr: ssr === 'server' || ssr === 'fastify' ? true : false,
604
532
  ssrManifest: ssr === 'client' || ssr === 'ssg',
605
533
  rollupOptions
606
- // ssr === 'server'
607
- // ? {
608
- // input: [
609
- // new URL('ssr/entry-server.ts', frameworkDir).pathname,
610
- // new URL('ssr/prerender.ts', frameworkDir).pathname,
611
- // new URL('ssr/server.ts', frameworkDir).pathname
612
- // ],
613
- // output: {
614
- // minifyInternalExports: false,
615
- // entryFileNames: '[name].mjs',
616
- // chunkFileNames: '[name].mjs',
617
- // format: 'es',
618
- // manualChunks: (id) => {
619
- // if (id.includes('vitrify/src/vite/')) {
620
- // const name = id.split('/').at(-1)?.split('.').at(0)
621
- // if (name && manualChunks.includes(name)) return name
622
- // } else if (id.includes('node_modules')) {
623
- // return 'vendor'
624
- // }
625
- // }
626
- // }
627
- // }
628
- // : {
629
- // output: {
630
- // format: 'es'
631
- // }
632
- // }
633
534
  },
634
535
  ssr: {
635
536
  // Create a SSR bundle
@@ -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')
153
+ // @ts-ignore
154
+ const { default: lang } = await import('virtual:quasar-lang')
151
155
 
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
@@ -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';
@@ -1,6 +1,7 @@
1
1
  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
+ import type { FastifyServerOptions } from 'fastify'
4
5
 
5
6
  export type BootFunction = ({
6
7
  app,
@@ -39,6 +40,7 @@ export type OnRenderedHook = (
39
40
  export type OnSetupFile = URL
40
41
  export interface VitrifyConfig extends UserConfig {
41
42
  vitrify?: {
43
+ lang?: string
42
44
  /**
43
45
  * Global CSS imports
44
46
  */
@@ -92,6 +94,7 @@ export interface VitrifyConfig extends UserConfig {
92
94
  */
93
95
  ssr?: {
94
96
  serverModules?: string[]
97
+ fastify?: FastifyServerOptions
95
98
  }
96
99
  /**
97
100
  * Development only configuration
@@ -1,5 +1,6 @@
1
1
  import type { FastifyInstance } from 'fastify'
2
2
  import { onSetup } from 'virtual:vitrify-hooks'
3
+ export { default as vitrifyConfig } from 'virtual:vitrify-config'
3
4
 
4
5
  export const setup = async ({ fastify }: { fastify: FastifyInstance }) => {
5
6
  if (onSetup?.length) {
@@ -1,8 +1,9 @@
1
1
  import Fastify from 'fastify'
2
- import { setup } from './entry'
2
+ import { setup, vitrifyConfig } from './entry'
3
3
 
4
4
  const fastify = Fastify({
5
- logger: true
5
+ logger: true,
6
+ ...vitrifyConfig.vitrify?.ssr.fastify
6
7
  })
7
8
  await setup({ fastify })
8
9
 
@@ -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,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 }