vitrify 0.3.0 → 0.5.1

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 (44) hide show
  1. package/README.md +2 -2
  2. package/dist/app-urls.js +1 -1
  3. package/dist/bin/build.js +9 -8
  4. package/dist/bin/cli.js +28 -6
  5. package/dist/bin/dev.js +73 -29
  6. package/dist/frameworks/vue/fastify-csr-plugin.js +38 -0
  7. package/dist/frameworks/vue/fastify-ssr-plugin.js +83 -18
  8. package/dist/frameworks/vue/server.js +10 -5
  9. package/dist/helpers/collect-css-ssr.js +61 -0
  10. package/dist/index.js +298 -77
  11. package/dist/plugins/quasar.js +30 -9
  12. package/dist/types/bin/build.d.ts +2 -2
  13. package/dist/types/bin/dev.d.ts +43 -4
  14. package/dist/types/frameworks/vue/fastify-csr-plugin.d.ts +17 -0
  15. package/dist/types/frameworks/vue/fastify-ssr-plugin.d.ts +6 -3
  16. package/dist/types/frameworks/vue/server.d.ts +10 -5
  17. package/dist/types/helpers/collect-css-ssr.d.ts +14 -0
  18. package/dist/types/helpers/routes.d.ts +1 -1
  19. package/dist/types/index.d.ts +4 -2
  20. package/dist/types/plugins/index.d.ts +1 -1
  21. package/dist/types/vitrify-config.d.ts +16 -5
  22. package/package.json +33 -32
  23. package/src/node/app-urls.ts +1 -1
  24. package/src/node/bin/build.ts +11 -10
  25. package/src/node/bin/cli.ts +35 -7
  26. package/src/node/bin/dev.ts +109 -38
  27. package/src/node/frameworks/vue/fastify-csr-plugin.ts +72 -0
  28. package/src/node/frameworks/vue/fastify-ssr-plugin.ts +99 -20
  29. package/src/node/frameworks/vue/server.ts +24 -9
  30. package/src/node/helpers/collect-css-ssr.ts +85 -0
  31. package/src/node/index.ts +338 -90
  32. package/src/node/plugins/index.ts +1 -1
  33. package/src/node/plugins/quasar.ts +40 -9
  34. package/src/node/vitrify-config.ts +20 -5
  35. package/src/vite/fastify/entry.ts +11 -0
  36. package/src/vite/fastify/server.ts +12 -0
  37. package/src/vite/vue/csr/app.ts +25 -0
  38. package/src/vite/vue/csr/fastify-csr-plugin.ts +3 -0
  39. package/src/vite/vue/csr/server.ts +8 -0
  40. package/src/vite/vue/index.html +1 -0
  41. package/src/vite/vue/main.ts +0 -1
  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/server.ts +23 -14
@@ -1,14 +1,17 @@
1
1
  import type { FastifyPluginCallback, FastifyRequest, FastifyReply } from 'fastify';
2
- import type { ViteDevServer } from 'vite';
3
2
  import type { OnRenderedHook } from '../../vitrify-config.js';
3
+ import type { ViteDevServer } from 'vite';
4
4
  export interface FastifySsrOptions {
5
5
  baseUrl?: string;
6
6
  provide?: (req: FastifyRequest, res: FastifyReply) => Promise<Record<string, unknown>>;
7
+ vitrifyDir?: URL;
7
8
  vite?: ViteDevServer;
8
- cliDir?: URL;
9
9
  appDir?: URL;
10
+ publicDir?: URL;
10
11
  productName?: string;
11
- onRenderedHooks?: OnRenderedHook[];
12
+ onRendered?: OnRenderedHook[];
13
+ mode?: string;
12
14
  }
13
15
  declare const fastifySsrPlugin: FastifyPluginCallback<FastifySsrOptions>;
14
16
  export { fastifySsrPlugin };
