vitrify 0.2.0 → 0.2.3

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.
@@ -0,0 +1,387 @@
1
+ import { readFileSync } from 'fs'
2
+ import type { Plugin } from 'vite'
3
+ import Components from 'unplugin-vue-components/vite'
4
+ // import { prepareQuasarConf } from './quasar-conf-file.js'
5
+ import type {
6
+ BootFunction,
7
+ OnMountedHook,
8
+ VitrifyConfig
9
+ } from '../vitrify-config.js'
10
+ // import { quasarDir as defaultQuasarDir } from '../app-urls.js'
11
+ // import { QuasarResolver } from '../resolver.js';
12
+ import { QuasarResolver } from 'unplugin-vue-components/resolvers'
13
+ import type { VitrifyPlugin } from './index.js'
14
+ import { getPkgJsonDir } from '../app-urls.js'
15
+ import { resolve } from 'import-meta-resolve'
16
+
17
+ export interface QuasarConf {
18
+ ctx: Record<string, any>
19
+ css: string[]
20
+ boot: string[]
21
+ framework: {
22
+ components?: string[]
23
+ directives?: string[]
24
+ plugins?: string[]
25
+ }
26
+ animations: string[]
27
+ extras: string[]
28
+ }
29
+
30
+ export const injectSsrContext = (
31
+ html: string,
32
+ ssrContext: Record<string, any>
33
+ ) =>
34
+ html
35
+ .replace(/(<html[^>]*)(>)/i, (found, start, end) => {
36
+ let matches
37
+
38
+ matches = found.match(/\sdir\s*=\s*['"]([^'"]*)['"]/i)
39
+ if (matches) {
40
+ start = start.replace(matches[0], '')
41
+ }
42
+
43
+ matches = found.match(/\slang\s*=\s*['"]([^'"]*)['"]/i)
44
+ if (matches) {
45
+ start = start.replace(matches[0], '')
46
+ }
47
+
48
+ return `${start} ${ssrContext._meta.htmlAttrs || ''} ${end}`
49
+ })
50
+ .replace(
51
+ /(<head[^>]*)(>)/i,
52
+ (_, start, end) => `${start}${end}${ssrContext._meta.headTags || ''}`
53
+ )
54
+ .replace(
55
+ /(<\/head>)/i,
56
+ (_, tag) =>
57
+ `${ssrContext._meta.resourceStyles || ''}${
58
+ ssrContext._meta.endingHeadTags || ''
59
+ }${tag}`
60
+ )
61
+ .replace(/(<body[^>]*)(>)/i, (found, start, end) => {
62
+ let classes = ssrContext._meta.bodyClasses || ''
63
+
64
+ const matches = found.match(/\sclass\s*=\s*['"]([^'"]*)['"]/i)
65
+
66
+ if (matches) {
67
+ if (matches[1].length > 0) {
68
+ classes += ` ${matches[1]}`
69
+ }
70
+ start = start.replace(matches[0], '')
71
+ }
72
+
73
+ return `${start} class="${classes.trim()}" ${
74
+ ssrContext._meta.bodyAttrs || ''
75
+ }${end}${ssrContext._meta.bodyTags || ''}`
76
+ })
77
+
78
+ // export interface Configuration {
79
+ // ssr?: 'server' | 'client' | 'ssg' | false
80
+ // }
81
+
82
+ export const QuasarPlugin: VitrifyPlugin = async ({
83
+ ssr = false,
84
+ pwa = false
85
+ }): Promise<Plugin[]> => {
86
+ // const extraPlugins: Plugin[] = []
87
+ // const ctx = {
88
+ // prod: process.env.MODE === 'production',
89
+ // dev: process.env.MODE === 'development',
90
+ // mode: {
91
+ // ssr: !!ssr,
92
+ // pwa: !!pwa
93
+ // }
94
+ // }
95
+
96
+ // let bootFilePaths: Record<string, any> = {}
97
+ // let components: string[] = []
98
+ let plugins: string[] = []
99
+ // let css: string[] = []
100
+ let extras: string[] = []
101
+ return [
102
+ // {
103
+ // name: 'legacy-support',
104
+ // enforce: 'pre',
105
+ // transform (code, id) {
106
+ // /**
107
+ // * ESM does not resolve an import to .default when there are multiple exports. The following is required to make the VuePlugin import of QCalendar work.
108
+ // */
109
+ // if (code.includes('app.use(VuePlugin)')) {
110
+ // code = code.replace(/app\.use\(VuePlugin\)/g, `app.use(VuePlugin.install ? VuePlugin : VuePlugin.default)`)
111
+ // }
112
+ // return code
113
+ // }
114
+ // },
115
+ Components({
116
+ resolvers: [QuasarResolver()]
117
+ }),
118
+ {
119
+ name: 'vite-plugin-quasar-setup',
120
+ enforce: 'pre',
121
+ config: async (config: VitrifyConfig, env): Promise<VitrifyConfig> => {
122
+ const { vitrify: { urls } = {}, quasar } = config
123
+
124
+ const globalCss = quasar?.extras.map(
125
+ (extra) => `@quasar/extras/${extra}/${extra}.css`
126
+ )
127
+
128
+ const localPackages = ['@quasar/extras', 'quasar']
129
+ await (async () => {
130
+ for (const val of localPackages)
131
+ urls!.packages![val] = getPkgJsonDir(
132
+ new URL(await resolve(val, urls!.app!.href))
133
+ )
134
+ })()
135
+
136
+ const onMountedHooks: OnMountedHook[] = [
137
+ async (instance) => {
138
+ // @ts-ignore
139
+ const {
140
+ proxy: { $q }
141
+ } = instance
142
+ $q.onSSRHydrated !== void 0 && $q.onSSRHydrated()
143
+ }
144
+ ]
145
+
146
+ const bootFunctions: BootFunction[] = [
147
+ async ({ app, ssrContext, staticImports }) => {
148
+ // @ts-ignore
149
+ // const quasarVuePlugin = (await import('quasar/vue-plugin')).default
150
+ // @ts-ignore
151
+ const quasarPlugins = await import('virtual:quasar-plugins')
152
+ // @ts-ignore
153
+ const directives = await import('quasar/src/directives.js')
154
+
155
+ app.use(
156
+ staticImports.Quasar,
157
+ {
158
+ plugins: quasarPlugins,
159
+ directives
160
+ },
161
+ ssrContext
162
+ )
163
+ }
164
+ ]
165
+
166
+ return {
167
+ vitrify: {
168
+ urls,
169
+ bootFunctions,
170
+ ssrFunctions: [injectSsrContext],
171
+ globalCss,
172
+ staticImports: {
173
+ quasar: ['Quasar']
174
+ },
175
+ hooks: {
176
+ onMounted: onMountedHooks
177
+ },
178
+ sass: {
179
+ additionalData: [`@import 'quasar/src/css/index.sass'`]
180
+ }
181
+ }
182
+ }
183
+ }
184
+ },
185
+ {
186
+ name: 'vite-plugin-quasar',
187
+ enforce: 'post',
188
+ // transformIndexHtml: {
189
+ // enforce: 'post',
190
+ // transform: (html) => {
191
+ // return html.replace(
192
+ // '<!--product-name-->',
193
+ // productName
194
+ // )
195
+ // }
196
+ // },
197
+ config: async (config: VitrifyConfig, env) => {
198
+ // let appDir: URL
199
+ // let cliDir: URL
200
+ // let cwd: URL
201
+ // let quasarDir: URL
202
+ // let quasarConf: QuasarConf | undefined
203
+
204
+ const { quasar: quasarConf, vitrify: { urls } = {} } = config
205
+
206
+ const quasarPkgJsonPath = new URL(
207
+ 'package.json',
208
+ urls?.packages?.quasar
209
+ ).pathname
210
+ const { version } = JSON.parse(
211
+ readFileSync(quasarPkgJsonPath, { encoding: 'utf-8' })
212
+ )
213
+
214
+ // if (quasarConf?.boot) {
215
+ // bootFilePaths = (quasarConf.boot as (Record<string, any> | string)[])
216
+ // .filter(entry => {
217
+ // if (typeof entry === 'object') return (entry.server && (ssr === 'server'))
218
+ // else if (entry !== '') return true
219
+ // })
220
+ // .map(entry => {
221
+ // if (typeof entry === 'string') return entry
222
+ // else if (typeof entry === 'object') return entry.path
223
+ // })
224
+ // .reduce((acc, entry) => {
225
+ // if (entry[0] === '~') {
226
+ // const split = entry.substring(1).split('/')
227
+ // const name = split[0].replace(/[|&;$%@"<>()+,]/g, "");
228
+ // acc[name] = {
229
+ // path: new URL(`node_modules/${entry.substring(1)}`, urls?.app).pathname
230
+ // }
231
+ // } else {
232
+ // const name = entry.split('.')[0]
233
+ // acc[name] = {
234
+ // path: `src/boot/${entry}`
235
+ // }
236
+ // }
237
+ // return acc
238
+ // }, {})
239
+ // }
240
+
241
+ /**
242
+ * All components should have been auto-imported
243
+ */
244
+ if (quasarConf?.framework?.plugins) {
245
+ if (!quasarConf.framework) quasarConf.framework = {}
246
+ quasarConf.framework.plugins = [
247
+ ...new Set(quasarConf.framework.plugins)
248
+ ]
249
+ plugins = quasarConf?.framework.plugins
250
+ }
251
+
252
+ // css = (quasarConf?.css || []).map((v => {
253
+ // if (v[0] === '~') {
254
+ // return v.slice(1)
255
+ // }
256
+ // return v
257
+ // })).map((v) => `@import '${v}'`)
258
+ extras = quasarConf?.extras || []
259
+
260
+ return {
261
+ resolve: {
262
+ alias: [
263
+ {
264
+ find: 'quasar/wrappers',
265
+ replacement: new URL('quasar-wrappers.ts', urls?.cli).pathname
266
+ },
267
+ {
268
+ find: 'quasar/vue-plugin',
269
+ replacement: new URL(
270
+ 'src/vue-plugin.js',
271
+ urls?.packages?.quasar
272
+ ).pathname
273
+ },
274
+ {
275
+ find: 'quasar/plugins',
276
+ replacement: new URL('src/plugins.js', urls?.packages?.quasar)
277
+ .pathname
278
+ },
279
+ {
280
+ find: 'quasar/components',
281
+ replacement: new URL(
282
+ 'src/components.js',
283
+ urls?.packages?.quasar
284
+ ).pathname
285
+ },
286
+ {
287
+ find: 'quasar/composables',
288
+ replacement: new URL(
289
+ 'src/composables.js',
290
+ urls?.packages?.quasar
291
+ ).pathname
292
+ },
293
+
294
+ {
295
+ find: 'quasar/directives',
296
+ replacement: new URL(
297
+ 'src/directives.js',
298
+ urls?.packages?.quasar
299
+ ).pathname
300
+ },
301
+ {
302
+ find: 'quasar/src',
303
+ replacement: new URL('src/', urls?.packages?.quasar).pathname
304
+ },
305
+ // ...extras.map(extra => ({
306
+ // find: `@quasar/extras/${extra}/${extra}.css`,
307
+ // replacement: new URL(`${extra}/${extra}.css`, urls?.packages?.['@quasar/extras']).pathname
308
+ // })
309
+ // ),
310
+ {
311
+ find: 'quasar',
312
+ replacement: new URL('src/', urls?.packages?.quasar).pathname
313
+ },
314
+ {
315
+ find: `@quasar/extras`,
316
+ replacement: new URL('.', urls?.packages?.['@quasar/extras'])
317
+ .pathname
318
+ }
319
+ // { find: new RegExp('^quasar$'), replacement: new URL('src/index.all.js', urls?.packages?.quasar).pathname },
320
+ // { find: new RegExp('^quasar$'), replacement: 'virtual:quasar' },
321
+ ]
322
+ },
323
+ define: {
324
+ __DEV__: process.env.NODE_ENV !== 'production' || true,
325
+ __QUASAR_VERSION__: `'${version}'`,
326
+ __QUASAR_SSR__: !!ssr,
327
+ __QUASAR_SSR_SERVER__: ssr === 'server',
328
+ __QUASAR_SSR_CLIENT__: ssr === 'client',
329
+ __QUASAR_SSR_PWA__: ssr === 'client' && pwa
330
+ },
331
+ // css: {
332
+ // preprocessorOptions: {
333
+ // sass: {
334
+ // additionalData: `@import 'quasar/src/css/index.sass'`
335
+ // // [
336
+ // // // ...extras.map(extra => `@import "@quasar/extras/${extra}/${extra}.css"`),
337
+ // // // ...extras.map(extra => `@import ${new URL(`${extra}/${extra}.css`, urls?.packages?.['@quasar/extras']).pathname}`) || [],
338
+ // // // config.css?.preprocessorOptions?.sass?.additionalData,
339
+ // // `@import 'quasar/src/css/index.sass'`
340
+ // // ].join('\n')
341
+ // }
342
+ // }
343
+ // },
344
+ ssr: {
345
+ noExternal: ['quasar']
346
+ }
347
+ }
348
+ }
349
+ },
350
+ {
351
+ name: 'quasar-virtual-modules',
352
+ enforce: 'post',
353
+ config: async (config, env) => ({
354
+ resolve: {
355
+ alias: [
356
+ { find: new RegExp('^quasar$'), replacement: 'virtual:quasar' }
357
+ ]
358
+ }
359
+ }),
360
+ resolveId(id) {
361
+ switch (id) {
362
+ case 'virtual:quasar-plugins':
363
+ return 'virtual:quasar-plugins'
364
+ case 'virtual:quasar':
365
+ return { id: 'virtual:quasar', moduleSideEffects: false }
366
+ default:
367
+ return
368
+ }
369
+ },
370
+ load(id) {
371
+ if (id === 'virtual:quasar-plugins') {
372
+ return `export { ${plugins.join(',')} } from 'quasar'`
373
+ } else if (id === 'virtual:quasar') {
374
+ return `export * from 'quasar/src/plugins.js';
375
+ export * from 'quasar/src/components.js';
376
+ export * from 'quasar/src/composables.js';
377
+ export * from 'quasar/src/directives.js';
378
+ export * from 'quasar/src/utils.js';
379
+ export { default as Quasar } from 'quasar/src/install-quasar.js'`
380
+ }
381
+ return null
382
+ }
383
+ }
384
+ ]
385
+ }
386
+
387
+ export default QuasarPlugin
@@ -0,0 +1,79 @@
1
+ import type { FastifyInstance } from 'fastify'
2
+ import type { UserConfig } from 'vite'
3
+ import type { QuasarConf } from './plugins/quasar.js'
4
+ import type { ComponentInternalInstance } from '@vue/runtime-core'
5
+
6
+ export type BootFunction = ({
7
+ app,
8
+ ssrContext,
9
+ staticImports
10
+ }: {
11
+ app: any
12
+ ssrContext: Record<string, unknown>
13
+ staticImports: Record<string, any>
14
+ }) => Promise<void> | void
15
+ export type OnMountedHook = (
16
+ instance: ComponentInternalInstance
17
+ ) => Promise<void> | void
18
+ export type StaticImports = Record<string, string[]>
19
+ export type SsrFunction = (
20
+ html: string,
21
+ ssrContext: Record<string, any>
22
+ ) => string
23
+
24
+ export interface VitrifyConfig extends UserConfig {
25
+ vitrify?: {
26
+ /**
27
+ * Global CSS imports
28
+ */
29
+ globalCss?: string[]
30
+ /**
31
+ * Functions which run after initializing the app
32
+ */
33
+ bootFunctions?: BootFunction[]
34
+ /**
35
+ * Functions which run on the server after rendering the app
36
+ */
37
+ ssrFunctions?: SsrFunction[]
38
+ /**
39
+ * Static imports in the app: packageName: [imports]
40
+ */
41
+ staticImports?: StaticImports
42
+ hooks?: {
43
+ /**
44
+ * Functions which run in the onMounted hook of the app
45
+ */
46
+ onMounted: OnMountedHook[]
47
+ }
48
+ /**
49
+ * Global SASS variables
50
+ */
51
+ sass?: {
52
+ variables?: Record<string, string>
53
+ additionalData?: string[]
54
+ }
55
+ fastify?: {
56
+ /**
57
+ * setup() is called directly after instantiating fastify. Use it to register your own plugins, routes etc.
58
+ */
59
+ setup: (fastify: FastifyInstance) => any
60
+ }
61
+ /**
62
+ * Product name of the application. Will be used for the HTML title tag
63
+ */
64
+ productName?: string
65
+ /**
66
+ * URL's for common dev paths and packages, automatically generated
67
+ */
68
+ urls?: {
69
+ app?: URL
70
+ cli?: URL
71
+ src?: URL
72
+ cwd?: URL
73
+ packages?: Record<string, URL>
74
+ }
75
+ }
76
+ quasar?: QuasarConf
77
+ }
78
+
79
+ export const defineConfig = (config: VitrifyConfig) => config
@@ -1,4 +1,4 @@
1
- import { fastifySsrPlugin } from '../../../node/vue/fastify-ssr-plugin.js'
1
+ import { fastifySsrPlugin } from '../../../node/frameworks/vue/fastify-ssr-plugin.js'
2
2
  import ssrFunctions from 'virtual:ssr-functions'
