vitrify 0.2.4 → 0.4.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.
Files changed (47) hide show
  1. package/dist/app-urls.js +1 -2
  2. package/dist/bin/build.js +0 -43
  3. package/dist/bin/cli.js +29 -7
  4. package/dist/bin/dev.js +58 -67
  5. package/dist/frameworks/vue/fastify-ssr-plugin.js +67 -23
  6. package/dist/frameworks/vue/prerender.js +3 -3
  7. package/dist/frameworks/vue/server.js +9 -10
  8. package/dist/helpers/collect-css-ssr.js +57 -0
  9. package/dist/helpers/logger.js +0 -72
  10. package/dist/index.js +268 -122
  11. package/dist/plugins/quasar.js +13 -106
  12. package/dist/types/bin/build.d.ts +2 -2
  13. package/dist/types/bin/dev.d.ts +39 -3
  14. package/dist/types/frameworks/vue/fastify-ssr-plugin.d.ts +6 -3
  15. package/dist/types/frameworks/vue/prerender.d.ts +3 -3
  16. package/dist/types/frameworks/vue/server.d.ts +9 -5
  17. package/dist/types/helpers/collect-css-ssr.d.ts +10 -0
  18. package/dist/types/helpers/logger.d.ts +0 -19
  19. package/dist/types/helpers/routes.d.ts +1 -1
  20. package/dist/types/index.d.ts +1 -1
  21. package/dist/types/plugins/index.d.ts +1 -1
  22. package/dist/types/vitrify-config.d.ts +20 -16
  23. package/package.json +32 -32
  24. package/src/node/app-urls.ts +1 -2
  25. package/src/node/bin/build.ts +2 -49
  26. package/src/node/bin/cli.ts +36 -8
  27. package/src/node/bin/dev.ts +89 -75
  28. package/src/node/bin/test.ts +0 -3
  29. package/src/node/frameworks/vue/fastify-ssr-plugin.ts +80 -26
  30. package/src/node/frameworks/vue/prerender.ts +5 -5
  31. package/src/node/frameworks/vue/server.ts +22 -16
  32. package/src/node/helpers/collect-css-ssr.ts +77 -0
  33. package/src/node/helpers/logger.ts +0 -87
  34. package/src/node/index.ts +302 -137
  35. package/src/node/plugins/index.ts +1 -1
  36. package/src/node/plugins/quasar.ts +14 -111
  37. package/src/node/vitrify-config.ts +31 -16
  38. package/src/vite/fastify/entry.ts +11 -0
  39. package/src/vite/fastify/server.ts +10 -0
  40. package/src/vite/vue/index.html +1 -0
  41. package/src/vite/vue/main.ts +5 -20
  42. package/src/vite/vue/ssr/app.ts +25 -0
  43. package/src/vite/vue/ssr/entry-server.ts +13 -1
  44. package/src/vite/vue/ssr/fastify-ssr-plugin.ts +2 -118
  45. package/src/vite/vue/ssr/prerender.ts +2 -2
  46. package/src/vite/vue/ssr/server.ts +24 -15
  47. package/src/node/helpers/ssr.ts.bak +0 -52
package/dist/index.js CHANGED
@@ -1,21 +1,96 @@
1
1
  import vuePlugin from '@vitejs/plugin-vue';
2
2
  import { mergeConfig } from 'vite';
3
+ import { build } from 'esbuild';
4
+ import fs from 'fs';
5
+ import path from 'path';
6
+ import { pathToFileURL } from 'url';
3
7
  import { readFileSync } from 'fs';
4
8
  import builtinModules from 'builtin-modules';
5
9
  import { resolve } from 'import-meta-resolve';
6
10
  import { getPkgJsonDir } from './app-urls.js';
7
- const serverModules = ['fastify', 'middie'];
11
+ const serverModules = [
12
+ // 'fs',
13
+ // 'path',
14
+ // 'url',
15
+ // 'module',
16
+ // 'crypto',
17
+ // 'node:fs',
18
+ 'util',
19
+ 'node:url',
20
+ 'node:util',
21
+ 'node:fs',
22
+ 'vitrify',
23
+ 'vite',
24
+ 'fastify',
25
+ 'middie',
26
+ 'knex',
27
+ 'bcrypt',
28
+ 'objection',
29
+ '@fastify/formbody',
30
+ '@fastify/static',
31
+ '@fastify/cors',
32
+ '@fastify/cookie',
33
+ 'mercurius',
34
+ 'jose',
35
+ 'oidc-provider'
36
+ ];
8
37
  const configPluginMap = {
9
38
  quasar: () => import('./plugins/quasar.js').then((module) => module.QuasarPlugin)
10
39
  };
