Skip to content

Commit 646319c

Browse files
keydingsapphi-red
andauthored
fix: do not access document in /@vite/client when not defined (#16318)
Co-authored-by: sapphi-red <49056869+sapphi-red@users.noreply.github.com>
1 parent 445c4f2 commit 646319c

File tree

5 files changed

+82
-64
lines changed

5 files changed

+82
-64
lines changed

packages/vite/src/client/client.ts

+44-33
Original file line numberDiff line numberDiff line change
@@ -102,9 +102,11 @@ function setupWebSocket(
102102

103103
notifyListeners('vite:ws:disconnect', { webSocket: socket })
104104

105-
console.log(`[vite] server connection lost. polling for restart...`)
106-
await waitForSuccessfulPing(protocol, hostAndPath)
107-
location.reload()
105+
if (hasDocument) {
106+
console.log(`[vite] server connection lost. polling for restart...`)
107+
await waitForSuccessfulPing(protocol, hostAndPath)
108+
location.reload()
109+
}
108110
})
109111

110112
return socket
@@ -182,16 +184,20 @@ async function handleMessage(payload: HMRPayload) {
182184
break
183185
case 'update':
184186
notifyListeners('vite:beforeUpdate', payload)
185-
// if this is the first update and there's already an error overlay, it
186-
// means the page opened with existing server compile error and the whole
187-
// module script failed to load (since one of the nested imports is 500).
188-
// in this case a normal update won't work and a full reload is needed.
189-
if (isFirstUpdate && hasErrorOverlay()) {
190-
window.location.reload()
191-
return
192-
} else {
193-
clearErrorOverlay()
194-
isFirstUpdate = false
187+
if (hasDocument) {
188+
// if this is the first update and there's already an error overlay, it
189+
// means the page opened with existing server compile error and the whole
190+
// module script failed to load (since one of the nested imports is 500).
191+
// in this case a normal update won't work and a full reload is needed.
192+
if (isFirstUpdate && hasErrorOverlay()) {
193+
window.location.reload()
194+
return
195+
} else {
196+
if (enableOverlay) {
197+
clearErrorOverlay()
198+
}
199+
isFirstUpdate = false
200+
}
195201
}
196202
await Promise.all(
197203
payload.updates.map(async (update): Promise<void> => {
@@ -249,21 +255,23 @@ async function handleMessage(payload: HMRPayload) {
249255
}
250256
case 'full-reload':
251257
notifyListeners('vite:beforeFullReload', payload)
252-
if (payload.path && payload.path.endsWith('.html')) {
253-
// if html file is edited, only reload the page if the browser is
254-
// currently on that page.
255-
const pagePath = decodeURI(location.pathname)
256-
const payloadPath = base + payload.path.slice(1)
257-
if (
258-
pagePath === payloadPath ||
259-
payload.path === '/index.html' ||
260-
(pagePath.endsWith('/') && pagePath + 'index.html' === payloadPath)
261-
) {
258+
if (hasDocument) {
259+
if (payload.path && payload.path.endsWith('.html')) {
260+
// if html file is edited, only reload the page if the browser is
261+
// currently on that page.
262+
const pagePath = decodeURI(location.pathname)
263+
const payloadPath = base + payload.path.slice(1)
264+
if (
265+
pagePath === payloadPath ||
266+
payload.path === '/index.html' ||
267+
(pagePath.endsWith('/') && pagePath + 'index.html' === payloadPath)
268+
) {
269+
pageReload()
270+
}
271+
return
272+
} else {
262273
pageReload()
263274
}
264-
return
265-
} else {
266-
pageReload()
267275
}
268276
break
269277
case 'prune':
@@ -272,13 +280,15 @@ async function handleMessage(payload: HMRPayload) {
272280
break
273281
case 'error': {
274282
notifyListeners('vite:error', payload)
275-
const err = payload.err
276-
if (enableOverlay) {
277-
createErrorOverlay(err)
278-
} else {
279-
console.error(
280-
`[vite] Internal Server Error\n${err.message}\n${err.stack}`,
281-
)
283+
if (hasDocument) {
284+
const err = payload.err
285+
if (enableOverlay) {
286+
createErrorOverlay(err)
287+
} else {
288+
console.error(
289+
`[vite] Internal Server Error\n${err.message}\n${err.stack}`,
290+
)
291+
}
282292
}
283293
break
284294
}
@@ -298,6 +308,7 @@ function notifyListeners(event: string, data: any): void {
298308
}
299309

300310
const enableOverlay = __HMR_ENABLE_OVERLAY__
311+
const hasDocument = 'document' in globalThis
301312

302313
function createErrorOverlay(err: ErrorPayload['err']) {
303314
clearErrorOverlay()

packages/vite/src/client/overlay.ts

+31-28
Original file line numberDiff line numberDiff line change
@@ -165,39 +165,41 @@ kbd {
165165
`
166166

167167
// Error Template
168-
const template = h(
169-
'div',
170-
{ class: 'backdrop', part: 'backdrop' },
168+
let template: HTMLElement
169+
const createTemplate = () =>
171170
h(
172171
'div',
173-
{ class: 'window', part: 'window' },
174-
h(
175-
'pre',
176-
{ class: 'message', part: 'message' },
177-
h('span', { class: 'plugin', part: 'plugin' }),
178-
h('span', { class: 'message-body', part: 'message-body' }),
179-
),
180-
h('pre', { class: 'file', part: 'file' }),
181-
h('pre', { class: 'frame', part: 'frame' }),
182-
h('pre', { class: 'stack', part: 'stack' }),
172+
{ class: 'backdrop', part: 'backdrop' },
183173
h(
184174
'div',
185-
{ class: 'tip', part: 'tip' },
186-
'Click outside, press ',
187-
h('kbd', {}, 'Esc'),
188-
' key, or fix the code to dismiss.',
189-
h('br'),
190-
'You can also disable this overlay by setting ',
191-
h('code', { part: 'config-option-name' }, 'server.hmr.overlay'),
192-
' to ',
193-
h('code', { part: 'config-option-value' }, 'false'),
194-
' in ',
195-
h('code', { part: 'config-file-name' }, hmrConfigName),
196-
'.',
175+
{ class: 'window', part: 'window' },
176+
h(
177+
'pre',
178+
{ class: 'message', part: 'message' },
179+
h('span', { class: 'plugin', part: 'plugin' }),
180+
h('span', { class: 'message-body', part: 'message-body' }),
181+
),
182+
h('pre', { class: 'file', part: 'file' }),
183+
h('pre', { class: 'frame', part: 'frame' }),
184+
h('pre', { class: 'stack', part: 'stack' }),
185+
h(
186+
'div',
187+
{ class: 'tip', part: 'tip' },
188+
'Click outside, press ',
189+
h('kbd', {}, 'Esc'),
190+
' key, or fix the code to dismiss.',
191+
h('br'),
192+
'You can also disable this overlay by setting ',
193+
h('code', { part: 'config-option-name' }, 'server.hmr.overlay'),
194+
' to ',
195+
h('code', { part: 'config-option-value' }, 'false'),
196+
' in ',
197+
h('code', { part: 'config-file-name' }, hmrConfigName),
198+
'.',
199+
),
197200
),
198-
),
199-
h('style', {}, templateStyle),
200-
)
201+
h('style', {}, templateStyle),
202+
)
201203

202204
const fileRE = /(?:[a-zA-Z]:\\|\/).*?:\d+:\d+/g
203205
const codeframeRE = /^(?:>?\s*\d+\s+\|.*|\s+\|\s*\^.*)\r?\n/gm
@@ -213,6 +215,7 @@ export class ErrorOverlay extends HTMLElement {
213215
super()
214216
this.root = this.attachShadow({ mode: 'open' })
215217

218+
template ??= createTemplate()
216219
this.root.appendChild(template)
217220

218221
codeframeRE.lastIndex = 0

playground/worker/__tests__/es/worker-es.spec.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,7 @@ test('emit chunk', async () => {
200200
)
201201
await untilUpdated(
202202
() => page.textContent('.emit-chunk-dynamic-import-worker'),
203-
'"A string/es/"',
203+
'"A stringmodule1/es/"',
204204
true,
205205
)
206206
})

playground/worker/__tests__/relative-base/worker-relative-base.spec.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ test.runIf(isBuild)('emit chunk', async () => {
141141
)
142142
await untilUpdated(
143143
() => page.textContent('.emit-chunk-dynamic-import-worker'),
144-
'"A string./"',
144+
'"A stringmodule1./"',
145145
true,
146146
)
147147
})

playground/worker/emit-chunk-dynamic-import-worker.js

+5-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
1+
import module1Url from './modules/module1.js?url'
2+
13
import('./modules/module0').then((module) => {
2-
self.postMessage(module.default + import.meta.env.BASE_URL)
4+
import(/* @vite-ignore */ module1Url).then((module1) => {
5+
self.postMessage(module.default + module1.msg1 + import.meta.env.BASE_URL)
6+
})
37
})
48

59
// for sourcemap

0 commit comments

Comments
 (0)