Skip to content

Commit

Permalink
fix: fix style block hmr for vitepress md files
Browse files Browse the repository at this point in the history
  • Loading branch information
yyx990803 committed Nov 8, 2023
1 parent e6417f6 commit a26a854
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 7 deletions.
18 changes: 15 additions & 3 deletions packages/plugin-vue/src/handleHotUpdate.ts
Expand Up @@ -4,6 +4,7 @@ import type { HmrContext, ModuleNode } from 'vite'
import { isCSSRequest } from 'vite'

import {
cache,
createDescriptor,
getDescriptor,
invalidateDescriptor,
Expand Down Expand Up @@ -148,9 +149,20 @@ export async function handleHotUpdate(
updateType.push(`style`)
}
if (updateType.length) {
// invalidate the descriptor cache so that the next transform will
// re-analyze the file and pick up the changes.
invalidateDescriptor(file)
if (file.endsWith('.vue')) {
// invalidate the descriptor cache so that the next transform will
// re-analyze the file and pick up the changes.
invalidateDescriptor(file)
} else {
// https://github.com/vuejs/vitepress/issues/3129
// For non-vue files, e.g. .md files in VitePress, invalidating the
// descriptor will cause the main `load()` hook to attempt to read and
// parse a descriptor from a non-vue source file, leading to errors.
// To fix that we need to provide the descriptor we parsed here in the
// main cache. This assumes no other plugin is applying pre-transform to
// the file type - not impossible, but should be extremely unlikely.
cache.set(file, descriptor)
}
debug(`[vue:update(${updateType.join('&')})] ${file}`)
}
return [...affectedModules].filter(Boolean) as ModuleNode[]
Expand Down
19 changes: 16 additions & 3 deletions packages/plugin-vue/src/main.ts
Expand Up @@ -40,9 +40,22 @@ export async function transformMain(
const prevDescriptor = getPrevDescriptor(filename)
const { descriptor, errors } = createDescriptor(filename, code, options)

if (fs.existsSync(filename))
// set descriptor for HMR if it's not set yet
getDescriptor(filename, options, true, true)
if (fs.existsSync(filename)) {
// populate descriptor cache for HMR if it's not set yet
getDescriptor(
filename,
options,
true,
true,
// for vue files, create descriptor from fs read to be consistent with
// logic in handleHotUpdate()
// for non vue files, e.g. md files in vitepress, we assume
// `hmrContext.read` is overwriten so handleHotUpdate() is dealing with
// post-transform code, so we populate the descriptor with post-transform
// code here as well.
filename.endsWith('.vue') ? undefined : code,
)
}

if (errors.length) {
errors.forEach((error) =>
Expand Down
7 changes: 6 additions & 1 deletion packages/plugin-vue/src/utils/descriptorCache.ts
Expand Up @@ -12,6 +12,10 @@ export interface SFCParseResult {
}

export const cache = new Map<string, SFCDescriptor>()
// we use a separate descriptor cache for HMR purposes.
// The main cached descriptors are parsed from SFCs that may have been
// transformed by other plugins, e.g. vue-macros;
// The HMR cached descriptors are based on the raw, pre-transform SFCs.
export const hmrCache = new Map<string, SFCDescriptor>()
const prevCache = new Map<string, SFCDescriptor | undefined>()

Expand Down Expand Up @@ -52,6 +56,7 @@ export function getDescriptor(
options: ResolvedOptions,
createIfNotFound = true,
hmr = false,
code?: string,
): SFCDescriptor | undefined {
const _cache = hmr ? hmrCache : cache
if (_cache.has(filename)) {
Expand All @@ -60,7 +65,7 @@ export function getDescriptor(
if (createIfNotFound) {
const { descriptor, errors } = createDescriptor(
filename,
fs.readFileSync(filename, 'utf-8'),
code ?? fs.readFileSync(filename, 'utf-8'),
options,
hmr,
)
Expand Down

0 comments on commit a26a854

Please sign in to comment.