40
+ const manualChunks = ['prerender', 'fastify-ssr-plugin', 'server'];
11
41
  export const VIRTUAL_MODULES = [
12
- 'virtual:fastify-setup',
13
- 'virtual:boot-functions',
14
- 'virtual:ssr-functions',
15
- 'virtual:on-mounted-hooks',
42
+ 'virtual:vitrify-hooks',
16
43
  'virtual:global-css',
17
44
  'virtual:static-imports'
18
45
  ];
46
+ async function bundleConfigFile(fileName, isESM = false) {
47
+ const result = await build({
48
+ absWorkingDir: process.cwd(),
49
+ entryPoints: [fileName],
50
+ outfile: 'out.js',
51
+ write: false,
52
+ platform: 'node',
53
+ bundle: true,
54
+ format: 'esm',
55
+ sourcemap: 'inline',
56
+ metafile: true,
57
+ plugins: [
58
+ {
59
+ name: 'externalize-deps',
60
+ setup(build) {
61
+ build.onResolve({ filter: /.*/ }, (args) => {
62
+ const id = args.path;
63
+ if (id[0] !== '.' && !path.isAbsolute(id)) {
64
+ return {
65
+ external: true
66
+ };
67
+ }
68
+ });
69
+ }
70
+ },
71
+ {
72
+ name: 'replace-import-meta',
73
+ setup(build) {
74
+ build.onLoad({ filter: /\.[jt]s$/ }, async (args) => {
75
+ const contents = await fs.promises.readFile(args.path, 'utf8');
76
+ return {
77
+ loader: args.path.endsWith('.ts') ? 'ts' : 'js',
78
+ contents: contents
79
+ .replace(/\bimport\.meta\.url\b/g, JSON.stringify(pathToFileURL(args.path).href))
80
+ .replace(/\b__dirname\b/g, JSON.stringify(path.dirname(args.path)))
81
+ .replace(/\b__filename\b/g, JSON.stringify(args.path))
82
+ };
83
+ });
84
+ }
85
+ }
86
+ ]
87
+ });
88
+ const { text } = result.outputFiles[0];
89
+ return {
90
+ code: text,
91
+ dependencies: result.metafile ? Object.keys(result.metafile.inputs) : []
92
+ };
93
+ }
19
94
  export const baseConfig = async ({ ssr, appDir, publicDir, command = 'build', mode = 'production', framework = 'vue', pwa = false }) => {
20
95
  const { getAppDir, getCliDir, getCliViteDir, getSrcDir, getCwd } = await import('./app-urls.js');
21
96
  if (!appDir) {
@@ -25,37 +100,8 @@ export const baseConfig = async ({ ssr, appDir, publicDir, command = 'build', mo
25
100
  const cwd = getCwd();
26
101
  const cliDir = getCliDir();
27
102
  const cliViteDir = getCliViteDir(cliDir);
28
- // const {
29
- // appDir: tempAppDir,
30
- // cliDir,
31
- // cliViteDir,
32
- // srcDir
33
- // } = await import('./app-urls.js')
34
- // const cwd = appDir || tempAppDir
35
103
  const frameworkDir = new URL(`${framework}/`, cliViteDir);
36
- // const localPackages = ['vue', 'vue-router', 'quasar']
37
- const localPackages = ['vue', 'vue-router'];
38
- const cliPackages = ['vitest'];
39
- const packageUrls = {};
40
- await (async () => {
41
- for (const val of localPackages)
42
- packageUrls[val] = getPkgJsonDir(new URL(await resolve(val, appDir.href)));
43
- })();
44
- await (async () => {
45
- for (const val of cliPackages)
46
- packageUrls[val] = getPkgJsonDir(new URL(await resolve(val, cliDir.href)));
47
- })();
48
- // if (appDir) {
49
- // srcDir = new URL('src/', appDir);
50
- // quasarDir = new URL(await resolve('quasar/', appDir.href));
51
- // ({ appDir: cwd, cliDir } = await import('./app-urls.js'))
52
- // } else {
53
- // ({ appDir, cliDir, srcDir, quasarDir } = await import('./app-urls.js'))
54
- // cwd = appDir
55
- // }
56
- // vueDir = new URL('./', await resolve('vue', appDir.href));
57
- // vueRouterDir = new URL('../', await resolve('vue-router', appDir.href));
58
- // vitestDir = new URL('../', await resolve('vitest', cliDir.href));
104
+ const fastifyDir = new URL('fastify/', cliViteDir);
59
105
  if (!publicDir)
60
106
  publicDir = new URL('public/', appDir);
61
107
  /**
@@ -63,19 +109,46 @@ export const baseConfig = async ({ ssr, appDir, publicDir, command = 'build', mo
63
109
  */
64
110
  let vitrifyConfig;
65
111
  try {
66
- vitrifyConfig = (await import(new URL('vitrify.config.js', appDir).pathname)).default;
112
+ if (fs.existsSync(new URL('vitrify.config.ts', appDir).pathname)) {
113
+ const configPath = new URL('vitrify.config.ts', appDir).pathname;
114
+ const bundledConfig = await bundleConfigFile(new URL('vitrify.config.ts', appDir).pathname);
115
+ fs.writeFileSync(configPath + '.js', bundledConfig.code);
116
+ vitrifyConfig = (await import(configPath + '.js')).default;
117
+ // fs.unlinkSync(configPath + '.js')
118
+ }
119
+ else {
120
+ vitrifyConfig = (await import(new URL('vitrify.config.js', appDir).pathname)).default;
121
+ }
67
122
  if (typeof vitrifyConfig === 'function')
68
- vitrifyConfig = vitrifyConfig({ mode, command });
123
+ vitrifyConfig = await vitrifyConfig({ mode, command });
69
124
  }
70
125
  catch (e) {
71
- console.error(e);
72
- console.log('No vitrify.config.js file found, using defaults');
126
+ console.log('No vitrify.config.(ts|js) file found, using defaults');
73
127
  vitrifyConfig = {};
74
128
  }
75
- let { productName = 'Product name' } = JSON.parse(readFileSync(new URL('package.json', appDir).pathname, {
76
- encoding: 'utf-8'
77
- }));
78
- const fastifySetup = vitrifyConfig.vitrify?.fastify?.setup || ((fastify) => { });
129
+ const localPackages = ['vue', 'vue-router'];
130
+ const cliPackages = [];
131
+ const packageUrls = vitrifyConfig.vitrify?.urls?.packages || {};
132
+ await (async () => {
133
+ for (const val of localPackages)
134
+ packageUrls[val] = getPkgJsonDir(new URL(await resolve(val, appDir.href)));
135
+ })();
136
+ // await (async () => {
137
+ // for (const val of cliPackages)
138
+ // packageUrls[val] = getPkgJsonDir(
139
+ // new URL(await resolve(val, cliDir!.href))
140
+ // )
141
+ // })()
142
+ let productName = 'Product name';
143
+ try {
144
+ ;
145
+ ({ productName } = JSON.parse(readFileSync(new URL('package.json', appDir).pathname, {
146
+ encoding: 'utf-8'
147
+ })));
148
+ }
149
+ catch (e) {
150
+ console.error('package.json not found');
151
+ }
79
152
  const ssrTransformCustomDir = () => {
80
153
  return {
81
154
  props: [],
@@ -92,15 +165,17 @@ export const baseConfig = async ({ ssr, appDir, publicDir, command = 'build', mo
92
165
  }));
93
166
  }
94
167
  }
95
- let bootFunctions;
96
- let ssrFunctions;
168
+ let onBootHooks;
169
+ let onRenderedHooks;
97
170
  let onMountedHooks;
171
+ let onSetupFiles;
98
172
  let globalCss;
99
173
  let staticImports;
100
174
  let sassVariables;
101
175
  let additionalData;
102
176
  const plugins = [
103
177
  vuePlugin({
178
+ compiler: await import('vue/compiler-sfc'),
104
179
  template: {
105
180
  ssr: !!ssr,
106
181
  compilerOptions: {
@@ -121,18 +196,14 @@ export const baseConfig = async ({ ssr, appDir, publicDir, command = 'build', mo
121
196
  }
122
197
  }),
123
198
  ...frameworkPlugins,
124
- // await QuasarPlugin({
125
- // ssr: ssr,
126
- // pwa: pwa
127
- // // quasarDir: packageUrls.quasar
128
- // }),
129
199
  {
130
200
  name: 'vitrify-setup',
131
201
  enforce: 'post',
132
202
  config: async (config, env) => {
133
- bootFunctions = config.vitrify?.bootFunctions || [];
134
- ssrFunctions = config.vitrify?.ssrFunctions || [];
203
+ onBootHooks = config.vitrify?.hooks?.onBoot || [];
204
+ onRenderedHooks = config.vitrify?.hooks?.onRendered || [];
135
205
  onMountedHooks = config.vitrify?.hooks?.onMounted || [];
206
+ onSetupFiles = config?.vitrify?.hooks?.onSetup || [];
136
207
  globalCss = config.vitrify?.globalCss || [];
137
208
  staticImports = config.vitrify?.staticImports || {};
138
209
  sassVariables = config.vitrify?.sass?.variables || {};
@@ -159,30 +230,43 @@ export const baseConfig = async ({ ssr, appDir, publicDir, command = 'build', mo
159
230
  },
160
231
  resolveId(id) {
161
232
  if (VIRTUAL_MODULES.includes(id))
162
- return id;
233
+ return { id, moduleSideEffects: false };
163
234
  return;
164
235
  },
165
- load(id) {
166
- if (id === 'virtual:fastify-setup') {
167
- return `export const setup = ${String(fastifySetup)}`;
236
+ transform: (code, id) => {
237
+ if (id.endsWith('main.ts') && id.includes('vitrify')) {
238
+ code =
239
+ `${globalCss.map((css) => `import '${css}'`).join('\n')}\n` + code;
168
240
  }
169
- else if (id === 'virtual:boot-functions') {
170
- return `export default [${bootFunctions
241
+ return code;
242
+ },
243
+ load(id) {
244
+ if (id === 'virtual:vitrify-hooks') {
245
+ return `export const onBoot = [${onBootHooks
171
246
  .map((fn) => `${String(fn)}`)
172
- .join(', ')}]`;
173
- }
174
- else if (id === 'virtual:ssr-functions') {
175
- return `export default [${ssrFunctions
247
+ .join(', ')}]
248
+ export const onMounted = [${onMountedHooks
176
249
  .map((fn) => `${String(fn)}`)
177
- .join(', ')}]`;
178
- }
179
- else if (id === 'virtual:on-mounted-hooks') {
180
- return `export default [${onMountedHooks
250
+ .join(', ')}]
251
+ export const onRendered = [${onRenderedHooks
181
252
  .map((fn) => `${String(fn)}`)
182
- .join(', ')}]`;
183
- }
184
- else if (id === 'virtual:global-css') {
185
- return `${globalCss.map((css) => `import '${css}'`).join('\n')}`;
253
+ .join(', ')}]
254
+ export const onSetup = []
255
+ ${onSetupFiles
256
+ .map((url, index) => `import ${url.pathname
257
+ .replaceAll('/', '')
258
+ .replaceAll('.', '')} from '${url.pathname}'; onSetup.push(${url.pathname
259
+ .replaceAll('/', '')
260
+ .replaceAll('.', '')})`)
261
+ .join('\n')}`;
262
+ // export const onSetup = [${onSetupHooks
263
+ // .map((fn) => `${String(fn)}`)
264
+ // .join(', ')}]`
265
+ /**
266
+ * CSS imports in virtual files do not seem to work. Using transform() instead
267
+ */
268
+ // } else if (id === 'virtual:global-css') {
269
+ // return `${globalCss.map((css) => `import '${css}'`).join('\n')}`
186
270
  }
187
271
  else if (id === 'virtual:static-imports') {
188
272
  return `${Object.entries(staticImports)
@@ -217,6 +301,9 @@ export const baseConfig = async ({ ssr, appDir, publicDir, command = 'build', mo
217
301
  case 'client':
218
302
  entry = new URL('ssr/entry-client.ts', frameworkDir).pathname;
219
303
  break;
304
+ case 'fastify':
305
+ entry = new URL('entry.ts', fastifyDir).pathname;
306
+ break;
220
307
  default:
221
308
  entry = new URL('csr/entry.ts', frameworkDir).pathname;
222
309
  }
@@ -250,25 +337,94 @@ export const baseConfig = async ({ ssr, appDir, publicDir, command = 'build', mo
250
337
  { find: 'cwd', replacement: cwd.pathname },
251
338
  { find: 'boot', replacement: new URL('boot/', srcDir).pathname },
252
339
  { find: 'assets', replacement: new URL('assets/', srcDir).pathname },
253
- // ...Object.entries(packageUrls).map(([key, value]) => ({
254
- // find: key, replacement: value.pathname
255
- // })),
256
- { find: 'vue', replacement: packageUrls['vue'].pathname },
257
- { find: 'vue-router', replacement: packageUrls['vue-router'].pathname },
258
- { find: 'vitrify', replacement: cliDir.pathname }
340
+ ...Object.entries(packageUrls).map(([key, value]) => ({
341
+ find: key,
342
+ replacement: value.pathname
343
+ }))
344
+ // { find: 'vue', replacement: packageUrls['vue'].pathname },
345
+ // { find: 'vue-router', replacement: packageUrls['vue-router'].pathname },
346
+ // { find: 'vitrify', replacement: cliDir.pathname }
259
347
  ];
260
348
  if (command === 'test')
261
349
  alias.push({
262
350
  find: 'vitest',
263
- replacement: packageUrls.vitest.pathname
351
+ replacement: new URL(await resolve('vitest', cliDir.href)).pathname
264
352
  });
353
+ let rollupOptions;
354
+ let noExternal = [];
355
+ const external = [...builtinModules, ...serverModules];
356
+ if (ssr === 'server') {
357
+ rollupOptions = {
358
+ input: [
359
+ new URL('ssr/entry-server.ts', frameworkDir).pathname,
360
+ new URL('ssr/prerender.ts', frameworkDir).pathname,
361
+ new URL('ssr/server.ts', frameworkDir).pathname
362
+ ],
363
+ external,
364
+ output: {
365
+ minifyInternalExports: false,
366
+ entryFileNames: '[name].mjs',
367
+ chunkFileNames: '[name].mjs',
368
+ // format: 'es',
369
+ manualChunks: (id) => {
370
+ if (id.includes('vitrify/src/vite/')) {
371
+ const name = id.split('/').at(-1)?.split('.').at(0);
372
+ if (name && manualChunks.includes(name))
373
+ return name;
374
+ }
375
+ else if (id.includes('node_modules')) {
376
+ return 'vendor';
377
+ }
378
+ }
379
+ }
380
+ };
381
+ // Create a SSR bundle
382
+ noExternal = [
383
+ new RegExp(`^(?!(${[...builtinModules, ...serverModules].join('|')}))`)
384
+ // new RegExp(`^(?!.*(${[...builtinModules, ...serverModules].join('|')}))`)
385
+ ];
386
+ }
387
+ else if (ssr === 'fastify') {
388
+ rollupOptions = {
389
+ input: [new URL('server.ts', fastifyDir).pathname],
390
+ external,
391
+ output: {
392
+ minifyInternalExports: false,
393
+ entryFileNames: '[name].mjs',
394
+ chunkFileNames: '[name].mjs',
395
+ // format: 'es',
396
+ manualChunks: (id) => {
397
+ if (id.includes('vitrify/src/vite/')) {
398
+ const name = id.split('/').at(-1)?.split('.').at(0);
399
+ if (name && manualChunks.includes(name))
400
+ return name;
401
+ }
402
+ else if (id.includes('node_modules')) {
403
+ return 'vendor';
404
+ }
405
+ }
406
+ }
407
+ };
408
+ // Create a SSR bundle
409
+ noExternal = [
410
+ new RegExp(`^(?!(${[...builtinModules, ...serverModules].join('|')}))`)
411
+ ];
412
+ }
413
+ else {
414
+ rollupOptions = {
415
+ // input: [new URL('index.html', frameworkDir).pathname],
416
+ // output: {
417
+ // format: 'es'
418
+ // }
419
+ };
420
+ }
265
421
  const config = {
266
- root: frameworkDir.pathname,
422
+ root: ssr === 'fastify' ? appDir.pathname : frameworkDir.pathname,
267
423
  publicDir: publicDir.pathname,
424
+ envDir: appDir.pathname,
268
425
  vitrify: {
269
426
  productName,
270
427
  urls: {
271
- // @ts-ignore
272
428
  app: appDir,
273
429
  cli: cliDir,
274
430
  src: srcDir,
@@ -278,7 +434,7 @@ export const baseConfig = async ({ ssr, appDir, publicDir, command = 'build', mo
278
434
  },
279
435
  plugins,
280
436
  optimizeDeps: {
281
- exclude: ['vue']
437
+ exclude: ['vue', ...serverModules, ...builtinModules]
282
438
  },
283
439
  resolve: {
284
440
  // Dedupe uses require which breaks ESM SSR builds
@@ -289,52 +445,42 @@ export const baseConfig = async ({ ssr, appDir, publicDir, command = 'build', mo
289
445
  alias
290
446
  },
291
447
  build: {
292
- target: ssr === 'server' ? 'esnext' : 'modules',
293
- ssr: ssr === 'server' ? true : false,
448
+ target: ssr === 'server' || ssr === 'fastify' ? 'esnext' : 'modules',
449
+ ssr: ssr === 'server' || ssr === 'fastify' ? true : false,
294
450
  ssrManifest: ssr === 'client' || ssr === 'ssg',
295
- rollupOptions: ssr === 'server'
296
- ? {
297
- input: [
298
- new URL('ssr/entry-server.ts', frameworkDir).pathname,
299
- new URL('ssr/prerender.ts', frameworkDir).pathname,
300
- new URL('ssr/server.ts', frameworkDir).pathname
301
- ],
302
- output: {
303
- minifyInternalExports: false,
304
- entryFileNames: '[name].mjs',
305
- chunkFileNames: '[name].mjs',
306
- format: 'es',
307
- manualChunks: (id) => {
308
- if (id.includes('fastify-ssr-plugin')) {
309
- return 'fastify-ssr-plugin';
310
- }
311
- else if (id.includes('prerender')) {
312
- return 'prerender';
313
- }
314
- else if (id.includes('node_modules')) {
315
- return 'vendor';
316
- }
317
- }
318
- }
319
- }
320
- : {
321
- output: {
322
- format: 'es'
323
- }
324
- }
451
+ rollupOptions
452
+ // ssr === 'server'
453
+ // ? {
454
+ // input: [
455
+ // new URL('ssr/entry-server.ts', frameworkDir).pathname,
456
+ // new URL('ssr/prerender.ts', frameworkDir).pathname,
457
+ // new URL('ssr/server.ts', frameworkDir).pathname
458
+ // ],
459
+ // output: {
460
+ // minifyInternalExports: false,
461
+ // entryFileNames: '[name].mjs',
462
+ // chunkFileNames: '[name].mjs',
463
+ // format: 'es',
464
+ // manualChunks: (id) => {
465
+ // if (id.includes('vitrify/src/vite/')) {
466
+ // const name = id.split('/').at(-1)?.split('.').at(0)
467
+ // if (name && manualChunks.includes(name)) return name
468
+ // } else if (id.includes('node_modules')) {
469
+ // return 'vendor'
470
+ // }
471
+ // }
472
+ // }
473
+ // }
474
+ // : {
475
+ // output: {
476
+ // format: 'es'
477
+ // }
478
+ // }
325
479
  },
326
- // css: {
327
- // preprocessorOptions: {
328
- // sass: {
329
- // additionalData: sass ? [...sass].join('\n') : undefined
330
- // }
331
- // }
332
- // },
333
480
  ssr: {
334
481
  // Create a SSR bundle
335
- noExternal: [
336
- new RegExp(`^(?!.*(${[...builtinModules, ...serverModules].join('|')}))`)
337
- ]
482
+ external,
483
+ noExternal
338
484
  },
339
485
  define: {
340
486
  __BASE_URL__: `'/'`