Skip to content

Commit ca1f5be

Browse files
committed
fix: improve virual vue hmr
1 parent 4d9f6ad commit ca1f5be

File tree

2 files changed

+54
-31
lines changed

2 files changed

+54
-31
lines changed

packages/slidev/node/plugins/loaders.ts

Lines changed: 38 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -62,16 +62,15 @@ function prepareSlideInfo(data: SlideInfo): SlideInfoExtended {
6262
}
6363
}
6464

65-
export function createSlidesLoader({ data, entry, clientRoot, themeRoots, userRoot }: ResolvedSlidevOptions, pluginOptions: SlidevPluginOptions): Plugin[] {
65+
export function createSlidesLoader({ data, entry, clientRoot, themeRoots, userRoot }: ResolvedSlidevOptions, pluginOptions: SlidevPluginOptions, VuePlugin: Plugin): Plugin[] {
6666
const slidePrefix = '/@slidev/slides/'
67-
const hmrNextModuleIds: string[] = []
67+
const hmrPages = new Set<number>()
6868

6969
const entryId = slash(entry)
7070

7171
return [
7272
{
7373
name: 'slidev:loader',
74-
7574
configureServer(server) {
7675
server.watcher.add(entry)
7776

@@ -90,7 +89,7 @@ export function createSlidesLoader({ data, entry, clientRoot, themeRoots, userRo
9089
const body = await getBodyJson(req)
9190
Object.assign(data.slides[idx], body)
9291

93-
hmrNextModuleIds.push(`${slidePrefix}${idx + 1}.md`)
92+
hmrPages.add(idx)
9493

9594
server.ws.send({
9695
type: 'custom',
@@ -117,11 +116,7 @@ export function createSlidesLoader({ data, entry, clientRoot, themeRoots, userRo
117116

118117
const newData = await parser.load(entry)
119118

120-
const moduleIds: (string | false)[] = [
121-
...hmrNextModuleIds,
122-
]
123-
124-
hmrNextModuleIds.length = 0
119+
const moduleIds: string[] = []
125120

126121
if (data.slides.length !== newData.slides.length)
127122
moduleIds.push('/@slidev/routes')
@@ -138,28 +133,47 @@ export function createSlidesLoader({ data, entry, clientRoot, themeRoots, userRo
138133
const length = Math.max(data.slides.length, newData.slides.length)
139134

140135
for (let i = 0; i < length; i++) {
136+
if (hmrPages.has(i))
137+
continue
138+
141139
const a = data.slides[i]
142140
const b = newData.slides[i]
143-
144141
if (a?.content.trim() === b?.content.trim() && JSON.stringify(a.frontmatter) === JSON.stringify(b.frontmatter))
145142
continue
143+
hmrPages.add(i)
144+
}
146145

147-
moduleIds.push(
148-
`${slidePrefix}${i + 1}.md`,
149-
`${slidePrefix}${i + 1}.json`,
146+
const modules = (
147+
await Promise.all(
148+
Array.from(hmrPages)
149+
.map(async(i) => {
150+
const id = `${slidePrefix}${i + 1}.md`
151+
const module = ctx.server.moduleGraph.getModuleById(id)
152+
153+
return await VuePlugin.handleHotUpdate!({
154+
...ctx,
155+
modules: Array.from(module?.importedModules || []),
156+
file: id,
157+
read() {
158+
return newData.slides[i - 1]?.raw
159+
},
160+
},
161+
)
162+
}),
150163
)
151-
}
164+
).flatMap(i => i || [])
165+
166+
hmrPages.clear()
152167

153168
const moduleEntries = moduleIds
154169
.filter(isTruthy)
155-
.map(id => ctx.server.moduleGraph.getModuleById(id as string))
170+
.map(id => ctx.server.moduleGraph.getModuleById(id))
156171
.filter(notNullish)
172+
.concat(modules)
157173

158174
pluginOptions.onDataReload?.(newData, data)
159-
160175
Object.assign(data, newData)
161176

162-
moduleEntries.map(m => ctx.server.moduleGraph.invalidateModule(m))
163177
return moduleEntries
164178
},
165179

@@ -227,6 +241,13 @@ export function createSlidesLoader({ data, entry, clientRoot, themeRoots, userRo
227241
}
228242
},
229243
},
244+
{
245+
name: 'xxx',
246+
handleHotUpdate(i) {
247+
if (i.file.endsWith('.vue'))
248+
console.dir(i.modules)
249+
},
250+
},
230251
]
231252

232253
async function getLayouts() {

packages/slidev/node/plugins/preset.ts

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -54,24 +54,27 @@ export async function ViteSlidevPlugin(
5454
data: { config },
5555
} = options
5656

57-
return [
58-
createWindiCSSPlugin(options, pluginOptions),
59-
60-
Vue({
61-
include: [/\.vue$/, /\.md$/],
62-
exclude: [],
63-
template: {
64-
compilerOptions: {
65-
isCustomElement(tag) {
66-
return customElements.has(tag)
67-
},
57+
const VuePlugin = Vue({
58+
include: [/\.vue$/, /\.md$/],
59+
exclude: [],
60+
template: {
61+
compilerOptions: {
62+
isCustomElement(tag) {
63+
return customElements.has(tag)
6864
},
6965
},
70-
...vueOptions,
71-
}),
66+
},
67+
...vueOptions,
68+
})
7269

70+
return [
71+
createWindiCSSPlugin(options, pluginOptions),
7372
await createMarkdownPlugin(options, pluginOptions),
7473

74+
VuePlugin,
75+
76+
createSlidesLoader(options, pluginOptions, VuePlugin),
77+
7578
ViteComponents({
7679
extensions: ['vue', 'md', 'ts'],
7780

@@ -124,7 +127,6 @@ export async function ViteSlidevPlugin(
124127
}),
125128
createConfigPlugin(options),
126129
createEntryPlugin(options),
127-
createSlidesLoader(options, pluginOptions),
128130
createClientSetupPlugin(options),
129131
createMonacoTypesLoader(),
130132
createFixPlugins(options),

0 commit comments

Comments
 (0)