diff --git a/packages/vite/src/node/server/hmr.ts b/packages/vite/src/node/server/hmr.ts index 86bf9961bf9a72..cf28591db056de 100644 --- a/packages/vite/src/node/server/hmr.ts +++ b/packages/vite/src/node/server/hmr.ts @@ -6,7 +6,7 @@ import colors from 'picocolors' import type { CustomPayload, HMRPayload, Update } from 'types/hmrPayload' import type { RollupError } from 'rollup' import { CLIENT_DIR } from '../constants' -import { createDebugger, normalizePath, unique } from '../utils' +import { createDebugger, normalizePath } from '../utils' import type { InferCustomEventPayload, ViteDevServer } from '..' import { isCSSRequest } from '../plugins/css' import { getAffectedGlobModules } from '../plugins/importMetaGlob' @@ -118,9 +118,9 @@ export function getShortName(file: string, root: string): string { } export async function handleHMRUpdate( + type: 'create' | 'delete' | 'update', file: string, server: ViteDevServer, - configOnly: boolean, ): Promise { const { hot, config, moduleGraph } = server const shortFile = getShortName(file, config.root) @@ -150,10 +150,6 @@ export async function handleHMRUpdate( return } - if (configOnly) { - return - } - debugHmr?.(`[file change] ${colors.dim(shortFile)}`) // (dev only) the client itself cannot be hot updated. @@ -166,22 +162,29 @@ export async function handleHMRUpdate( return } - const mods = moduleGraph.getModulesByFile(file) + const mods = moduleGraph.getModulesByFile(file) || new Set() + if (type === 'create' || type === 'delete') { + for (const mod of getAffectedGlobModules(file, server)) { + mods.add(mod) + } + } // check if any plugin wants to perform custom HMR handling const timestamp = Date.now() const hmrContext: HmrContext = { file, timestamp, - modules: mods ? [...mods] : [], + modules: [...mods], read: () => readModifiedFile(file), server, } - for (const hook of config.getSortedPluginHooks('handleHotUpdate')) { - const filteredModules = await hook(hmrContext) - if (filteredModules) { - hmrContext.modules = filteredModules + if (type === 'update') { + for (const hook of config.getSortedPluginHooks('handleHotUpdate')) { + const filteredModules = await hook(hmrContext) + if (filteredModules) { + hmrContext.modules = filteredModules + } } } @@ -315,33 +318,6 @@ function getSSRInvalidatedImporters(module: ModuleNode) { ) } -export async function handleFileAddUnlink( - file: string, - server: ViteDevServer, - isUnlink: boolean, -): Promise { - const modules = [...(server.moduleGraph.getModulesByFile(file) || [])] - - if (isUnlink) { - for (const deletedMod of modules) { - deletedMod.importedModules.forEach((importedMod) => { - importedMod.importers.delete(deletedMod) - }) - } - } - - modules.push(...getAffectedGlobModules(file, server)) - - if (modules.length > 0) { - updateModules( - getShortName(file, server.config.root), - unique(modules), - Date.now(), - server, - ) - } -} - function areAllImportsAccepted( importedBindings: Set, acceptedExports: Set, diff --git a/packages/vite/src/node/server/index.ts b/packages/vite/src/node/server/index.ts index 134a781b9550d9..5cd066ffc736d4 100644 --- a/packages/vite/src/node/server/index.ts +++ b/packages/vite/src/node/server/index.ts @@ -82,7 +82,6 @@ import { createHMRBroadcaster, createServerHMRChannel, getShortName, - handleFileAddUnlink, handleHMRUpdate, updateModules, } from './hmr' @@ -728,10 +727,13 @@ export async function _createServer( const publicFiles = await initPublicFilesPromise - const onHMRUpdate = async (file: string, configOnly: boolean) => { + const onHMRUpdate = async ( + type: 'create' | 'delete' | 'update', + file: string, + ) => { if (serverConfig.hmr !== false) { try { - await handleHMRUpdate(file, server, configOnly) + await handleHMRUpdate(type, file, server) } catch (err) { hot.send({ type: 'error', @@ -762,8 +764,8 @@ export async function _createServer( } } } - await handleFileAddUnlink(file, server, isUnlink) - await onHMRUpdate(file, true) + if (isUnlink) moduleGraph.onFileDelete(file) + await onHMRUpdate(isUnlink ? 'delete' : 'create', file) } watcher.on('change', async (file) => { @@ -771,7 +773,7 @@ export async function _createServer( await container.watchChange(file, { event: 'update' }) // invalidate module graph cache on file change moduleGraph.onFileChange(file) - await onHMRUpdate(file, false) + await onHMRUpdate('update', file) }) getFsUtils(config).initWatcher?.(watcher) diff --git a/packages/vite/src/node/server/moduleGraph.ts b/packages/vite/src/node/server/moduleGraph.ts index ac139f06fd112a..02a30fb7af315a 100644 --- a/packages/vite/src/node/server/moduleGraph.ts +++ b/packages/vite/src/node/server/moduleGraph.ts @@ -148,6 +148,17 @@ export class ModuleGraph { } } + onFileDelete(file: string): void { + const mods = this.getModulesByFile(file) + if (mods) { + mods.forEach((mod) => { + mod.importedModules.forEach((importedMod) => { + importedMod.importers.delete(mod) + }) + }) + } + } + invalidateModule( mod: ModuleNode, seen: Set = new Set(),