From 4f817d16348d751b6f8be70b687dcddf1aeb6d2f Mon Sep 17 00:00:00 2001 From: sapphi-red <49056869+sapphi-red@users.noreply.github.com> Date: Sun, 24 Mar 2024 17:21:31 +0900 Subject: [PATCH 1/4] refactor(hmr): extract `moduleGraph.onFileDelete` --- packages/vite/src/node/server/hmr.ts | 8 -------- packages/vite/src/node/server/index.ts | 1 + packages/vite/src/node/server/moduleGraph.ts | 11 +++++++++++ 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/packages/vite/src/node/server/hmr.ts b/packages/vite/src/node/server/hmr.ts index 86bf9961bf9a72..45e49cbc3228eb 100644 --- a/packages/vite/src/node/server/hmr.ts +++ b/packages/vite/src/node/server/hmr.ts @@ -322,14 +322,6 @@ export async function handleFileAddUnlink( ): 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) { diff --git a/packages/vite/src/node/server/index.ts b/packages/vite/src/node/server/index.ts index 134a781b9550d9..067cf4634f7d40 100644 --- a/packages/vite/src/node/server/index.ts +++ b/packages/vite/src/node/server/index.ts @@ -762,6 +762,7 @@ export async function _createServer( } } } + if (isUnlink) moduleGraph.onFileDelete(file) await handleFileAddUnlink(file, server, isUnlink) await onHMRUpdate(file, true) } 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(), From 1f0b656549093cb396ca0ab95779e859eca71369 Mon Sep 17 00:00:00 2001 From: sapphi-red <49056869+sapphi-red@users.noreply.github.com> Date: Sun, 24 Mar 2024 17:25:23 +0900 Subject: [PATCH 2/4] refactor(hmr): merge `handleFileAddUnlink` and `onHMRUpdate` --- packages/vite/src/node/server/hmr.ts | 80 ++++++++++++-------------- packages/vite/src/node/server/index.ts | 14 +++-- 2 files changed, 44 insertions(+), 50 deletions(-) diff --git a/packages/vite/src/node/server/hmr.ts b/packages/vite/src/node/server/hmr.ts index 45e49cbc3228eb..e583fecdb67888 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,6 +118,7 @@ export function getShortName(file: string, root: string): string { } export async function handleHMRUpdate( + type: 'create' | 'delete' | 'update', file: string, server: ViteDevServer, configOnly: boolean, @@ -166,43 +167,53 @@ 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 + } } - } - if (!hmrContext.modules.length) { - // html file cannot be hot updated - if (file.endsWith('.html')) { - config.logger.info(colors.green(`page reload `) + colors.dim(shortFile), { - clear: true, - timestamp: true, - }) - hot.send({ - type: 'full-reload', - path: config.server.middlewareMode - ? '*' - : '/' + normalizePath(path.relative(config.root, file)), - }) - } else { - // loaded but not in the module graph, probably not js - debugHmr?.(`[no modules matched] ${colors.dim(shortFile)}`) + if (!hmrContext.modules.length) { + // html file cannot be hot updated + if (file.endsWith('.html')) { + config.logger.info( + colors.green(`page reload `) + colors.dim(shortFile), + { + clear: true, + timestamp: true, + }, + ) + hot.send({ + type: 'full-reload', + path: config.server.middlewareMode + ? '*' + : '/' + normalizePath(path.relative(config.root, file)), + }) + } else { + // loaded but not in the module graph, probably not js + debugHmr?.(`[no modules matched] ${colors.dim(shortFile)}`) + } + return } - return } updateModules(shortFile, hmrContext.modules, timestamp, server) @@ -315,25 +326,6 @@ function getSSRInvalidatedImporters(module: ModuleNode) { ) } -export async function handleFileAddUnlink( - file: string, - server: ViteDevServer, - isUnlink: boolean, -): Promise { - const modules = [...(server.moduleGraph.getModulesByFile(file) || [])] - - 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 067cf4634f7d40..9e4b62a88c70dc 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,14 @@ export async function _createServer( const publicFiles = await initPublicFilesPromise - const onHMRUpdate = async (file: string, configOnly: boolean) => { + const onHMRUpdate = async ( + type: 'create' | 'delete' | 'update', + file: string, + configOnly: boolean, + ) => { if (serverConfig.hmr !== false) { try { - await handleHMRUpdate(file, server, configOnly) + await handleHMRUpdate(type, file, server, configOnly) } catch (err) { hot.send({ type: 'error', @@ -763,8 +766,7 @@ export async function _createServer( } } if (isUnlink) moduleGraph.onFileDelete(file) - await handleFileAddUnlink(file, server, isUnlink) - await onHMRUpdate(file, true) + await onHMRUpdate(isUnlink ? 'delete' : 'create', file, false) } watcher.on('change', async (file) => { @@ -772,7 +774,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, false) }) getFsUtils(config).initWatcher?.(watcher) From de606d402818f2d575c69b4041515c39a8ffd119 Mon Sep 17 00:00:00 2001 From: sapphi-red <49056869+sapphi-red@users.noreply.github.com> Date: Sun, 24 Mar 2024 17:26:19 +0900 Subject: [PATCH 3/4] refactor(hmr): remove `configOnly` parameter --- packages/vite/src/node/server/hmr.ts | 5 ----- packages/vite/src/node/server/index.ts | 7 +++---- 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/packages/vite/src/node/server/hmr.ts b/packages/vite/src/node/server/hmr.ts index e583fecdb67888..38b7945a4852df 100644 --- a/packages/vite/src/node/server/hmr.ts +++ b/packages/vite/src/node/server/hmr.ts @@ -121,7 +121,6 @@ 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) @@ -151,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. diff --git a/packages/vite/src/node/server/index.ts b/packages/vite/src/node/server/index.ts index 9e4b62a88c70dc..5cd066ffc736d4 100644 --- a/packages/vite/src/node/server/index.ts +++ b/packages/vite/src/node/server/index.ts @@ -730,11 +730,10 @@ export async function _createServer( const onHMRUpdate = async ( type: 'create' | 'delete' | 'update', file: string, - configOnly: boolean, ) => { if (serverConfig.hmr !== false) { try { - await handleHMRUpdate(type, file, server, configOnly) + await handleHMRUpdate(type, file, server) } catch (err) { hot.send({ type: 'error', @@ -766,7 +765,7 @@ export async function _createServer( } } if (isUnlink) moduleGraph.onFileDelete(file) - await onHMRUpdate(isUnlink ? 'delete' : 'create', file, false) + await onHMRUpdate(isUnlink ? 'delete' : 'create', file) } watcher.on('change', async (file) => { @@ -774,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('update', file, false) + await onHMRUpdate('update', file) }) getFsUtils(config).initWatcher?.(watcher) From 635188e524a0ac498881c4eb1b7ca7b3b7845a61 Mon Sep 17 00:00:00 2001 From: sapphi-red <49056869+sapphi-red@users.noreply.github.com> Date: Sun, 24 Mar 2024 17:34:06 +0900 Subject: [PATCH 4/4] feat(hmr): reload when HTML file is created/deleted --- packages/vite/src/node/server/hmr.ts | 39 +++++++++++++--------------- 1 file changed, 18 insertions(+), 21 deletions(-) diff --git a/packages/vite/src/node/server/hmr.ts b/packages/vite/src/node/server/hmr.ts index 38b7945a4852df..cf28591db056de 100644 --- a/packages/vite/src/node/server/hmr.ts +++ b/packages/vite/src/node/server/hmr.ts @@ -186,29 +186,26 @@ export async function handleHMRUpdate( hmrContext.modules = filteredModules } } + } - if (!hmrContext.modules.length) { - // html file cannot be hot updated - if (file.endsWith('.html')) { - config.logger.info( - colors.green(`page reload `) + colors.dim(shortFile), - { - clear: true, - timestamp: true, - }, - ) - hot.send({ - type: 'full-reload', - path: config.server.middlewareMode - ? '*' - : '/' + normalizePath(path.relative(config.root, file)), - }) - } else { - // loaded but not in the module graph, probably not js - debugHmr?.(`[no modules matched] ${colors.dim(shortFile)}`) - } - return + if (!hmrContext.modules.length) { + // html file cannot be hot updated + if (file.endsWith('.html')) { + config.logger.info(colors.green(`page reload `) + colors.dim(shortFile), { + clear: true, + timestamp: true, + }) + hot.send({ + type: 'full-reload', + path: config.server.middlewareMode + ? '*' + : '/' + normalizePath(path.relative(config.root, file)), + }) + } else { + // loaded but not in the module graph, probably not js + debugHmr?.(`[no modules matched] ${colors.dim(shortFile)}`) } + return } updateModules(shortFile, hmrContext.modules, timestamp, server)