Skip to content

Commit

Permalink
feat(hmr): call hotUpdate hook with file create/delete (#16249)
Browse files Browse the repository at this point in the history
  • Loading branch information
sapphi-red committed Mar 29, 2024
1 parent c1fc111 commit 3d37ac1
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 48 deletions.
71 changes: 35 additions & 36 deletions packages/vite/src/node/plugins/importMetaGlob.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,12 @@ import fg from 'fast-glob'
import { stringifyQuery } from 'ufo'
import type { GeneralImportGlobOptions } from 'types/importGlob'
import type { Plugin } from '../plugin'
import type { ViteDevServer } from '../server'
import type { EnvironmentModuleNode } from '../server/moduleGraph'
import type { ResolvedConfig } from '../config'
import { evalValue, normalizePath, transformStableResult } from '../utils'
import type { Logger } from '../logger'
import { slash } from '../../shared/utils'
import type { Environment } from '../environment'

const { isMatch, scan } = micromatch

Expand All @@ -44,43 +44,16 @@ interface ParsedGeneralImportGlobOptions extends GeneralImportGlobOptions {
query?: string
}

export function getAffectedGlobModules(
file: string,
server: ViteDevServer,
): EnvironmentModuleNode[] {
const modules: EnvironmentModuleNode[] = []
// TODO: properly support other runtimes. Changing _importGlobMap breaks VitePress
// https://github.com/vuejs/vitepress/blob/28989df83446923a9e7c8ada345b0778119ed66f/src/node/plugins/staticDataPlugin.ts#L128
for (const [id, allGlobs] of server._importGlobMap!) {
// (glob1 || glob2) && !glob3 && !glob4...
if (
allGlobs.some(
({ affirmed, negated }) =>
(!affirmed.length || affirmed.some((glob) => isMatch(file, glob))) &&
(!negated.length || negated.every((glob) => isMatch(file, glob))),
)
) {
const mod = server.environments.client.moduleGraph.getModuleById(id)

if (mod) {
if (mod.file) {
server.environments.client.moduleGraph.onFileChange(mod.file)
}
modules.push(mod)
}
}
}
return modules
}

export function importGlobPlugin(config: ResolvedConfig): Plugin {
let server: ViteDevServer | undefined
const importGlobMaps = new Map<
Environment,
Map<string, { affirmed: string[]; negated: string[] }[]>
>()

return {
name: 'vite:import-glob',
configureServer(_server) {
server = _server
server._importGlobMap.clear()
configureServer() {
importGlobMaps.clear()
},
async transform(code, id, options) {
if (!code.includes('import.meta.glob')) return
Expand All @@ -94,9 +67,12 @@ export function importGlobPlugin(config: ResolvedConfig): Plugin {
config.logger,
)
if (result) {
if (server) {
if (this.environment) {
const allGlobs = result.matches.map((i) => i.globsResolved)
server._importGlobMap.set(
if (!importGlobMaps.has(this.environment)) {
importGlobMaps.set(this.environment, new Map())
}
importGlobMaps.get(this.environment)!.set(
id,
allGlobs.map((globs) => {
const affirmed: string[] = []
Expand All @@ -112,6 +88,29 @@ export function importGlobPlugin(config: ResolvedConfig): Plugin {
return transformStableResult(result.s, id, config)
}
},
hotUpdate({ type, file, modules: oldModules, environment }) {
if (type === 'update') return

const importGlobMap = importGlobMaps.get(environment)
if (!importGlobMap) return

const modules: EnvironmentModuleNode[] = []
for (const [id, allGlobs] of importGlobMap) {
// (glob1 || glob2) && !glob3 && !glob4...
if (
allGlobs.some(
({ affirmed, negated }) =>
(!affirmed.length ||
affirmed.some((glob) => isMatch(file, glob))) &&
(!negated.length || negated.every((glob) => isMatch(file, glob))),
)
) {
const mod = environment.moduleGraph.getModuleById(id)
if (mod) modules.push(mod)
}
}
return modules.length > 0 ? [...oldModules, ...modules] : undefined
},
}
}

Expand Down
11 changes: 4 additions & 7 deletions packages/vite/src/node/server/hmr.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import { createDebugger, normalizePath } from '../utils'
import type { InferCustomEventPayload, ViteDevServer } from '..'
import { getHookHandler } from '../plugins'
import { isCSSRequest } from '../plugins/css'
import { getAffectedGlobModules } from '../plugins/importMetaGlob'
import { isExplicitImportRequired } from '../plugins/importAnalysis'
import { getEnvFilesForMode } from '../env'
import { withTrailingSlash, wrapId } from '../../shared/utils'
Expand Down Expand Up @@ -42,6 +41,7 @@ export interface HmrOptions {
}

export interface HotUpdateContext {
type: 'create' | 'update' | 'delete'
file: string
timestamp: number
modules: Array<EnvironmentModuleNode>
Expand Down Expand Up @@ -233,15 +233,11 @@ export async function handleHMRUpdate(
async function hmr(environment: DevEnvironment) {
try {
const mods = environment.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 hotContext: HotUpdateContext = {
type,
file,
timestamp,
modules: [...mods],
Expand All @@ -263,14 +259,15 @@ export async function handleHMRUpdate(
// Invalidate the hmrContext to force compat modules to be updated
hmrContext = undefined
}
} else if (environment.name === 'client') {
} else if (environment.name === 'client' && type === 'update') {
// later on, we'll need: if (runtime === 'client')
// Backward compatibility with mixed client and ssr moduleGraph
hmrContext ??= {
...hotContext,
modules: hotContext.modules.map((mod) =>
server.moduleGraph.getBackwardCompatibleModuleNode(mod),
),
type: undefined,
} as HmrContext
const filteredModules = await getHookHandler(plugin.handleHotUpdate!)(
hmrContext,
Expand Down
5 changes: 0 additions & 5 deletions packages/vite/src/node/server/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -382,10 +382,6 @@ export interface ViteDevServer {
* @internal
*/
_setInternalServer(server: ViteDevServer): void
/**
* @internal
*/
_importGlobMap: Map<string, { affirmed: string[]; negated: string[] }[]>
/**
* @internal
*/
Expand Down Expand Up @@ -742,7 +738,6 @@ export async function _createServer(
server = _server
},
_restartPromise: null,
_importGlobMap: new Map(),
_forceOptimizeOnRestart: false,
_pendingRequests: new Map(),
_safeModulesPath: new Set(),
Expand Down

0 comments on commit 3d37ac1

Please sign in to comment.