Skip to content

Commit

Permalink
fix: code snippets HMR (#1789)
Browse files Browse the repository at this point in the history
  • Loading branch information
KermanX authored Jul 28, 2024
1 parent c0a0e40 commit d054c55
Show file tree
Hide file tree
Showing 7 changed files with 30 additions and 25 deletions.
4 changes: 3 additions & 1 deletion packages/parser/src/fs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ export async function load(userRoot: string, filepath: string, loadedSource: Rec
}

const markdownFiles: Record<string, SlidevMarkdown> = {}
const watchFiles: Record<string, Set<number>> = {}
const slides: SlideInfo[] = []

async function loadMarkdown(path: string, range?: string, frontmatterOverride?: Record<string, unknown>, importers?: SourceSlideInfo[]) {
Expand All @@ -48,6 +49,7 @@ export async function load(userRoot: string, filepath: string, loadedSource: Rec
const raw = loadedSource[path] ?? fs.readFileSync(path, 'utf-8')
md = await parse(raw, path, extensions)
markdownFiles[path] = md
watchFiles[path] = new Set()
}

const directImporter = importers?.at(-1)
Expand Down Expand Up @@ -125,7 +127,7 @@ export async function load(userRoot: string, filepath: string, loadedSource: Rec
headmatter,
features: detectFeatures(slides.map(s => s.source.raw).join('')),
markdownFiles,
watchFiles: Object.keys(markdownFiles).map(slash),
watchFiles,
}
}

Expand Down
8 changes: 3 additions & 5 deletions packages/slidev/node/syntax/transform/snippet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ function findRegion(lines: Array<string>, regionName: string) {
* captures: ['/path/to/file.extension', '#region', 'language', '{meta}']
*/
export function transformSnippet({ s, slide, options }: MarkdownTransformContext) {
const data = options.data
const watchFiles = options.data.watchFiles
const dir = path.dirname(slide.source?.filepath ?? options.entry ?? options.userRoot)

s.replace(
Expand All @@ -97,7 +97,8 @@ export function transformSnippet({ s, slide, options }: MarkdownTransformContext
: path.resolve(dir, filepath),
)

data.watchFiles.push(src)
watchFiles[src] ??= new Set()
watchFiles[src].add(slide.index)

const isAFile = fs.statSync(src).isFile()
if (!fs.existsSync(src) || !isAFile) {
Expand All @@ -108,9 +109,6 @@ export function transformSnippet({ s, slide, options }: MarkdownTransformContext

let content = fs.readFileSync(src, 'utf8')

slide.snippetsUsed ??= {}
slide.snippetsUsed[src] = content

if (regionName) {
const lines = content.split(/\r?\n/)
const region = findRegion(lines, regionName.slice(1))
Expand Down
27 changes: 16 additions & 11 deletions packages/slidev/node/vite/loaders.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ export function createSlidesLoader(
options: ResolvedSlidevOptions,
serverOptions: SlidevServerOptions,
): Plugin {
const hmrPages = new Set<number>()
const hmrSlidesIndexes = new Set<number>()
let server: ViteDevServer | undefined

let skipHmr: { filePath: string, fileContent: string } | null = null
Expand All @@ -53,7 +53,7 @@ export function createSlidesLoader(
function updateServerWatcher() {
if (!server)
return
server.watcher.add(data.watchFiles)
server.watcher.add(Object.keys(data.watchFiles))
}

function getFrontmatter(pageNo: number) {
Expand Down Expand Up @@ -87,7 +87,7 @@ export function createSlidesLoader(
const slide = data.slides[idx]

if (body.content && body.content !== slide.source.content)
hmrPages.add(idx)
hmrSlidesIndexes.add(idx)

if (body.content)
slide.content = slide.source.content = body.content
Expand Down Expand Up @@ -123,9 +123,14 @@ export function createSlidesLoader(
},

async handleHotUpdate(ctx) {
if (!data.watchFiles.includes(ctx.file))
const forceChangedSlides = data.watchFiles[ctx.file]
if (!forceChangedSlides)
return

for (const index of forceChangedSlides) {
hmrSlidesIndexes.add(index)
}

const newData = await serverOptions.loadData?.({
[ctx.file]: await ctx.read(),
})
Expand All @@ -142,12 +147,12 @@ export function createSlidesLoader(

if (data.slides.length !== newData.slides.length) {
moduleIds.add(templateSlides.id)
range(newData.slides.length).map(i => hmrPages.add(i))
range(newData.slides.length).map(i => hmrSlidesIndexes.add(i))
}

if (!equal(data.headmatter.defaults, newData.headmatter.defaults)) {
moduleIds.add(templateSlides.id)
range(data.slides.length).map(i => hmrPages.add(i))
range(data.slides.length).map(i => hmrSlidesIndexes.add(i))
}

if (!equal(data.config, newData.config))
Expand All @@ -166,7 +171,7 @@ export function createSlidesLoader(
const b = newData.slides[i]

if (
!hmrPages.has(i)
!hmrSlidesIndexes.has(i)
&& a.content.trim() === b.content.trim()
&& a.title?.trim() === b.title?.trim()
&& equal(a.frontmatter, b.frontmatter)
Expand All @@ -191,16 +196,16 @@ export function createSlidesLoader(
data: withRenderedNote(newData.slides[i]),
},
)
hmrPages.add(i)
hmrSlidesIndexes.add(i)
}

Object.assign(data, newData)
Object.assign(utils, createDataUtils(newData, clientRoot, roots))

if (hmrPages.size > 0)
if (hmrSlidesIndexes.size > 0)
moduleIds.add(templateTitleRendererMd.id)

const vueModules = Array.from(hmrPages)
const vueModules = Array.from(hmrSlidesIndexes)
.flatMap((idx) => {
const frontmatter = ctx.server.moduleGraph.getModuleById(getSourceId(idx, 'frontmatter'))
const main = ctx.server.moduleGraph.getModuleById(getSourceId(idx, 'md'))
Expand All @@ -212,7 +217,7 @@ export function createSlidesLoader(
]
})

hmrPages.clear()
hmrSlidesIndexes.clear()

const moduleEntries = [
...ctx.modules.filter(i => i.id === templateMonacoRunDeps.id || i.id === templateMonacoTypes.id),
Expand Down
8 changes: 4 additions & 4 deletions packages/types/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@ export interface SlideInfo extends SlideInfoBase {
* The source slide where the content is from
*/
source: SourceSlideInfo
snippetsUsed?: LoadedSnippets
noteHTML?: string
}

Expand Down Expand Up @@ -112,7 +111,10 @@ export interface SlidevData {
features: SlidevDetectedFeatures
themeMeta?: SlidevThemeMeta
markdownFiles: Record<string, SlidevMarkdown>
watchFiles: string[]
/**
* From watched files to indexes of slides that must be reloaded regardless of the loaded content
*/
watchFiles: Record<string, Set<number>>
}

export interface SlidevPreparserExtension {
Expand All @@ -137,5 +139,3 @@ export interface SlideRoute {
*/
component: Component
}

export type LoadedSnippets = Record<string, string>
4 changes: 2 additions & 2 deletions packages/vscode/src/projects.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,15 +75,15 @@ export function useProjects() {
onScopeDispose(() => fsWatcher.dispose())

fsWatcher.onDidChange(async (uri) => {
const path = slash(uri.fsPath).toLowerCase()
const path = slash(uri.fsPath)
logger.info(`File ${path} changed.`)
const startMs = Date.now()
if (pendingUpdate)
pendingUpdate.cancelled = true
const thisUpdate = pendingUpdate = { cancelled: false }
const effects: (() => void)[] = []
for (const project of projects.values()) {
if (!project.data.watchFiles.some(f => f.toLowerCase() === path))
if (!project.data.markdownFiles[path])
continue

if (existsSync(project.entry)) {
Expand Down
2 changes: 1 addition & 1 deletion packages/vscode/src/views/projectsTree.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ export const useProjectsTree = createSingletonComposable(() => {
const treeData = computed(() => {
return [...projects.values()].map(project => ({
treeItem: getProjectTreeItem(project),
children: project.data.watchFiles
children: Object.keys(project.data.markdownFiles)
.filter(file => file.toLowerCase() !== project.entry.toLowerCase())
.map(file => ({ treeItem: getFileTreeItem(file) })),
}))
Expand Down
2 changes: 1 addition & 1 deletion test/_tutils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export function createTransformContext(code: string, shiki?: any): MarkdownTrans
slides: [
{} as any,
],
watchFiles: [],
watchFiles: {},
config: {} as any,
features: {},
},
Expand Down

0 comments on commit d054c55

Please sign in to comment.