@@ -25,12 +25,8 @@ const regexId = /^\/@slidev\/slide\/(\d+)\.(md|json)(?:\?import)?$/
25
25
const regexIdQuery = / ( \d + ) \. ( m d | j s o n | f r o n t m a t t e r ) $ /
26
26
27
27
const templateInjectionMarker = '/* @slidev-injection */'
28
- const templateImportContextUtils = `import {
29
- useSlideContext,
30
- provideFrontmatter as _provideFrontmatter,
31
- frontmatterToProps as _frontmatterToProps,
32
- } from "@slidev/client/context.ts"` . replace ( / \n \s * / g, ' ' )
33
- const templateInitContext = `const { $slidev, $nav, $clicksContext, $clicks, $page, $renderContext, $frontmatter } = useSlideContext()`
28
+ const templateImportContextUtils = `import { useSlideContext as _useSlideContext, frontmatterToProps as _frontmatterToProps } from "@slidev/client/context.ts"`
29
+ const templateInitContext = `const { $slidev, $nav, $clicksContext, $clicks, $page, $renderContext, $frontmatter } = _useSlideContext()`
34
30
35
31
export function getBodyJson ( req : Connect . IncomingMessage ) {
36
32
return new Promise < any > ( ( resolve , reject ) => {
@@ -321,37 +317,42 @@ export function createSlidesLoader(
321
317
return {
322
318
code : [
323
319
'// @unocss-include' ,
324
- 'import { reactive, computed } from "vue"' ,
325
- `export const frontmatter = reactive(${ JSON . stringify ( fontmatter ) } )` ,
326
- `export const meta = reactive({
327
- layout: computed(() => frontmatter.layout),
328
- transition: computed(() => frontmatter.transition),
329
- class: computed(() => frontmatter.class),
330
- clicks: computed(() => frontmatter.clicks),
331
- name: computed(() => frontmatter.name),
332
- preload: computed(() => frontmatter.preload),
333
- slide: {
334
- ...(${ JSON . stringify ( slideBase ) } ),
335
- frontmatter,
336
- filepath: ${ JSON . stringify ( mode === 'dev' ? slide . source . filepath : '' ) } ,
337
- start: ${ JSON . stringify ( slide . source . start ) } ,
338
- id: ${ pageNo } ,
339
- no: ${ no } ,
340
- },
341
- __clicksContext: null,
342
- __preloaded: false,
343
- })` ,
344
- 'export default frontmatter' ,
320
+ 'import { computed, reactive, shallowReactive } from "vue"' ,
321
+ `export const frontmatterData = ${ JSON . stringify ( fontmatter ) } ` ,
345
322
// handle HMR, update frontmatter with update
346
323
'if (import.meta.hot) {' ,
347
- ' import.meta.hot.accept(({ frontmatter: update }) => {' ,
348
- ' if(!update) return' ,
324
+ ' const firstLoad = !import.meta.hot.data.frontmatter' ,
325
+ ' import.meta.hot.data.frontmatter ??= reactive(frontmatterData)' ,
326
+ ' import.meta.hot.accept(({ frontmatterData: update }) => {' ,
327
+ ' if (firstLoad) return' ,
328
+ ' const frontmatter = import.meta.hot.data.frontmatter' ,
349
329
' Object.keys(frontmatter).forEach(key => {' ,
350
330
' if (!(key in update)) delete frontmatter[key]' ,
351
331
' })' ,
352
332
' Object.assign(frontmatter, update)' ,
353
333
' })' ,
354
334
'}' ,
335
+ 'export const frontmatter = import.meta.hot ? import.meta.hot.data.frontmatter : reactive(frontmatterData)' ,
336
+ 'export default frontmatter' ,
337
+ 'export const meta = shallowReactive({' ,
338
+ ' get layout(){ return frontmatter.layout },' ,
339
+ ' get transition(){ return frontmatter.transition },' ,
340
+ ' get class(){ return frontmatter.class },' ,
341
+ ' get clicks(){ return frontmatter.clicks },' ,
342
+ ' get name(){ return frontmatter.name },' ,
343
+ ' get preload(){ return frontmatter.preload },' ,
344
+ // No need to be reactive, as it's only used once after reload
345
+ ' slide: {' ,
346
+ ` ...(${ JSON . stringify ( slideBase ) } ),` ,
347
+ ` frontmatter,` ,
348
+ ` filepath: ${ JSON . stringify ( mode === 'dev' ? slide . source . filepath : '' ) } ,` ,
349
+ ` start: ${ JSON . stringify ( slide . source . start ) } ,` ,
350
+ ` id: ${ pageNo } ,` ,
351
+ ` no: ${ no } ,` ,
352
+ ' },' ,
353
+ ' __clicksContext: null,' ,
354
+ ' __preloaded: false,' ,
355
+ '})' ,
355
356
] . join ( '\n' ) ,
356
357
map : { mappings : '' } ,
357
358
}
@@ -430,9 +431,7 @@ export function createSlidesLoader(
430
431
delete frontmatter . title
431
432
const imports = [
432
433
`import InjectedLayout from "${ toAtFS ( layouts [ layoutName ] ) } "` ,
433
- `import frontmatter from "${ toAtFS ( `${ VIRTUAL_SLIDE_PREFIX + ( index + 1 ) } .frontmatter` ) } "` ,
434
434
templateImportContextUtils ,
435
- '_provideFrontmatter(frontmatter)' ,
436
435
templateInitContext ,
437
436
templateInjectionMarker ,
438
437
]
@@ -443,7 +442,7 @@ export function createSlidesLoader(
443
442
let body = code . slice ( injectA , injectB ) . trim ( )
444
443
if ( body . startsWith ( '<div>' ) && body . endsWith ( '</div>' ) )
445
444
body = body . slice ( 5 , - 6 )
446
- code = `${ code . slice ( 0 , injectA ) } \n<InjectedLayout v-bind="_frontmatterToProps(frontmatter,${ index } )">\n${ body } \n</InjectedLayout>\n${ code . slice ( injectB ) } `
445
+ code = `${ code . slice ( 0 , injectA ) } \n<InjectedLayout v-bind="_frontmatterToProps($ frontmatter,${ index } )">\n${ body } \n</InjectedLayout>\n${ code . slice ( injectB ) } `
447
446
448
447
return code
449
448
}
0 commit comments