3
3
 
4
4
  export { fastifySsrPlugin, ssrFunctions }
@@ -1,4 +1,4 @@
1
- import { prerender } from '../../../node/vue/prerender.js'
1
+ import { prerender } from '../../../node/frameworks/vue/prerender.js'
2
2
  import ssrFunctions from 'virtual:ssr-functions'
3
3
 
4
4
  export { prerender, ssrFunctions }
@@ -1,15 +1,18 @@
1
- import { createApp } from '../../../node/vue/server.js'
2
- import { appDir } from '../../../node/app-urls.js'
1
+ import { createApp } from '../../../node/frameworks/vue/server.js'
2
+ import { getAppDir } from '../../../node/app-urls.js'
3
3
  import { setup } from 'virtual:fastify-setup'
4
+ import ssrFunctions from 'virtual:ssr-functions'
4
5
 
5
6
  // const appDir = getPkgJsonDir(import.meta.url)
6
7
  const getString = (str?: string) => str
7
8
  let baseUrl = getString(__BASE_URL__)
9
+ const appDir = getAppDir()
8
10
 
9
11
  const app = createApp({
10
12
  setup,
11
13
  appDir,
12
- baseUrl
14
+ baseUrl,
15
+ ssrFunctions
13
16
  })
14
17
 
15
18
  app.listen(process.env.PORT || 3000, process.env.HOST || '127.0.0.1')