17
+ export declare type FastifySsrPlugin = typeof fastifySsrPlugin;
@@ -1,9 +1,14 @@
1
1
  /// <reference types="node" />
2
2
  import type { FastifyInstance } from 'fastify';
3
- import type { OnRenderedHook } from '../../vitrify-config.js';
4
- export declare const createApp: ({ setup, appDir, baseUrl, onRenderedHooks }: {
5
- setup: (fastify: FastifyInstance) => any;
3
+ import type { OnRenderedHook, OnSetupFile } from '../../vitrify-config.js';
4
+ import type { FastifyCsrPlugin } from './fastify-csr-plugin.js';
5
+ import type { FastifySsrPlugin } from './fastify-ssr-plugin.js';
6
+ export declare const createApp: ({ onSetup, appDir, baseUrl, onRendered, fastifyPlugin, vitrifyDir, mode }: {
7
+ onSetup: OnSetupFile[];
6
8
  appDir: URL;
7
9
  baseUrl?: string | undefined;
8
- onRenderedHooks?: OnRenderedHook[] | undefined;
9
- }) => FastifyInstance<import("http").Server, import("http").IncomingMessage, import("http").ServerResponse, import("fastify").FastifyLoggerInstance> & PromiseLike<FastifyInstance<import("http").Server, import("http").IncomingMessage, import("http").ServerResponse, import("fastify").FastifyLoggerInstance>>;
10
+ onRendered?: OnRenderedHook[] | undefined;
11
+ fastifyPlugin: FastifySsrPlugin | FastifyCsrPlugin;
12
+ vitrifyDir?: URL | undefined;
13
+ mode: string;
14
+ }) => FastifyInstance<import("http").Server, import("http").IncomingMessage, import("http").ServerResponse, pino.Logger, import("fastify").FastifyTypeProviderDefault> & PromiseLike<FastifyInstance<import("http").Server, import("http").IncomingMessage, import("http").ServerResponse, pino.Logger, import("fastify").FastifyTypeProviderDefault>>;
@@ -0,0 +1,14 @@
1
+ import type { ViteDevServer, ModuleNode } from 'vite';
2
+ /**
3
+ * Collect SSR CSS for Vite
4
+ */
5
+ export declare const componentsModules: (components: string[], vite: ViteDevServer) => Set<ModuleNode>;
6
+ export declare const collectCss: ({ mods, styles, checkedComponents }: {
7
+ mods: Set<ModuleNode>;
8
+ styles?: Map<string, string> | undefined;
9
+ checkedComponents?: Set<unknown> | undefined;
10
+ }) => string;
11
+ /**
12
+ * Client listener to detect updated modules through HMR, and remove the initial styled attached to the head
13
+ */
14
+ export declare const removeCssHotReloaded: () => void;
@@ -1,2 +1,2 @@
1
1
  import type { RouteRecordRaw } from 'vue-router';
2
- export declare const routesToPaths: (routes?: RouteRecordRaw[] | undefined) => string[];
2
+ export declare const routesToPaths: (routes?: RouteRecordRaw[]) => string[];
@@ -3,13 +3,15 @@ import type { BootFunction, VitrifyConfig } from './vitrify-config.js';
3
3
  import type { VitrifyContext } from './bin/run.js';
4
4
  import type { VitrifyPlugin } from './plugins/index.js';
5
5
  export declare const VIRTUAL_MODULES: string[];
