vitrify 0.21.0 → 0.22.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.
@@ -1,9 +1,10 @@
1
1
  import type { Alias, UserConfig as ViteUserConfig, ViteDevServer } from 'vite';
2
- import type { QuasarConf } from './plugins/quasar.js';
3
2
  import type { ComponentInternalInstance } from '@vue/runtime-core';
4
3
  import type { FastifyInstance, FastifyServerOptions } from 'fastify';
5
4
  import type { VitePWAOptions } from 'vite-plugin-pwa';
5
+ import type { Options as unpluginVueComponentsOptions } from 'unplugin-vue-components';
6
6
  import type { UserConfig as UnoCSSUserConfig } from '@unocss/core';
7
+ import { VitrifyPlugin } from './plugins/index.js';
7
8
  export type BootFunction = ({ app, ssrContext, staticImports }: {
8
9
  app: any;
9
10
  ssrContext: Record<string, unknown>;
@@ -25,6 +26,10 @@ export type OnSetupFile = URL;
25
26
  export interface VitrifyConfig extends ViteUserConfig {
26
27
  vitrify?: {
27
28
  lang?: string;
29
+ /**
30
+ * Vitrify plugins
31
+ */
32
+ plugins?: VitrifyPluginConfig[];
28
33
  /**
29
34
  * Global CSS imports
30
35
  */
@@ -97,8 +102,11 @@ export interface VitrifyConfig extends ViteUserConfig {
97
102
  * UnoCSS Configuration
98
103
  */
99
104
  unocss?: UnoCSSUserConfig;
105
+ /**
106
+ * unplugin-vue-components configuration
107
+ */
108
+ unpluginVueComponents?: unpluginVueComponentsOptions;
100
109
  };
101
- quasar?: QuasarConf;
102
110
  }
103
111
  export type VitrifyCommands = 'build' | 'dev' | 'test';
104
112
  export type VitrifyModes = 'production' | 'development';
@@ -108,4 +116,9 @@ export type VitrifyConfigAsync = ({ mode, command }: {
108
116
  mode: VitrifyModes;
109
117
  command: VitrifyCommands;
110
118
  }) => Promise<VitrifyConfig>;
119
+ type VitrifyPluginConfig = {
120
+ plugin: VitrifyPlugin<any>;
121
+ options: any;
122
+ };
111
123
  export declare const defineConfig: (config: VitrifyConfig) => VitrifyConfig;
124
+ export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vitrify",
3
- "version": "0.21.0",
3
+ "version": "0.22.0",
4
4
  "license": "MIT",
5
5
  "author": "Stefan van Herwijnen",
6
6
  "description": "Vite as your Full Stack development tool",
@@ -30,9 +30,9 @@
30
30
  "./client": {
31
31
  "types": "./client.d.ts"
32
32
  },
33
- "./unocss/quasar/styles": {
34
- "types": "./dist/types/plugins/quasar/unocss/styles/index.d.ts",
35
- "import": "./dist/plugins/quasar/unocss/styles/index.js"
33
+ "./plugins": {
34
+ "types": "./dist/types/plugins/index.d.ts",
35
+ "import": "./dist/plugins/index.js"
36
36
  }
37
37
  },
38
38
  "engines": {
@@ -49,6 +49,7 @@
49
49
  "homepage": "https://github.com/simsustech/vitrify/tree/main/#readme",
50
50
  "dependencies": {
51
51
  "@fastify/middie": "^9.0.3",
52
+ "@fastify/one-line-logger": "^2.0.2",
52
53
  "@fastify/static": "^8.1.1",
53
54
  "@unocss/core": "^66.0.0",
54
55
  "@unocss/preset-uno": "^66.0.0",
@@ -49,8 +49,6 @@ export async function createVitrifyDevServer({
49
49
  '../app-urls.js'
50
50
  )
51
51
 
52
- const cliDir = getCliDir()
53
-
54
52
  if (!appDir) appDir = getAppDir()
55
53
  let config: InlineConfig = {}
56
54
  let ssrMode: 'server' | 'fastify' | undefined
@@ -66,52 +64,32 @@ export async function createVitrifyDevServer({
66
64
  base
67
65
  })
68
66
 
69
- config.logLevel = logLevel
70
-
71
- config.define = {
72
- ...config.define,
73
- __HOST__: `'${host}'`
74
- }
75
-
76
67
  const wsPort = await getFirstOpenPort(24678)
77
68
  if (config.server?.https) {
78
69
  exitLogs.push(
79
70
  `[warning] HTTPS mode enabled. Visit https://{hostname}:${wsPort} to enable a security exception for HMR.`
80
71
  )
81
72
  }
82
- config.server = {
83
- https: config.server?.https,
84
- hmr: {
85
- protocol: config.server?.https ? 'wss' : 'ws',
86
- port: wsPort
87
- },
88
- port,
89
- // middlewareMode: mode === 'ssr' ? 'ssr' : undefined,
90
- middlewareMode: ssr ? true : false,
91
- fs: {
92
- strict: false, // https://github.com/vitejs/vite/issues/8175
93
- allow: [
94
- searchForWorkspaceRoot(process.cwd()),
95
- searchForWorkspaceRoot(fileURLToPath(appDir)),
96
- searchForWorkspaceRoot(fileURLToPath(cliDir)),
97
- fileURLToPath(appDir)
98
- ]
99
- },
100
- watch: {
101
- // During tests we edit the files too fast and sometimes chokidar
102
- // misses change events, so enforce polling for consistency
103
- usePolling: true,
104
- interval: 100
105
- },
106
- host
107
- }
108
- if (ssr) config.appType = 'custom'
109
73
 
110
74
  const vitrifyDevServer = await (
111
75
  await import('vite')
112
76
  ).createServer({
113
77
  configFile: false,
114
- ...config
78
+ ...config,
79
+ logLevel,
80
+ define: {
81
+ ...config.define,
82
+ __HOST__: `'${host}'`
83
+ },
84
+ server: {
85
+ ...config.server,
86
+ host,
87
+ port,
88
+ hmr: {
89
+ protocol: config.server?.https ? 'wss' : 'ws',
90
+ port: wsPort
91
+ }
92
+ }
115
93
  })
116
94
 
117
95
  return vitrifyDevServer
@@ -170,9 +148,17 @@ export async function createServer({
170
148
  ? fileURLToPath(new URL('src/vite/fastify/entry.ts', cliDir))
171
149
  : fileURLToPath(new URL(`src/vite/${framework}/ssr/app.ts`, cliDir))
172
150
 
173
- ;({ setup, onRendered, vitrifyConfig } = await vite.ssrLoadModule(entryUrl))
151
+ const environment = vite.environments.ssr
152
+ ;({ setup, onRendered, vitrifyConfig } =
153
+ // @ts-expect-error missing types
154
+ await environment.runner.import(entryUrl))
155
+ // console.log(module)
156
+ // ;({ setup, onRendered, vitrifyConfig } = await vite.ssrLoadModule(entryUrl))
174
157
  app = fastify({
175
158
  logger: {
159
+ transport: {
160
+ target: '@fastify/one-line-logger'
161
+ },
176
162
  level: process.env.DEBUG
177
163
  ? 'debug'
178
164
  : process.env.PINO_LOG_LEVEL || 'info'
@@ -79,7 +79,10 @@ const fastifySsrPlugin: FastifyPluginAsync<FastifySsrOptions> = async (
79
79
  const entryUrl = fileURLToPath(
80
80
  new URL('ssr/entry-server.ts', frameworkDir)
81
81
  )
82
- const render = (await vite!.ssrLoadModule(entryUrl)).render
82
+ const environment = vite.environments.ssr
83
+ // @ts-expect-error missing type
84
+ const { render } = await environment.runner.import(entryUrl)
85
+ // const render = (await vite!.ssrLoadModule(entryUrl)).render
83
86
  let manifest
84
87
  // TODO: https://github.com/vitejs/vite/issues/2282
85
88
  try {
@@ -23,6 +23,9 @@ export const createApp = ({
23
23
  }) => {
24
24
  const app = fastify({
25
25
  logger: {
26
+ transport: {
27
+ target: '@fastify/one-line-logger'
28
+ },
26
29
  level: process.env.DEBUG ? 'debug' : process.env.PINO_LOG_LEVEL || 'info'
27
30
  }
28
31
  })
package/src/node/index.ts CHANGED
@@ -1,5 +1,10 @@
1
1
  import vuePlugin from '@vitejs/plugin-vue'
2
- import type { Alias, InlineConfig, UserConfig as ViteUserConfig } from 'vite'
2
+ import type {
3
+ Alias,
4
+ InlineConfig,
5
+ Plugin,
6
+ UserConfig as ViteUserConfig
7
+ } from 'vite'
3
8
  import { findDepPkgJsonPath } from 'vitefu'
4
9
  import { mergeConfig } from 'vite'
5
10
  import { build } from 'esbuild'
@@ -29,10 +34,10 @@ import type { VitrifyPlugin } from './plugins/index.js'
29
34
  import { resolve } from './app-urls.js'
30
35
  import type { ManualChunksOption, RollupOptions } from 'rollup'
31
36
  import { addOrReplaceTitle, appendToBody } from './helpers/utils.js'
32
- import type { ComponentResolver } from 'unplugin-vue-components'
33
37
  import Components from 'unplugin-vue-components/vite'
34
38
  import { VitePWA } from 'vite-plugin-pwa'
35
39
  import UnoCSS from 'unocss/vite'
40
+ import { searchForWorkspaceRoot } from 'vite'
36
41
 
37
42
  const internalServerModules = [
38
43
  'util',
@@ -50,21 +55,6 @@ const internalServerModules = [
50
55
  'abort-controller'
51
56
  ]
52
57
 
53
- const configPluginMap: Record<string, () => Promise<VitrifyPlugin>> = {
54
- quasar: () =>
55
- import('./plugins/quasar.js').then((module) => module.QuasarPlugin)
56
- }
57
-
58
- const configResolverMap: Record<
59
- string,
60
- () => Promise<ComponentResolver | ComponentResolver[]>
61
- > = {
62
- quasar: () =>
63
- import('unplugin-vue-components/resolvers').then((module) =>
64
- module.QuasarResolver()
65
- )
66
- }
67
-
68
58
  const manualChunkNames = [
69
59
  'prerender',
70
60
  'fastify-ssr-plugin',
@@ -103,31 +93,6 @@ const manualChunksFn = (manualChunkList?: string[]): ManualChunksOption => {
103
93
  }
104
94
  }
105
95
 
106
- // const manualChunks: ManualChunksOption = (
107
- // id: string,
108
- // manualChunkList?: string[]
109
- // ) => {
110
- // const matchedModule = Object.entries(moduleChunks).find(
111
- // ([chunkName, moduleNames]) =>
112
- // moduleNames.some((moduleName) => id.includes(moduleName + '/'))
113
- // )
114
- // if (id.includes('vitrify/src/')) {
115
- // const name = id.split('/').at(-1)?.split('.').at(0)
116
- // if (name && manualChunkNames.includes(name)) return name
117
- // } else if (
118
- // VIRTUAL_MODULES.some((virtualModule) => id.includes(virtualModule))
119
- // ) {
120
- // return VIRTUAL_MODULES.find((name) => id.includes(name))
121
- // } else if (manualChunkList?.some((file) => id.includes(file))) {
122
- // return manualChunkList.find((file) => id.includes(file))
123
- // } else if (id.includes('node_modules')) {
124
- // if (matchedModule) {
125
- // return matchedModule[0]
126
- // }
127
- // return 'vendor'
128
- // }
129
- // }
130
-
131
96
  export const VIRTUAL_MODULES = [
132
97
  'virtual:vitrify-hooks',
133
98
  'virtual:static-imports',
@@ -241,7 +206,6 @@ export const baseConfig = async ({
241
206
  fs.writeFileSync(configPath + '.js', bundledConfig.code)
242
207
 
243
208
  rawVitrifyConfig = (await import('file://' + configPath + '.js')).default
244
- // vitrifyConfig = (await import(configPath + '.js')).default
245
209
  fs.unlinkSync(configPath + '.js')
246
210
  } else {
247
211
  rawVitrifyConfig = (
@@ -258,9 +222,11 @@ export const baseConfig = async ({
258
222
  throw e
259
223
  }
260
224
 
261
- const localPackages = ['vue', 'vue-router', '@vue/server-renderer']
262
- // const localPackages: string[] = []
263
- const cliPackages = []
225
+ const localPackages = []
226
+ if (framework === 'vue')
227
+ localPackages.push('vue', 'vue-router', '@vue/server-renderer')
228
+
229
+ const cliPackages: string[] = []
264
230
  const packageUrls: Record<string, URL> =
265
231
  vitrifyConfig.vitrify?.urls?.packages || {}
266
232
  await (async () => {
@@ -269,14 +235,6 @@ export const baseConfig = async ({
269
235
  if (pkgDir) packageUrls![val] = new URL(`file://${pkgDir}`)
270
236
  }
271
237
  })()
272
-
273
- // await (async () => {
274
- // for (const val of cliPackages)
275
- // packageUrls[val] = getPkgJsonDir(
276
- // new URL(await resolve(val, cliDir!.href))
277
- // )
278
- // })()
279
-
280
238
  if (!productName) {
281
239
  try {
282
240
  ;({ productName } = JSON.parse(
@@ -294,20 +252,28 @@ export const baseConfig = async ({
294
252
 
295
253
  const isPwa = !!vitrifyConfig.vitrify?.pwa || false
296
254
 
297
- const frameworkPlugins = []
298
- const resolvers = []
299
- for (const framework of Object.keys(configPluginMap)) {
300
- if (Object.keys(vitrifyConfig).includes(framework)) {
301
- const plugin = await configPluginMap[framework]()
302
- const resolver = await configResolverMap[framework]()
303
-
304
- frameworkPlugins.push(
305
- await plugin({
306
- ssr,
307
- pwa: isPwa
308
- })
309
- )
310
- resolvers.push(resolver)
255
+ const frameworkPlugins: Plugin[] = []
256
+ if (framework === 'vue') {
257
+ frameworkPlugins.push(vuePlugin())
258
+ }
259
+
260
+ const vitrifyPlugins: Plugin[] = []
261
+ if (vitrifyConfig.vitrify?.plugins) {
262
+ for (const vitrifyPluginConfig of vitrifyConfig.vitrify.plugins) {
263
+ const vitrifyPlugin = await vitrifyPluginConfig.plugin({
264
+ ssr,
265
+ pwa: isPwa,
266
+ options: vitrifyPluginConfig.options
267
+ })
268
+ if ('plugin' in vitrifyPlugin) {
269
+ vitrifyPlugins.push(vitrifyPlugin.plugin)
270
+ } else if ('plugins' in vitrifyPlugin) {
271
+ vitrifyPlugins.push(...vitrifyPlugin.plugins)
272
+ }
273
+
274
+ if (vitrifyPlugin.config) {
275
+ vitrifyConfig = mergeConfig(vitrifyConfig, vitrifyPlugin.config)
276
+ }
311
277
  }
312
278
  }
313
279
 
@@ -378,14 +344,13 @@ export const baseConfig = async ({
378
344
  /<style lang="sass">(.*?)<\/style>/,
379
345
  '<style lang="sass">' + sass + '</style>'
380
346
  )
381
- // code = code.replace(/<\/style>/, sass + '</style>')
382
347
  }
383
348
 
384
349
  return code
385
350
  }
386
351
  },
387
- vuePlugin(),
388
352
  ...frameworkPlugins,
353
+ ...vitrifyPlugins,
389
354
  {
390
355
  name: 'vitrify-setup',
391
356
  enforce: 'post',
@@ -445,10 +410,6 @@ export const baseConfig = async ({
445
410
  return `import ${varName} from '${
446
411
  new URL(url, appDir).pathname
447
412
  }'; onSetup.push(${varName})`
448
-
449
- // return `import ${varName} from '${fileURLToPath(
450
- // url
451
- // )}'; onSetup.push(${varName})`
452
413
  })
453
414
  .join('\n')}`
454
415
  } else if (id === 'virtual:static-imports') {
@@ -465,11 +426,7 @@ export const baseConfig = async ({
465
426
  ),
466
427
  ...globalSass.map((sass) => `@import '${sass}'`)
467
428
  ].join('\n')
468
- }
469
- // else if (id === 'vitrify.css') {
470
- // return `${globalCss.map((css) => `@import '${css}'`).join('\n')}`
471
- // }
472
- else if (id === 'virtual:vitrify-config') {
429
+ } else if (id === 'virtual:vitrify-config') {
473
430
  return `export default ${JSON.stringify(vitrifyConfig)}`
474
431
  }
475
432
  return null
@@ -499,14 +456,14 @@ export const baseConfig = async ({
499
456
  }
500
457
  },
501
458
  Components({
459
+ ...vitrifyConfig.vitrify?.unpluginVueComponents,
502
460
  exclude: [
503
461
  new RegExp(
504
462
  `[\\/]node_modules[\\/].*[\\/]!(${serverModules.join('|')})`
505
463
  ),
506
464
  /[\\/]\.git[\\/]/,
507
465
  /[\\/]\.nuxt[\\/]/
508
- ],
509
- resolvers
466
+ ]
510
467
  }),
511
468
  UnoCSS({
512
469
  ...vitrifyConfig.vitrify?.unocss,
@@ -559,32 +516,13 @@ export const baseConfig = async ({
559
516
  } else {
560
517
  entryScript = `<script type="module" src="${entry}"></script>`
561
518
  }
562
- // html = html.replace('<!--entry-script-->', entryScript)
563
519
  html = appendToBody(entryScript, html)
564
520
  if (productName) html = addOrReplaceTitle(productName, html)
565
- // html = html.replace('<!--product-name-->', productName)
566
521
  return html
567
522
  }
568
523
  }
569
524
  })
570
525
 
571
- // plugins.unshift({
572
- // name: 'product-name',
573
- // enforce: 'post',
574
- // config: (config: VitrifyConfig, env) => {
575
- // if (config.vitrify?.productName)
576
- // productName = config.vitrify?.productName
577
- // return
578
- // },
579
- // transformIndexHtml: {
580
- // enforce: 'post',
581
- // transform: (html) => {
582
- // html = html.replace('<!--product-name-->', productName)
583
- // return html
584
- // }
585
- // }
586
- // })
587
-
588
526
  if (debug) plugins.push(visualizer())
589
527
  }
590
528
 
@@ -599,19 +537,40 @@ export const baseConfig = async ({
599
537
  ]
600
538
 
601
539
  const vuePkgAliases: Alias[] = []
602
- for (const pkg of vueInternalPkgs) {
603
- const specifier = pkg.split('/').at(-1)
604
- const pkgJsonPath = await findDepPkgJsonPath(pkg, fileURLToPath(appDir!))
605
- if (pkgJsonPath)
606
- vuePkgAliases.push({
607
- find: pkg,
608
- replacement: fileURLToPath(
609
- new URL(
610
- `./dist/${specifier}.esm-bundler.js`,
611
- `file://${pkgJsonPath}` || ''
540
+ if (packageUrls['vue']) {
541
+ for (const pkg of vueInternalPkgs) {
542
+ const specifier = pkg.split('/').at(-1)
543
+ const pkgJsonPath = await findDepPkgJsonPath(pkg, fileURLToPath(appDir!))
544
+ if (pkgJsonPath)
545
+ vuePkgAliases.push({
546
+ find: pkg,
547
+ replacement: fileURLToPath(
548
+ new URL(
549
+ `./dist/${specifier}.esm-bundler.js`,
550
+ `file://${pkgJsonPath}` || ''
551
+ )
612
552
  )
613
- )
614
- })
553
+ })
554
+
555
+ vuePkgAliases.push(
556
+ {
557
+ find: new RegExp('^vue$'),
558
+ replacement: fileURLToPath(
559
+ new URL('./dist/vue.runtime.esm-bundler.js', packageUrls['vue'])
560
+ )
561
+ },
562
+ {
563
+ find: new RegExp('^vue-router$'),
564
+ replacement: fileURLToPath(
565
+ new URL(
566
+ './dist/vue-router.esm-bundler.js',
567
+ packageUrls['vue-router']
568
+ )
569
+ )
570
+ },
571
+ ...vuePkgAliases
572
+ )
573
+ }
615
574
  }
616
575
 
617
576
  const alias: Alias[] = [
@@ -619,21 +578,11 @@ export const baseConfig = async ({
619
578
  { find: 'app', replacement: fileURLToPath(appDir) },
620
579
  { find: 'cwd', replacement: fileURLToPath(cwd) },
621
580
  { find: 'boot', replacement: fileURLToPath(new URL('boot/', srcDir)) },
622
- { find: 'assets', replacement: fileURLToPath(new URL('assets/', srcDir)) },
623
- {
624
- find: new RegExp('^vue$'),
625
- replacement: fileURLToPath(
626
- new URL('./dist/vue.runtime.esm-bundler.js', packageUrls['vue'])
627
- )
628
- },
629
- {
630
- find: new RegExp('^vue-router$'),
631
- replacement: fileURLToPath(
632
- new URL('./dist/vue-router.esm-bundler.js', packageUrls['vue-router'])
633
- )
634
- },
635
- ...vuePkgAliases
581
+ { find: 'assets', replacement: fileURLToPath(new URL('assets/', srcDir)) }
636
582
  ]
583
+
584
+ if (framework === 'vue') alias.push(...vuePkgAliases)
585
+
637
586
  if (mode === 'development' && vitrifyConfig.vitrify?.dev?.alias)
638
587
  alias.push(...vitrifyConfig.vitrify.dev.alias)
639
588
 
@@ -704,6 +653,7 @@ export const baseConfig = async ({
704
653
 
705
654
  const config = {
706
655
  root: fileURLToPath(appDir),
656
+ appType: ssr ? 'custom' : 'spa',
707
657
  publicDir: fileURLToPath(publicDir),
708
658
  base,
709
659
  envDir: fileURLToPath(appDir),
@@ -740,6 +690,28 @@ export const baseConfig = async ({
740
690
  __HOST__: `'localhost'`,
741
691
  __BASE_URL__: `'${base}'`,
742
692
  __IS_PWA__: `${isPwa}`
693
+ },
694
+ // environments: {
695
+ // },
696
+ server: {
697
+ https: vitrifyConfig.server?.https,
698
+ // middlewareMode: mode === 'ssr' ? 'ssr' : undefined,
699
+ middlewareMode: ssr ? true : false,
700
+ fs: {
701
+ strict: false, // https://github.com/vitejs/vite/issues/8175
702
+ allow: [
703
+ searchForWorkspaceRoot(process.cwd()),
704
+ searchForWorkspaceRoot(fileURLToPath(appDir)),
705
+ searchForWorkspaceRoot(fileURLToPath(cliDir)),
706
+ fileURLToPath(appDir)
707
+ ]
708
+ },
709
+ watch: {
710
+ // During tests we edit the files too fast and sometimes chokidar
711
+ // misses change events, so enforce polling for consistency
712
+ usePolling: true,
713
+ interval: 100
714
+ }
743
715
  }
744
716
  } as VitrifyConfig
745
717
 
@@ -1,12 +1,28 @@
1
1
  import type { Plugin } from 'vite'
2
+ import { VitrifyConfig } from '../vitrify-config.js'
2
3
 
3
- export type VitrifyPlugin = ({
4
+ type VitrifyPluginReturnType =
5
+ | {
6
+ plugin: Plugin
7
+ config?: Partial<VitrifyConfig>
8
+ }
9
+ | {
10
+ plugins: Plugin[]
11
+ config?: Partial<VitrifyConfig>
12
+ }
13
+
14
+ export type VitrifyPlugin<Options> = ({
4
15
  ssr,
16
+ pwa,
5
17
  mode,
6
- command
18
+ command,
19
+ options
7
20
  }: {
8
21
  ssr?: 'server' | 'client' | 'ssg' | 'fastify' | false
9
22
  pwa?: boolean
10
23
  mode?: 'production' | 'development'
11
24
  command?: 'build' | 'dev' | 'test'
12
- }) => Promise<Plugin | Plugin[]> | Plugin | Plugin[]
25
+ options: Options
26
+ }) => Promise<VitrifyPluginReturnType> | VitrifyPluginReturnType
27
+
28
+ export * from './quasar/index.js'