refactor(plugin-search): optimize search data generate (#855)

This commit is contained in:
pengzhanbo 2026-02-15 11:33:24 +08:00 committed by GitHub
parent bfd1d1692f
commit 1ed3dd9154
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 34 additions and 16 deletions

View File

@ -47,6 +47,10 @@ function getIndexCache(filepath: string) {
return index return index
} }
export async function prepareSearchIndexPlaceholder(app: App) {
await app.writeTemp(`${SEARCH_INDEX_DIR}index.js`, 'export const searchIndex = {}')
}
export async function prepareSearchIndex({ export async function prepareSearchIndex({
app, app,
isSearchable, isSearchable,
@ -56,10 +60,10 @@ export async function prepareSearchIndex({
indexByLocales.clear() indexByLocales.clear()
indexCache.clear() indexCache.clear()
const pages = isSearchable ? app.pages.filter(isSearchable) : app.pages await pMap(app.pages, p => indexFile(p, searchOptions, isSearchable), {
await pMap(pages, p => indexFile(p, searchOptions), {
concurrency: 64, concurrency: 64,
}) })
await writeTemp(app) await writeTemp(app)
if (app.env.isBuild) { if (app.env.isBuild) {
@ -84,7 +88,11 @@ export async function onSearchIndexUpdated(
): Promise<void> { ): Promise<void> {
const pages = isSearchable ? app.pages.filter(isSearchable) : app.pages const pages = isSearchable ? app.pages.filter(isSearchable) : app.pages
if (pages.some(p => p.filePathRelative?.endsWith(filepath))) { if (pages.some(p => p.filePathRelative?.endsWith(filepath))) {
await indexFile(app.pages.find(p => p.filePathRelative?.endsWith(filepath))!, searchOptions) await indexFile(
app.pages.find(p => p.filePathRelative?.endsWith(filepath))!,
searchOptions,
isSearchable,
)
await writeTemp(app) await writeTemp(app)
} }
} }
@ -113,29 +121,35 @@ export async function onSearchIndexRemoved(
async function writeTemp(app: App) { async function writeTemp(app: App) {
const records: string[] = [] const records: string[] = []
const promises: Promise<string>[] = []
for (const [locale] of indexByLocales) { for (const [locale] of indexByLocales) {
const index = indexByLocales.get(locale)! const index = indexByLocales.get(locale)!
const localeName = locale.replace(/^\/|\/$/g, '').replace(/\//g, '_') || 'default' const localeName = locale.replace(/^\/|\/$/g, '').replace(/\//g, '_') || 'default'
const filename = `searchBox-${localeName}.js` const filename = `searchBox-${localeName}.js`
records.push(`${JSON.stringify(locale)}: () => import('@${SEARCH_INDEX_DIR}${filename}')`) records.push(`${JSON.stringify(locale)}: () => import('@${SEARCH_INDEX_DIR}${filename}')`)
await app.writeTemp( promises.push(
app.writeTemp(
`${SEARCH_INDEX_DIR}${filename}`, `${SEARCH_INDEX_DIR}${filename}`,
`export default ${JSON.stringify( `export default ${JSON.stringify(
JSON.stringify(index) ?? {}, JSON.stringify(index) ?? {},
)}`, )}`,
),
) )
} }
await app.writeTemp( promises.push(
app.writeTemp(
`${SEARCH_INDEX_DIR}index.js`, `${SEARCH_INDEX_DIR}index.js`,
`export const searchIndex = {${records.join(',')}}${app.env.isDev ? `\n${genHmrCode('searchIndex')}` : ''}`, `export const searchIndex = {${records.join(',')}}${app.env.isDev ? `\n${genHmrCode('searchIndex')}` : ''}`,
),
) )
await Promise.all(promises)
} }
async function indexFile(page: Page, options: SearchIndexOptions['searchOptions']) { async function indexFile(page: Page, options: SearchIndexOptions['searchOptions'], isSearchable: SearchPluginOptions['isSearchable']) {
if (!page.filePath) if (!page.filePath || page.frontmatter?.search === false)
return return
if (page.frontmatter?.search === false) if (isSearchable && !isSearchable(page))
return return
// get file metadata // get file metadata

View File

@ -4,7 +4,7 @@ import { addViteOptimizeDepsInclude, getFullLocaleConfig } from '@vuepress/helpe
import chokidar from 'chokidar' import chokidar from 'chokidar'
import { getDirname, path } from 'vuepress/utils' import { getDirname, path } from 'vuepress/utils'
import { SEARCH_LOCALES } from './locales/index.js' import { SEARCH_LOCALES } from './locales/index.js'
import { onSearchIndexRemoved, onSearchIndexUpdated, prepareSearchIndex } from './prepareSearchIndex.js' import { onSearchIndexRemoved, onSearchIndexUpdated, prepareSearchIndex, prepareSearchIndexPlaceholder } from './prepareSearchIndex.js'
const __dirname = getDirname(import.meta.url) const __dirname = getDirname(import.meta.url)
@ -32,7 +32,11 @@ export function searchPlugin({
addViteOptimizeDepsInclude(bundlerOptions, app, ['mark.js/src/vanilla.js', '@vueuse/integrations/useFocusTrap', 'minisearch']) addViteOptimizeDepsInclude(bundlerOptions, app, ['mark.js/src/vanilla.js', '@vueuse/integrations/useFocusTrap', 'minisearch'])
}, },
onPrepared: app => prepareSearchIndex({ app, isSearchable, searchOptions }), onPrepared: async (app) => {
const placeholder = prepareSearchIndexPlaceholder(app)
prepareSearchIndex({ app, isSearchable, searchOptions })
await placeholder
},
onWatched: (app, watchers) => { onWatched: (app, watchers) => {
const searchIndexWatcher = chokidar.watch('pages', { const searchIndexWatcher = chokidar.watch('pages', {