From 5ebd6b39ced39399cf1c699a071571fcad7925f4 Mon Sep 17 00:00:00 2001 From: Divyansh Singh <40380293+brc-dd@users.noreply.github.com> Date: Thu, 30 Jul 2026 03:13:45 +0530 Subject: [PATCH] refactor(search): handle missing files at read time and skip empty pages Drop the existsSync pre-check in favor of catching ENOENT from the read itself, and skip indexing when a page renders to nothing (file gone or excluded via search: false) instead of feeding empty html to the section splitter. Co-Authored-By: Claude Fable 5 --- src/node/plugins/localSearchPlugin.ts | 35 ++++++++++++++++----------- 1 file changed, 21 insertions(+), 14 deletions(-) diff --git a/src/node/plugins/localSearchPlugin.ts b/src/node/plugins/localSearchPlugin.ts index 4a209cea..472c4b18 100644 --- a/src/node/plugins/localSearchPlugin.ts +++ b/src/node/plugins/localSearchPlugin.ts @@ -1,6 +1,5 @@ import { prefixRegex } from '@rolldown/pluginutils' import MiniSearch from 'minisearch' -import fs from 'node:fs' import { readFile } from 'node:fs/promises' import path from 'node:path' import { createDebug } from 'obug' @@ -50,16 +49,21 @@ export async function localSearchPlugin( const options = siteConfig.site.themeConfig.search.options || {} async function render(file: string) { - if (!fs.existsSync(file)) return '' const { srcDir, cleanUrls = false } = siteConfig const relativePath = slash(path.relative(srcDir, file)) const env: MarkdownEnv = { path: file, relativePath, cleanUrls } - const md_raw = await readFile(file, 'utf8') - const md_src = processIncludes(md, srcDir, md_raw, file, [], cleanUrls) + const raw = await readFile(file, 'utf8').catch((e) => { + if (e.code === 'ENOENT') { + debug(`File not found: ${file}`) + return '' + } + throw e + }) + const src = processIncludes(md, srcDir, raw, file, [], cleanUrls) if (options._render) { - return await options._render(md_src, env, md) + return options._render(src, env, md) } else { - const html = await md.renderAsync(md_src, env) + const html = await md.renderAsync(src, env) return env.frontmatter?.search === false ? '' : html } } @@ -128,6 +132,7 @@ export async function localSearchPlugin( const index = getIndexByLocale(locale) // retrieve file and split into "sections" const html = await render(file) + if (!html) return const sections = // user provided generator (await options.miniSearch?._splitIntoSections?.(file, html)) ?? @@ -169,15 +174,17 @@ export async function localSearchPlugin( ) }, - config: () => ({ - optimizeDeps: { - include: [ - 'vitepress > @vueuse/integrations/useFocusTrap', - 'vitepress > mark.js/src/vanilla.js', - 'vitepress > minisearch' - ] + config() { + return { + optimizeDeps: { + include: [ + 'vitepress > @vueuse/integrations/useFocusTrap', + 'vitepress > mark.js/src/vanilla.js', + 'vitepress > minisearch' + ] + } } - }), + }, configureServer(_server) { server = _server