Skip to content

Commit 7b6eb24

Browse files
fix: use client/server createHead (#442)
* fix: use client/server createHead * chore: fix lint * chore: tree-shake server code from client build * chore: use process.env.VITE_SSG * chore: remove temp folder * feat: use `import.meta.env.SSR` (#444) * feat: use `import.meta.env.SSR` * feat: use also `import.meta.env.SSR` instead `client` * chore: remove client arg. from `createApp` chore: add `vite-ssg` to `ssr.noExternal` in server build * chore: add back client argument to `createApp` * chore: apply suggestion I'll change also client spa Co-authored-by: Kevin Marrec <[email protected]> * chore: apply suggestion also to client spa module * fix(client)!: treeshake hydration (#445) --------- Co-authored-by: Kevin Marrec <[email protected]>
1 parent aaf807e commit 7b6eb24

File tree

3 files changed

+49
-41
lines changed

3 files changed

+49
-41
lines changed

src/client/index.ts

Lines changed: 19 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import type { VueHeadClient } from '@unhead/vue'
22
import type { Component } from 'vue'
33
import type { RouterOptions, ViteSSGClientOptions, ViteSSGContext } from '../types'
44
import { createHead } from '@unhead/vue/client'
5+
import { createHead as createSSRHead } from '@unhead/vue/server'
56
import { createApp as createClientApp, createSSRApp } from 'vue'
67
import { createMemoryHistory, createRouter, createWebHistory } from 'vue-router'
78
import { documentReady } from '../utils/document-ready'
@@ -14,33 +15,30 @@ export function ViteSSG(
1415
App: Component,
1516
routerOptions: RouterOptions,
1617
fn?: (context: ViteSSGContext<true>) => Promise<void> | void,
17-
options: ViteSSGClientOptions = {},
18+
options?: ViteSSGClientOptions,
1819
) {
1920
const {
2021
transformState,
2122
registerComponents = true,
2223
useHead = true,
2324
rootContainer = '#app',
24-
hydration = false,
25-
} = options
26-
const isClient = typeof window !== 'undefined'
25+
} = options ?? {}
2726

28-
async function createApp(client = false, routePath?: string) {
29-
const app = client && !hydration
30-
? createClientApp(App)
31-
: createSSRApp(App)
27+
async function createApp(_client = false, routePath?: string) {
28+
const app = import.meta.env.SSR || options?.hydration
29+
? createSSRApp(App)
30+
: createClientApp(App)
3231

3332
let head: VueHeadClient | undefined
3433

3534
if (useHead) {
36-
head = createHead()
37-
app.use(head)
35+
app.use(head = import.meta.env.SSR ? createSSRHead() : createHead())
3836
}
3937

4038
const router = createRouter({
41-
history: client
42-
? createWebHistory(routerOptions.base)
43-
: createMemoryHistory(routerOptions.base),
39+
history: import.meta.env.SSR
40+
? createMemoryHistory(routerOptions.base)
41+
: createWebHistory(routerOptions.base),
4442
...routerOptions,
4543
})
4644

@@ -50,16 +48,16 @@ export function ViteSSG(
5048
app.component('ClientOnly', ClientOnly)
5149

5250
const appRenderCallbacks: (() => void)[] = []
53-
const onSSRAppRendered = client
54-
? () => {}
55-
: (cb: () => void) => appRenderCallbacks.push(cb)
51+
const onSSRAppRendered = import.meta.env.SSR
52+
? (cb: () => void) => appRenderCallbacks.push(cb)
53+
: () => {}
5654
const triggerOnSSRAppRendered = () => {
5755
return Promise.all(appRenderCallbacks.map(cb => cb()))
5856
}
5957
const context: ViteSSGContext<true> = {
6058
app,
6159
head,
62-
isClient,
60+
isClient: !import.meta.env.SSR,
6361
router,
6462
routes,
6563
onSSRAppRendered,
@@ -69,7 +67,7 @@ export function ViteSSG(
6967
routePath,
7068
}
7169

72-
if (client) {
70+
if (!import.meta.env.SSR) {
7371
await documentReady()
7472
// @ts-expect-error global variable
7573
context.initialState = transformState?.(window.__INITIAL_STATE__ || {}) || deserializeState(window.__INITIAL_STATE__)
@@ -92,7 +90,7 @@ export function ViteSSG(
9290
next()
9391
})
9492

95-
if (!client) {
93+
if (!import.meta.env.SSR) {
9694
const route = context.routePath ?? '/'
9795
router.push(route)
9896

@@ -108,9 +106,9 @@ export function ViteSSG(
108106
} as ViteSSGContext<true>
109107
}
110108

111-
if (isClient) {
109+
if (!import.meta.env.SSR) {
112110
(async () => {
113-
const { app, router } = await createApp(true)
111+
const { app, router } = await createApp()
114112
// wait until page component is fetched before mounting
115113
await router.isReady()
116114
app.mount(rootContainer, true)

src/client/single-page.ts

Lines changed: 25 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import type { VueHeadClient } from '@unhead/vue'
22
import type { Component } from 'vue'
33
import type { ViteSSGClientOptions, ViteSSGContext } from '../types'
44
import { createHead } from '@unhead/vue/client'
5+
import { createHead as createSSRHead } from '@unhead/vue/server'
56
import { createApp as createClientApp, createSSRApp } from 'vue'
67
import { documentReady } from '../utils/document-ready'
78
import { deserializeState } from '../utils/state'
@@ -12,42 +13,49 @@ export * from '../types'
1213
export function ViteSSG(
1314
App: Component,
1415
fn?: (context: ViteSSGContext<false>) => Promise<void> | void,
15-
options: ViteSSGClientOptions = {},
16+
options?: ViteSSGClientOptions,
1617
) {
1718
const {
1819
transformState,
1920
registerComponents = true,
2021
useHead = true,
2122
rootContainer = '#app',
22-
hydration = false,
23-
} = options
24-
const isClient = typeof window !== 'undefined'
23+
} = options ?? {}
2524

26-
async function createApp(client = false) {
27-
const app = client && !hydration
28-
? createClientApp(App)
29-
: createSSRApp(App)
25+
async function createApp(_client = false) {
26+
const app = import.meta.env.SSR || options?.hydration
27+
? createSSRApp(App)
28+
: createClientApp(App)
3029

3130
let head: VueHeadClient | undefined
3231

3332
if (useHead) {
34-
head = createHead()
35-
app.use(head)
33+
app.use(head = import.meta.env.SSR ? createSSRHead() : createHead())
3634
}
3735

3836
const appRenderCallbacks: (() => void)[] = []
39-
const onSSRAppRendered = client
40-
? () => {}
41-
: (cb: () => void) => appRenderCallbacks.push(cb)
37+
const onSSRAppRendered = import.meta.env.SSR
38+
? (cb: () => void) => appRenderCallbacks.push(cb)
39+
: () => {}
4240
const triggerOnSSRAppRendered = () => {
4341
return Promise.all(appRenderCallbacks.map(cb => cb()))
4442
}
45-
const context = { app, head, isClient, router: undefined, routes: undefined, initialState: {}, onSSRAppRendered, triggerOnSSRAppRendered, transformState }
43+
const context = {
44+
app,
45+
head,
46+
isClient: !import.meta.env.SSR,
47+
router: undefined,
48+
routes: undefined,
49+
initialState: {},
50+
onSSRAppRendered,
51+
triggerOnSSRAppRendered,
52+
transformState,
53+
}
4654

4755
if (registerComponents)
4856
app.component('ClientOnly', ClientOnly)
4957

50-
if (client) {
58+
if (!import.meta.env.SSR) {
5159
await documentReady()
5260
// @ts-expect-error global variable
5361
context.initialState = transformState?.(window.__INITIAL_STATE__ || {}) || deserializeState(window.__INITIAL_STATE__)
@@ -64,9 +72,9 @@ export function ViteSSG(
6472
} as ViteSSGContext<false>
6573
}
6674

67-
if (isClient) {
75+
if (!import.meta.env.SSR) {
6876
(async () => {
69-
const { app } = await createApp(true)
77+
const { app } = await createApp()
7078
app.mount(rootContainer, true)
7179
})()
7280
}

src/node/build.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1+
/* eslint-disable no-console */
12
import type { InlineConfig, ResolvedConfig } from 'vite'
23
import type { VitePluginPWAAPI } from 'vite-plugin-pwa'
34
import type { RouteRecordRaw } from 'vue-router'
45
import type { SSRContext } from 'vue/server-renderer'
56
import type { ViteSSGContext, ViteSSGOptions } from '../types'
67
import { existsSync } from 'node:fs'
78
import fs from 'node:fs/promises'
8-
/* eslint-disable no-console */
99
import { createRequire } from 'node:module'
1010
import { dirname, isAbsolute, join, parse } from 'node:path'
1111
import process from 'node:process'
@@ -109,6 +109,9 @@ export async function build(ssgOptions: Partial<ViteSSGOptions> = {}, viteConfig
109109
},
110110
},
111111
mode: config.mode,
112+
ssr: {
113+
noExternal: ['vite-ssg'],
114+
},
112115
}))
113116

114117
const prefix = (format === 'esm' && process.platform === 'win32') ? 'file://' : ''
@@ -280,8 +283,7 @@ async function renderHTML({
280283
indexHTML: string
281284
appHTML: string
282285
initialState: any
283-
},
284-
) {
286+
}) {
285287
const stateScript = initialState
286288
? `\n<script>window.__INITIAL_STATE__=${initialState}</script>`
287289
: ''

0 commit comments

Comments
 (0)