Skip to content

Commit aa2b59d

Browse files
authored
fix(plugin-vue): distinguish HMR and transform descriptor (#227)
1 parent 729181c commit aa2b59d

File tree

3 files changed

+25
-15
lines changed

3 files changed

+25
-15
lines changed

packages/plugin-vue/src/handleHotUpdate.ts

+6-5
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { isCSSRequest } from 'vite'
66
import {
77
createDescriptor,
88
getDescriptor,
9-
setPrevDescriptor,
9+
invalidateDescriptor,
1010
} from './utils/descriptorCache'
1111
import {
1212
getResolvedScript,
@@ -26,16 +26,14 @@ export async function handleHotUpdate(
2626
{ file, modules, read }: HmrContext,
2727
options: ResolvedOptions,
2828
): Promise<ModuleNode[] | void> {
29-
const prevDescriptor = getDescriptor(file, options, false)
29+
const prevDescriptor = getDescriptor(file, options, false, true)
3030
if (!prevDescriptor) {
3131
// file hasn't been requested yet (e.g. async component)
3232
return
3333
}
3434

35-
setPrevDescriptor(file, prevDescriptor)
36-
3735
const content = await read()
38-
const { descriptor } = createDescriptor(file, content, options)
36+
const { descriptor } = createDescriptor(file, content, options, true)
3937

4038
let needRerender = false
4139
const affectedModules = new Set<ModuleNode | undefined>()
@@ -150,6 +148,9 @@ export async function handleHotUpdate(
150148
updateType.push(`style`)
151149
}
152150
if (updateType.length) {
151+
// invalidate the descriptor cache so that the next transform will
152+
// re-analyze the file and pick up the changes.
153+
invalidateDescriptor(file)
153154
debug(`[vue:update(${updateType.join('&')})] ${file}`)
154155
}
155156
return [...affectedModules].filter(Boolean) as ModuleNode[]

packages/plugin-vue/src/main.ts

+4-1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import { addMapping, fromMap, toEncodedMap } from '@jridgewell/gen-mapping'
99
import { normalizePath, transformWithEsbuild } from 'vite'
1010
import {
1111
createDescriptor,
12+
getDescriptor,
1213
getPrevDescriptor,
1314
setSrcDescriptor,
1415
} from './utils/descriptorCache'
@@ -35,10 +36,12 @@ export async function transformMain(
3536
) {
3637
const { devServer, isProduction, devToolsEnabled } = options
3738

38-
// prev descriptor is only set and used for hmr
3939
const prevDescriptor = getPrevDescriptor(filename)
4040
const { descriptor, errors } = createDescriptor(filename, code, options)
4141

42+
// set descriptor for HMR if it's not set yet
43+
getDescriptor(filename, options, true, true)
44+
4245
if (errors.length) {
4346
errors.forEach((error) =>
4447
pluginContext.error(createRollupError(filename, error)),

packages/plugin-vue/src/utils/descriptorCache.ts

+15-9
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,14 @@ export interface SFCParseResult {
1212
}
1313

1414
export const cache = new Map<string, SFCDescriptor>()
15+
export const hmrCache = new Map<string, SFCDescriptor>()
1516
const prevCache = new Map<string, SFCDescriptor | undefined>()
1617

1718
export function createDescriptor(
1819
filename: string,
1920
source: string,
2021
{ root, isProduction, sourceMap, compiler }: ResolvedOptions,
22+
hmr = false,
2123
): SFCParseResult {
2224
const { descriptor, errors } = compiler.parse(source, {
2325
filename,
@@ -28,35 +30,39 @@ export function createDescriptor(
2830
// project (relative to root) and on different systems.
2931
const normalizedPath = slash(path.normalize(path.relative(root, filename)))
3032
descriptor.id = getHash(normalizedPath + (isProduction ? source : ''))
31-
32-
cache.set(filename, descriptor)
33+
;(hmr ? hmrCache : cache).set(filename, descriptor)
3334
return { descriptor, errors }
3435
}
3536

3637
export function getPrevDescriptor(filename: string): SFCDescriptor | undefined {
3738
return prevCache.get(filename)
3839
}
3940

40-
export function setPrevDescriptor(
41-
filename: string,
42-
entry: SFCDescriptor,
43-
): void {
44-
prevCache.set(filename, entry)
41+
export function invalidateDescriptor(filename: string, hmr = false): void {
42+
const _cache = hmr ? hmrCache : cache
43+
const prev = _cache.get(filename)
44+
_cache.delete(filename)
45+
if (prev) {
46+
prevCache.set(filename, prev)
47+
}
4548
}
4649

4750
export function getDescriptor(
4851
filename: string,
4952
options: ResolvedOptions,
5053
createIfNotFound = true,
54+
hmr = false,
5155
): SFCDescriptor | undefined {
52-
if (cache.has(filename)) {
53-
return cache.get(filename)!
56+
const _cache = hmr ? hmrCache : cache
57+
if (_cache.has(filename)) {
58+
return _cache.get(filename)!
5459
}
5560
if (createIfNotFound) {
5661
const { descriptor, errors } = createDescriptor(
5762
filename,
5863
fs.readFileSync(filename, 'utf-8'),
5964
options,
65+
hmr,
6066
)
6167
if (errors.length) {
6268
throw errors[0]

0 commit comments

Comments
 (0)