6
- export declare const baseConfig: ({ ssr, appDir, publicDir, command, mode, framework, pwa }: {
7
- ssr?: "server" | "client" | "ssg" | undefined;
6
+ export declare const baseConfig: ({ ssr, appDir, publicDir, base, command, mode, framework, pwa }: {
7
+ ssr?: "server" | "client" | "ssg" | "fastify" | undefined;
8
8
  appDir?: URL | undefined;
9
9
  publicDir?: URL | undefined;
10
+ base?: string | undefined;
10
11
  command?: "build" | "dev" | "test" | undefined;
11
12
  mode?: "production" | "development" | undefined;
12
13
  framework?: "vue" | undefined;
13
14
  pwa?: boolean | undefined;
14
15
  }) => Promise<InlineConfig>;
16
+ export declare const vitrifyDir: URL;
15
17
  export type { VitrifyConfig, VitrifyPlugin, VitrifyContext, BootFunction };
@@ -1,6 +1,6 @@
1
1
  import type { Plugin } from 'vite';
2
2
  export declare type VitrifyPlugin = ({ ssr, mode, command }: {
3
- ssr?: 'server' | 'client' | 'ssg' | false;
3
+ ssr?: 'server' | 'client' | 'ssg' | 'fastify' | false;
4
4
  pwa?: boolean;
5
5
  mode?: 'production' | 'development';
6
6
  command?: 'build' | 'dev' | 'test';
@@ -1,5 +1,4 @@
1
- import type { FastifyInstance } from 'fastify';
2
- import type { UserConfig } from 'vite';
1
+ import type { Alias, UserConfig } from 'vite';
3
2
  import type { QuasarConf } from './plugins/quasar.js';
4
3
  import type { ComponentInternalInstance } from '@vue/runtime-core';
5
4
  export declare type BootFunction = ({ app, ssrContext, staticImports }: {
@@ -10,13 +9,13 @@ export declare type BootFunction = ({ app, ssrContext, staticImports }: {
10
9
  export declare type OnBootHook = ({ app, ssrContext, staticImports }: {
11
10
  app: any;
12
11
  ssrContext: Record<string, unknown>;
13
- staticImports: Record<string, any>;
12
+ staticImports?: Record<string, any>;
14
13
  }) => Promise<void> | void;
15
14
  export declare type OnMountedHook = (instance: ComponentInternalInstance) => Promise<void> | void;
16
15
  export declare type StaticImports = Record<string, string[]>;
17
16
  export declare type SsrFunction = (html: string, ssrContext: Record<string, any>) => string;
18
17
  export declare type OnRenderedHook = (html: string, ssrContext: Record<string, any>) => string;
19
- export declare type OnSetupHook = (fastify: FastifyInstance) => any;
18
+ export declare type OnSetupFile = URL;
20
19
  export interface VitrifyConfig extends UserConfig {
21
20
  vitrify?: {
22
21
  /**
@@ -31,7 +30,7 @@ export interface VitrifyConfig extends UserConfig {
31
30
  /**
32
31
  * setup() is called directly after instantiating fastify. Use it to register your own plugins, routes etc.
33
32
  */
34
- onSetup?: OnSetupHook[];
33
+ onSetup?: OnSetupFile[];
35
34
  /**
36
35
  * Functions which run in the onMounted hook of the app
37
36
  */
@@ -66,6 +65,18 @@ export interface VitrifyConfig extends UserConfig {
66
65
  cwd?: URL;
67
66
  packages?: Record<string, URL>;
68
67
  };
68
+ /**
69
+ * SSR specific configuration
70
+ */
71
+ ssr?: {
72
+ serverModules?: string[];
73
+ };
74
+ /**
75
+ * Development only configuration
76
+ */
77
+ dev?: {
78
+ alias?: Alias[];
79
+ };
69
80
  };
70
81
  quasar?: QuasarConf;
71
82
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vitrify",
3
- "version": "0.3.0",
3
+ "version": "0.5.1",
4
4
  "license": "MIT",
5
5
  "author": "Stefan van Herwijnen",
6
6
  "description": "Pre-configured Vite CLI for your framework",
@@ -49,53 +49,54 @@
49
49
  "homepage": "https://github.com/simsustech/vitrify/tree/main/#readme",
50
50
  "scripts": {
51
51
  "build": "tsc",
52
- "test": "echo \"Error: no test specified\" && exit 0"
52
+ "test": "vitest test/"
53
53
  },
54
54
  "dependencies": {
55
- "@quasar/extras": "^1.13.5",
56
- "@vitejs/plugin-vue": "^2.3.1",
57
- "@vue/compiler-sfc": "^3.2.33",
58
- "@vue/server-renderer": "^3.2.33",
59
- "builtin-modules": "^3.2.0",
55
+ "@fastify/middie": "^8.0.0",
56
+ "@fastify/static": "^6.4.0",
57
+ "@quasar/extras": "^1.14.0",
58
+ "@vitejs/plugin-vue": "^3.0.0-alpha.1",
59
+ "builtin-modules": "^3.3.0",
60
60
  "cac": "^6.7.12",
61
61
  "chalk": "^5.0.1",
62
62
  "cross-env": "^7.0.3",
63
- "fastify": "^3.28.0",
64
- "fastify-static": "^4.6.1",
65
- "glob": "^8.0.1",
66
- "happy-dom": "^2.55.0",
67
- "import-meta-resolve": "^1.1.1",
63
+ "esbuild": "^0.14.43",
64
+ "fastify": "^4.0.0",
65
+ "glob": "^8.0.3",
66
+ "happy-dom": "^5.2.0",
68
67
  "local-pkg": "^0.4.1",
69
- "magic-string": "^0.26.1",
68
+ "magic-string": "^0.26.2",
70
69
  "merge-deep": "^3.0.3",
71
- "middie": "^6.0.0",
72
70
  "readline": "^1.3.0",
73
- "sass": "1.50.0",
74
- "unplugin-vue-components": "^0.19.3",
75
- "vite": "^2.9.5",
76
- "vitest": "^0.9.3"
71
+ "sass": "1.52.3",
72
+ "ts-node": "^10.8.1",
73
+ "unplugin-vue-components": "^0.19.6",
74
+ "vite": "^3.0.0-beta.0",
75
+ "vitest": "^0.14.1"
77
76
  },
78
77
  "devDependencies": {
78
+ "@types/connect": "^3.4.35",
79
79
  "@types/glob": "^7.2.0",
80
80
  "@types/merge-deep": "^3.0.0",
81
- "@types/node": "^17.0.24",
81
+ "@types/node": "^17.0.41",
82
82
  "@types/ws": "^8.5.3",
83
- "@vue/runtime-core": "^3.2.33",
84
- "quasar": "^2.6.6",
85
- "rollup": "^2.70.1",
86
- "typescript": "^4.6.3",
87
- "vite": "^2.9.5",
88
- "vue": "^3.2.33",
89
- "vue-router": "^4.0.14"
83
+ "@vue/runtime-core": "^3.2.37",
84
+ "import-meta-resolve": "^2.0.3",
85
+ "quasar": "^2.7.1",
86
+ "rollup": "^2.75.6",
87
+ "typescript": "^4.7.3",
88
+ "vite": "^3.0.0-alpha.11",
89
+ "vue": "^3.2.37",
90
+ "vue-router": "^4.0.15"
90
91
  },
91
92
  "peerDependencies": {
92
- "fastify": "^3.28.0",
93
+ "@fastify/static": "^6.4.0",
94
+ "fastify": "^4.0.0",
93
95
  "fastify-plugin": "^3.0.1",
94
- "fastify-sensible": "^3.1.2",
95
- "fastify-static": "^4.6.1",
96
- "quasar": "^2.6.6",
97
- "vue": "^3.2.33",
98
- "vue-router": "^4.0.14"
96
+ "quasar": "^2.7.1",
97
+ "vue": "^3.2.37",
98
+ "vue-router": "^4.0.15",
99
+ "import-meta-resolve": "^2.0.3"
99
100
  },
100
101
  "publishConfig": {
101
102
  "access": "public",
@@ -17,7 +17,7 @@ export const getCwd = () => new URL(`file://${process.cwd()}/`)
17
17
 
18
18
  export const parsePath = (path: string, basePath: URL) => {
19
19
  if (path) {
20
- if (path.slice(-1) !== '/') path += '/'
20
+ if (!path.includes('.') && path.slice(-1) !== '/') path += '/'
21
21
  if (path.startsWith('.')) {
22
22
  return new URL(path, basePath)
23
23
  } else if (path) {
@@ -3,9 +3,9 @@ import { baseConfig } from '../index.js'
3
3
  import { build as viteBuild } from 'vite'
4
4
 
5
5
  export async function build(opts: {
6
- ssr?: 'client' | 'server' | 'ssg'
6
+ ssr?: 'client' | 'server' | 'ssg' | 'fastify'
7
7
  base?: string
8
- outDir?: string
8
+ outDir: string
9
9
  appDir?: URL
10
10
  publicDir?: URL
11
11
  }) {
@@ -14,7 +14,8 @@ export async function build(opts: {
14
14
  mode: 'production',
15
15
  ssr: opts?.ssr,
16
16
  appDir: opts.appDir,
17
- publicDir: opts.publicDir
17
+ publicDir: opts.publicDir,
18
+ base: opts.base
18
19
  })
19
20
 
20
21
  config.build = {
@@ -24,16 +25,16 @@ export async function build(opts: {
24
25
  emptyOutDir: !!opts.outDir
25
26
  }
26
27
 
27
- if (opts.base) {
28
- config.define = {
29
- ...config.define,
30
- __BASE_URL__: `'${opts.base}'`
31
- }
32
- }
28
+ // if (opts.base) {
29
+ // config.define = {
30
+ // ...config.define,
31
+ // __BASE_URL__: `'${opts.base}'`
32
+ // }
33
+ // }
33
34
 
34
35
  return viteBuild({
35
36
  configFile: false,
36
- base: opts.base,
37
+ // base: opts.base,
37
38
  // logLevel: 'silent',
38
39
  ...config
39
40
  })
@@ -2,7 +2,13 @@
2
2
  import cac from 'cac'
3
3
  import { getAppDir, parsePath } from '../app-urls.js'
4
4
  import { printHttpServerUrls } from '../helpers/logger.js'
5
- import type { ViteDevServer } from 'vite'
5
+ import type {
6
+ ConfigEnv,
7
+ ResolvedConfig,
8
+ UserConfig,
9
+ UserConfigExport,
10
+ ViteDevServer
11
+ } from 'vite'
6
12
  import type { Server } from 'net'
7
13
 
8
14
  const cli = cac('vitrify')
@@ -42,7 +48,14 @@ cli
42
48
  case 'csr':
43
49
  await build({
44
50
  ...args,
45
- outDir: new URL('spa/', baseOutDir).pathname
51
+ outDir: new URL('csr/', baseOutDir).pathname
52
+ })
53
+ break
54
+ case 'fastify':
55
+ await build({
56
+ ssr: 'fastify',
57
+ ...args,
58
+ outDir: new URL('server/', baseOutDir).pathname
46
59
  })
47
60
  break
48
61
  case 'ssr':
@@ -96,26 +109,41 @@ cli
96
109
  { default: '127.0.0.1' }
97
110
  )
98
111
  .option('--appDir [appDir]', 'Application directory')
112
+ .option('--app [app]', 'Fastify app instance path')
99
113
  .option('--publicDir [publicDir]', 'Public directory')
100
114
  .action(async (options) => {
101
115
  let server: Server
102
- let vite: ViteDevServer
116
+ let config: ResolvedConfig
103
117
  if (options.host === true) {
104
118
  options.host = '0.0.0.0'
105
119
  }
106
120
  const { createServer } = await import('./dev.js')
107
121
  const cwd = (await import('../app-urls.js')).getCwd()
122
+ let app
123
+ const appPath = parsePath(options.app, cwd)?.pathname
124
+ if (appPath) {
125
+ app = await import(appPath)
126
+ }
127
+
108
128
  switch (options.mode) {
109
129
  case 'ssr':
110
- ;({ server, vite } = await createServer({
111
- mode: 'ssr',
130
+ ;({ server, config } = await createServer({
131
+ ssr: 'ssr',
132
+ host: options.host,
133
+ appDir: parsePath(options.appDir, cwd),
134
+ publicDir: parsePath(options.publicDir, cwd)
135
+ }))
136
+ break
137
+ case 'fastify':
138
+ ;({ server, config } = await createServer({
139
+ ssr: 'fastify',
112
140
  host: options.host,
113
141
  appDir: parsePath(options.appDir, cwd),
114
142
  publicDir: parsePath(options.publicDir, cwd)
115
143
  }))
116
144
  break
117
145
  default:
118
- ;({ server, vite } = await createServer({
146
+ ;({ server, config } = await createServer({
119
147
  host: options.host,
120
148
  appDir: parsePath(options.appDir, cwd),
121
149
  publicDir: parsePath(options.publicDir, cwd)
@@ -123,7 +151,7 @@ cli
123
151
  break
124
152
  }
125
153
  console.log('Dev server running at:')
126
- printHttpServerUrls(server, vite.config)
154
+ printHttpServerUrls(server, config)
127
155
  })
128
156
 
129
157
  cli.command('test').action(async (options) => {
@@ -1,56 +1,74 @@
1
- import type { ViteDevServer, LogLevel } from 'vite'
1
+ import type { LogLevel, InlineConfig } from 'vite'
2
+ import { ViteDevServer, mergeConfig } from 'vite'
2
3
  import { searchForWorkspaceRoot } from 'vite'
3
4
  import { baseConfig } from '../index.js'
4
5
  import type { Server } from 'net'
5
6
  import type { FastifyInstance } from 'fastify/types/instance'
6
7
  import fastify from 'fastify'
7
- import { readFileSync } from 'fs'
8
+ import { fastifySsrPlugin } from '../frameworks/vue/fastify-ssr-plugin.js'
9
+ import type { ServerOptions } from 'https'
8
10
 
9
- export async function createServer({
11
+ export async function createVitrifyDevServer({
10
12
  port = 3000,
11
13
  logLevel = 'info',
12
- mode = 'csr',
14
+ // mode = 'csr',
15
+ ssr,
13
16
  framework = 'vue',
14
17
  host,
15
18
  appDir,
16
- publicDir
19
+ publicDir,
20
+ base
17
21
  }: {
18
22
  port?: number
19
23
  logLevel?: LogLevel
20
- mode?: 'csr' | 'ssr'
24
+ // mode?: 'csr' | 'ssr' | 'fastify'
25
+ ssr?: 'ssr' | 'fastify'
21
26
  framework?: 'vue'
22
27
  host?: string
23
28
  appDir?: URL
24
29
  publicDir?: URL
30
+ base?: string
25
31
  }) {
26
- const { getAppDir, getCliDir, getCwd } = await import('../app-urls.js')
27
- const cwd = getCwd()
28
- const cliDir = getCliDir()
29
- if (!appDir) appDir = getAppDir()
30
- const { fastifySsrPlugin } = await import(
31
- `../frameworks/${framework}/fastify-ssr-plugin.js`
32
+ const { getAppDir, getCliDir, getCliViteDir, getCwd } = await import(
33
+ '../app-urls.js'
32
34
  )
33
35
 
34
- /**
35
- * @type {import('vite').ViteDevServer}
36
- */
37
- const config = await baseConfig({
38
- ssr: mode === 'ssr' ? 'server' : undefined,
36
+ const cliDir = getCliDir()
37
+
38
+ if (!appDir) appDir = getAppDir()
39
+ let config: InlineConfig = {}
40
+ let ssrMode: 'server' | 'fastify' | undefined
41
+ if (ssr === 'ssr') ssrMode = 'server'
42
+ if (ssr === 'fastify') ssrMode = 'fastify'
43
+ config = await baseConfig({
44
+ framework,
45
+ ssr: ssrMode,
39
46
  command: 'dev',
40
47
  mode: 'development',
41
48
  appDir,
42
- publicDir
49
+ publicDir,
50
+ base
43
51
  })
52
+
44
53
  config.logLevel = logLevel
54
+
55
+ console.log(searchForWorkspaceRoot(appDir.pathname))
45
56
  config.server = {
57
+ https: config.server?.https,
58
+ hmr: {
59
+ protocol: config.server?.https ? 'wss' : 'ws',
60
+ port: 24678
61
+ },
46
62
  port,
47
- middlewareMode: mode === 'ssr' ? 'ssr' : undefined,
63
+ // middlewareMode: mode === 'ssr' ? 'ssr' : undefined,
64
+ middlewareMode: ssr ? 'ssr' : false,
48
65
  fs: {
66
+ strict: false, // https://github.com/vitejs/vite/issues/8175
49
67
  allow: [
50
68
  searchForWorkspaceRoot(process.cwd()),
51
69
  searchForWorkspaceRoot(appDir.pathname),
52
- searchForWorkspaceRoot(cliDir.pathname)
53
- // appDir.pathname,
70
+ searchForWorkspaceRoot(cliDir.pathname),
71
+ appDir.pathname
54
72
  ]
55
73
  },
56
74
  watch: {
@@ -61,34 +79,87 @@ export async function createServer({
61
79
  },
62
80
  host
63
81
  }
64
- const vite = await (
82
+ const vitrifyDevServer = await (
65
83
  await import('vite')
66
84
  ).createServer({
67
85
  configFile: false,
68
86
  ...config
69
87
  })
70
- const { productName = 'Product name' } = JSON.parse(
71
- readFileSync(new URL('package.json', appDir).pathname, {
72
- encoding: 'utf-8'
73
- })
88
+
89
+ return vitrifyDevServer
90
+ }
91
+
92
+ export async function createServer({
93
+ port = 3000,
94
+ logLevel = 'info',
95
+ // mode = 'csr',
96
+ ssr,
97
+ framework = 'vue',
98
+ host,
99
+ appDir,
100
+ publicDir
101
+ }: {
102
+ port?: number
103
+ logLevel?: LogLevel
104
+ // mode?: 'csr' | 'ssr' | 'fastify'
105
+ ssr?: 'ssr' | 'fastify'
106
+ framework?: 'vue'
107
+ host?: string
108
+ appDir?: URL
109
+ publicDir?: URL
110
+ }) {
111
+ const { getAppDir, getCliDir, getCliViteDir, getCwd } = await import(
112
+ '../app-urls.js'
74
113
  )
75
114
 
76
- let app: ViteDevServer | FastifyInstance
115
+ appDir = appDir || getAppDir()
116
+ const cliDir = getCliDir()
117
+
118
+ const vite = await createVitrifyDevServer({
119
+ port,
120
+ logLevel,
121
+ ssr,
122
+ framework,
123
+ host,
124
+ appDir,
125
+ publicDir
126
+ })
127
+
128
+ let setup
77
129
  let server: Server
78
- if (mode === 'ssr') {
79
- console.log('SSR mode')
80
- app = fastify()
81
- await app.register(fastifySsrPlugin, {
82
- appDir,
83
- cliDir,
84
- vite,
85
- productName
86
- })
87
130
 
88
- await app.listen(port || 3000, host)
131
+ console.log(`Development mode: ${ssr ? ssr : 'csr'}`)
132
+ if (ssr) {
133
+ const entryUrl =
134
+ ssr === 'fastify'
135
+ ? new URL('src/vite/fastify/entry.ts', cliDir).pathname
136
+ : new URL(`src/vite/${framework}/ssr/entry-server.ts`, cliDir).pathname
137
+
138
+ ;({ setup } = await vite.ssrLoadModule(entryUrl))
139
+
140
+ const app = fastify({
141
+ logger: true,
142
+ https: vite.config.server.https as ServerOptions
143
+ })
144
+ if (process.env) process.env.MODE = 'development'
145
+ if (setup) {
146
+ await setup({
147
+ fastify: app
148
+ })
149
+ }
150
+ if (ssr === 'ssr') {
151
+ await app.register(fastifySsrPlugin, {
152
+ appDir,
153
+ mode: 'development'
154
+ })
155
+ }
156
+ await app.listen({
157
+ port: Number(port || 3000),
158
+ host
159
+ })
89
160
  server = app.server
90
161
  } else {
91
162
  server = (await vite.listen()).httpServer as Server
92
163
  }
93
- return { server, vite }
164
+ return { server, config: vite.config }
94
165
  }
@@ -0,0 +1,72 @@
1
+ import type {
2
+ FastifyPluginCallback,
3
+ FastifyRequest,
4
+ FastifyReply
5
+ } from 'fastify'
6
+ import fastifyStatic from '@fastify/static'
7
+ import type { OnRenderedHook } from '../../vitrify-config.js'
8
+ import type { ViteDevServer } from 'vite'
9
+
10
+ export interface FastifySsrOptions {
11
+ baseUrl?: string
12
+ provide?: (
13
+ req: FastifyRequest,
14
+ res: FastifyReply
15
+ ) => Promise<Record<string, unknown>>
16
+ vitrifyDir?: URL
17
+ vite?: ViteDevServer
18
+ // frameworkDir?: URL
19
+ appDir?: URL
20
+ publicDir?: URL
21
+ productName?: string
22
+ onRendered?: OnRenderedHook[]
23
+ mode?: string
24
+ }
25
+
26
+ const fastifyCsrPlugin: FastifyPluginCallback<FastifySsrOptions> = async (
27
+ fastify,
28
+ options,
29
+ done
30
+ ) => {
31
+ options.vitrifyDir =
32
+ options.vitrifyDir || (await import('vitrify')).vitrifyDir
33
+ const frameworkDir = new URL('src/vite/vue/', options.vitrifyDir)
34
+ options.baseUrl = options.baseUrl || '/'
35
+ options.mode = options.mode || process.env.MODE || import.meta.env.MODE
36
+ options.appDir = options.appDir || new URL('../../..', import.meta.url)
37
+
38
+ if (
39
+ options.baseUrl.charAt(options.baseUrl.length - 1) !== '/' ||
40
+ options.baseUrl.charAt(0) !== '/'
41
+ )
42
+ throw new Error('baseUrl should start and end with a /')
43
+ if (options.mode === 'development') {
44
+ options.appDir = options.appDir || new URL('../..', import.meta.url)
45
+
46
+ const { createVitrifyDevServer } = await import('vitrify/dev')
47
+ const vite = await createVitrifyDevServer({
48
+ appDir: options.appDir,
49
+ framework: 'vue',
50
+ base: options.baseUrl
51
+ })
52
+
53
+ console.log('Dev mode')
54
+ if (!('use' in fastify)) {
55
+ const middie = (await import('@fastify/middie')).default
56
+ await fastify.register(middie)
57
+ }
58
+ fastify.use(vite.middlewares)
59
+ } else {
60
+ options.appDir = options.appDir || new URL('../../..', import.meta.url)
61
+ fastify.register(fastifyStatic, {
62
+ root: new URL('./dist/csr', options.appDir).pathname,
63
+ wildcard: false,
64
+ index: false,
65
+ prefix: options.baseUrl
66
+ })
67
+ }
68
+ done()
69
+ }
70
+
71
+ export { fastifyCsrPlugin }
72
+ export type FastifyCsrPlugin = typeof fastifyCsrPlugin