Skip to content

Commit 1f53796

Browse files
authored
feat(hmr): reload when HTML file is created/deleted (#16288)
1 parent c2d0b88 commit 1f53796

File tree

3 files changed

+34
-45
lines changed

3 files changed

+34
-45
lines changed

packages/vite/src/node/server/hmr.ts

+15-39
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import colors from 'picocolors'
66
import type { CustomPayload, HMRPayload, Update } from 'types/hmrPayload'
77
import type { RollupError } from 'rollup'
88
import { CLIENT_DIR } from '../constants'
9-
import { createDebugger, normalizePath, unique } from '../utils'
9+
import { createDebugger, normalizePath } from '../utils'
1010
import type { InferCustomEventPayload, ViteDevServer } from '..'
1111
import { isCSSRequest } from '../plugins/css'
1212
import { getAffectedGlobModules } from '../plugins/importMetaGlob'
@@ -118,9 +118,9 @@ export function getShortName(file: string, root: string): string {
118118
}
119119

120120
export async function handleHMRUpdate(
121+
type: 'create' | 'delete' | 'update',
121122
file: string,
122123
server: ViteDevServer,
123-
configOnly: boolean,
124124
): Promise<void> {
125125
const { hot, config, moduleGraph } = server
126126
const shortFile = getShortName(file, config.root)
@@ -150,10 +150,6 @@ export async function handleHMRUpdate(
150150
return
151151
}
152152

153-
if (configOnly) {
154-
return
155-
}
156-
157153
debugHmr?.(`[file change] ${colors.dim(shortFile)}`)
158154

159155
// (dev only) the client itself cannot be hot updated.
@@ -166,22 +162,29 @@ export async function handleHMRUpdate(
166162
return
167163
}
168164

169-
const mods = moduleGraph.getModulesByFile(file)
165+
const mods = moduleGraph.getModulesByFile(file) || new Set()
166+
if (type === 'create' || type === 'delete') {
167+
for (const mod of getAffectedGlobModules(file, server)) {
168+
mods.add(mod)
169+
}
170+
}
170171

171172
// check if any plugin wants to perform custom HMR handling
172173
const timestamp = Date.now()
173174
const hmrContext: HmrContext = {
174175
file,
175176
timestamp,
176-
modules: mods ? [...mods] : [],
177+
modules: [...mods],
177178
read: () => readModifiedFile(file),
178179
server,
179180
}
180181

181-
for (const hook of config.getSortedPluginHooks('handleHotUpdate')) {
182-
const filteredModules = await hook(hmrContext)
183-
if (filteredModules) {
184-
hmrContext.modules = filteredModules
182+
if (type === 'update') {
183+
for (const hook of config.getSortedPluginHooks('handleHotUpdate')) {
184+
const filteredModules = await hook(hmrContext)
185+
if (filteredModules) {
186+
hmrContext.modules = filteredModules
187+
}
185188
}
186189
}
187190

@@ -315,33 +318,6 @@ function getSSRInvalidatedImporters(module: ModuleNode) {
315318
)
316319
}
317320

318-
export async function handleFileAddUnlink(
319-
file: string,
320-
server: ViteDevServer,
321-
isUnlink: boolean,
322-
): Promise<void> {
323-
const modules = [...(server.moduleGraph.getModulesByFile(file) || [])]
324-
325-
if (isUnlink) {
326-
for (const deletedMod of modules) {
327-
deletedMod.importedModules.forEach((importedMod) => {
328-
importedMod.importers.delete(deletedMod)
329-
})
330-
}
331-
}
332-
333-
modules.push(...getAffectedGlobModules(file, server))
334-
335-
if (modules.length > 0) {
336-
updateModules(
337-
getShortName(file, server.config.root),
338-
unique(modules),
339-
Date.now(),
340-
server,
341-
)
342-
}
343-
}
344-
345321
function areAllImportsAccepted(
346322
importedBindings: Set<string>,
347323
acceptedExports: Set<string>,

packages/vite/src/node/server/index.ts

+8-6
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,6 @@ import {
8282
createHMRBroadcaster,
8383
createServerHMRChannel,
8484
getShortName,
85-
handleFileAddUnlink,
8685
handleHMRUpdate,
8786
updateModules,
8887
} from './hmr'
@@ -728,10 +727,13 @@ export async function _createServer(
728727

729728
const publicFiles = await initPublicFilesPromise
730729

731-
const onHMRUpdate = async (file: string, configOnly: boolean) => {
730+
const onHMRUpdate = async (
731+
type: 'create' | 'delete' | 'update',
732+
file: string,
733+
) => {
732734
if (serverConfig.hmr !== false) {
733735
try {
734-
await handleHMRUpdate(file, server, configOnly)
736+
await handleHMRUpdate(type, file, server)
735737
} catch (err) {
736738
hot.send({
737739
type: 'error',
@@ -762,16 +764,16 @@ export async function _createServer(
762764
}
763765
}
764766
}
765-
await handleFileAddUnlink(file, server, isUnlink)
766-
await onHMRUpdate(file, true)
767+
if (isUnlink) moduleGraph.onFileDelete(file)
768+
await onHMRUpdate(isUnlink ? 'delete' : 'create', file)
767769
}
768770

769771
watcher.on('change', async (file) => {
770772
file = normalizePath(file)
771773
await container.watchChange(file, { event: 'update' })
772774
// invalidate module graph cache on file change
773775
moduleGraph.onFileChange(file)
774-
await onHMRUpdate(file, false)
776+
await onHMRUpdate('update', file)
775777
})
776778

777779
getFsUtils(config).initWatcher?.(watcher)

packages/vite/src/node/server/moduleGraph.ts

+11
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,17 @@ export class ModuleGraph {
148148
}
149149
}
150150

151+
onFileDelete(file: string): void {
152+
const mods = this.getModulesByFile(file)
153+
if (mods) {
154+
mods.forEach((mod) => {
155+
mod.importedModules.forEach((importedMod) => {
156+
importedMod.importers.delete(mod)
157+
})
158+
})
159+
}
160+
}
161+
151162
invalidateModule(
152163
mod: ModuleNode,
153164
seen: Set<ModuleNode> = new Set(),

0 commit comments

Comments
 (0)