Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: code snippets HMR #1789

Merged
merged 1 commit into from
Jul 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading