vitepress-plugin-pagefind
Version:
vitepress plugin, Offline full-text search based on pagefind implementation.
1 lines • 17.1 kB
Source Map (JSON)
{"version":3,"sources":["../src/index.ts","../src/node.ts","../src/utils/index.ts"],"sourcesContent":["import { Buffer } from 'node:buffer'\nimport path from 'node:path'\nimport { fileURLToPath } from 'node:url'\nimport fs from 'node:fs'\nimport process from 'node:process'\nimport type { PluginOption } from 'vite'\nimport type { HeadConfig, SiteConfig } from 'vitepress'\nimport { stringify } from 'javascript-stringify'\nimport { cacheAllGitTimestamps, getFileLastModifyTime, grayMatter, joinPath } from '@sugarat/theme-shared'\nimport { buildEnd, getPagefindHead } from './node'\nimport type { PagefindOption, SearchConfig } from './type'\n\nfunction isESM() {\n return typeof __filename === 'undefined' || typeof __dirname === 'undefined'\n}\nfunction getDirname() {\n return isESM() ? path.dirname(fileURLToPath(import.meta.url)) : __dirname\n}\n\nconst aliasSearchVueFile = `${getDirname()}/../src/Search.vue`\nconst aliasSearchVueFileMPA = `${getDirname()}/../src/SearchMPA.vue`\nconst aliasSearchVueFileMPADefault = `${getDirname()}/../src/SearchMPADefault.vue`\n\nexport function meta2string(frontmatter: Record<string, any>) {\n return `base64:${Buffer.from(encodeURIComponent(JSON.stringify(frontmatter))).toString('base64')}`\n}\n\nexport function pagefindPlugin(\n searchConfig: SearchConfig & PagefindOption = {}\n): any {\n const virtualModuleId = 'virtual:pagefind'\n const resolvedVirtualModuleId = `\\0${virtualModuleId}`\n\n let resolveConfig: any\n let vitepressConfig: SiteConfig\n let dynamicRoutes: SiteConfig['dynamicRoutes']\n const pluginOps: PluginOption = {\n name: 'vitepress-plugin-pagefind',\n config: (cfg) => {\n // @ts-expect-error\n // MPA 模式下使用 MPA 组件\n const isMPA = !!cfg.vitepress.mpa\n const isMPADefaultUI = searchConfig.mpaDefaultUI\n return {\n resolve: {\n alias: {\n './VPNavBarSearch.vue': isMPA ? (isMPADefaultUI ? aliasSearchVueFileMPADefault : aliasSearchVueFileMPA) : aliasSearchVueFile\n }\n }\n }\n },\n async configResolved(config: any) {\n if (searchConfig.manual) {\n return\n }\n if (resolveConfig) {\n return\n }\n resolveConfig = config\n\n vitepressConfig = config.vitepress\n if (vitepressConfig) {\n dynamicRoutes = vitepressConfig.dynamicRoutes\n }\n if (!vitepressConfig) {\n return\n }\n\n if (!searchConfig.manual) {\n await cacheAllGitTimestamps(vitepressConfig.srcDir)\n }\n // 添加生成索引的方法\n const selfBuildEnd = vitepressConfig.buildEnd\n vitepressConfig.buildEnd = async (siteConfig: any) => {\n const okMark = '\\x1B[32m✓\\x1B[0m'\n console.time(`${okMark} generating pagefind Indexing...`)\n // 调用自己的\n await selfBuildEnd?.(siteConfig)\n await buildEnd(searchConfig, siteConfig)\n console.timeEnd(`${okMark} generating pagefind Indexing...`)\n }\n\n // 通过 head 添加额外的脚本注入\n const selfTransformHead = vitepressConfig.transformHead\n vitepressConfig.transformHead = async (ctx) => {\n const selfHead = (await Promise.resolve(selfTransformHead?.(ctx))) || []\n return selfHead.concat(getPagefindHead(ctx.siteData.base) as HeadConfig[])\n }\n },\n resolveId(id: string) {\n if (id === virtualModuleId) {\n return resolvedVirtualModuleId\n }\n },\n load(this, id) {\n if (id !== resolvedVirtualModuleId)\n return\n\n // 动态模块处理\n return `\n export const searchConfig = ${stringify(searchConfig)}\n `\n },\n // 添加检索的内容标识\n async transform(code, id, options) {\n if (!id.includes('.md')) {\n return code\n }\n let { searchParams, pathname, protocol } = new URL(id, 'file:')\n pathname = decodeURIComponent(pathname)\n if (!pathname.endsWith('.md')) {\n return code\n }\n\n // 兼容 动态 路由\n const isWindows = process.platform === 'win32'\n const fullPath = isWindows ? `${protocol}${pathname}` : pathname\n // @ts-expect-error\n const _dynamicRoutes = Array.isArray(dynamicRoutes) ? dynamicRoutes : (dynamicRoutes?.routes || [])\n // @ts-expect-error\n const dynamicRoute = _dynamicRoutes.find(route => fullPath.toLowerCase() === route.fullPath.toLowerCase())\n const isDynamicRoute = !!dynamicRoute\n const filepath = isDynamicRoute ? joinPath(vitepressConfig.srcDir, `/${dynamicRoute.route}`) : pathname\n const isExist = fs.existsSync(filepath)\n if (!isExist) {\n this.warn(`${id}: not parse ${filepath} please contact the author for assistance`)\n return code\n }\n // 兼容 setup lang=\"ts\"\n if (!searchParams.size || searchParams.has('lang.ts')) {\n const fileContent = await fs.promises.readFile(filepath, 'utf-8')\n const { data: frontmatter, content } = grayMatter(fileContent, {\n excerpt: true\n })\n\n // 不检索空内容页\n if (!content.trim()) {\n return code\n }\n\n // 指定标志的不检索\n if (frontmatter['pagefind-indexed'] === false) {\n return code\n }\n // 添加检索标志\n const attrs: Record<string, any> = {\n 'data-pagefind-body': true\n }\n\n if (!searchConfig.manual) {\n // 添加 frontmatter 元数据\n // 移除路径后的查询参数\n const cleanId = id.split('?')[0]\n frontmatter.date = +new Date(frontmatter.date || await getFileLastModifyTime(cleanId, vitepressConfig.cacheDir))\n attrs['data-pagefind-meta'] = `date:${frontmatter.date}`\n // 没有filter则不插入额外的 meta\n if (typeof searchConfig.filter === 'function') {\n attrs['data-pagefind-meta'] = `${meta2string(frontmatter)}`\n }\n }\n\n if (!code.includes(options?.ssr ? '_push(`' : '_createElementBlock(\"div\", null')) {\n // 兼容 setup lang=\"ts\"\n if (!code.includes(`${id}?vue&type=script&setup=true&lang.ts`)) {\n this.warn(`${options?.ssr ? 'SSR' : 'Client'} ${id} may not be a valid file, will not be indexed, please contact the author for assistance`)\n }\n return code\n }\n\n if (options?.ssr) {\n return code.replace('_push(`', `Object.assign(_attrs, ${stringify(attrs)});_push(\\``)\n }\n return code.replace('_createElementBlock(\"div\", null', `_createElementBlock(\"div\", ${stringify(attrs)}`)\n }\n return code\n }\n }\n return pluginOps\n}\n\nexport * from './type'\n\nexport { chineseSearchOptimize } from './node'\nexport { formatShowDate } from './utils/index'\n","import { execSync } from 'node:child_process'\nimport { withBase } from '@sugarat/theme-shared'\nimport type { SiteConfig } from 'vitepress'\nimport type { PagefindOption } from './type'\n\n// 需要忽略检索的内容\nconst ignoreSelectors: string[] = [\n // 侧边栏内容\n 'div.aside',\n // 标题锚点\n 'a.header-anchor'\n]\n\nexport async function buildEnd(pagefindOps: PagefindOption, siteConfig: SiteConfig) {\n const ignore = [\n ...new Set(ignoreSelectors.concat(pagefindOps?.excludeSelector || []))\n ]\n const { log } = console\n log()\n log('=== pagefind: https://pagefind.app/ ===')\n\n let command = `npx pagefind --site \"${siteConfig.outDir}\"`\n\n if (ignore.length) {\n command += ` --exclude-selectors \"${ignore.join(', ')}\"`\n }\n\n if (typeof pagefindOps.forceLanguage === 'string') {\n command += ` --force-language ${pagefindOps.forceLanguage}`\n }\n // 用户自定义指令\n if (pagefindOps.indexingCommand) {\n command = pagefindOps.indexingCommand\n }\n log(command)\n log()\n execSync(command, {\n stdio: 'inherit'\n })\n}\n\nexport function getPagefindHead(base: string) {\n return [\n [\n 'script',\n {},\n `\n const load = () => {\n import('${withBase(base || '', '/pagefind/pagefind.js')}')\n .then((module) => {\n window.__pagefind__ = module\n module.init()\n })\n .catch(() => {\n // console.log('not load /pagefind/pagefind.js')\n })\n }\n if (window.requestIdleCallback) {\n window.requestIdleCallback(load)\n } else {\n setTimeout(load, 0)\n }\n `\n ]\n ]\n}\nexport function chineseSearchOptimize(input: string) {\n const segmenter = new Intl.Segmenter('zh-CN', { granularity: 'word' })\n const result: string[] = []\n for (const it of segmenter.segment(input)) {\n if (it.isWordLike) {\n result.push(it.segment)\n }\n }\n return result.join(' ')\n}\n","export function formatDate(d: any, fmt = 'yyyy-MM-dd hh:mm:ss') {\n if (!(d instanceof Date)) {\n d = new Date(d)\n }\n const o: any = {\n 'M+': d.getMonth() + 1, // 月份\n 'd+': d.getDate(), // 日\n 'h+': d.getHours(), // 小时\n 'm+': d.getMinutes(), // 分\n 's+': d.getSeconds(), // 秒\n 'q+': Math.floor((d.getMonth() + 3) / 3), // 季度\n 'S': d.getMilliseconds() // 毫秒\n }\n if (/(y+)/.test(fmt)) {\n fmt = fmt.replace(\n RegExp.$1,\n `${d.getFullYear()}`.substr(4 - RegExp.$1.length)\n )\n }\n // eslint-disable-next-line no-restricted-syntax\n for (const k in o) {\n if (new RegExp(`(${k})`).test(fmt))\n fmt = fmt.replace(\n RegExp.$1,\n RegExp.$1.length === 1 ? o[k] : `00${o[k]}`.substr(`${o[k]}`.length)\n )\n }\n return fmt\n}\n\nexport function formatShowDate(date: Date | string, lang: string) {\n const source = +new Date(date)\n const now = +new Date()\n const diff = now - source\n const oneSeconds = 1000\n const oneMinute = oneSeconds * 60\n const oneHour = oneMinute * 60\n const oneDay = oneHour * 24\n const oneWeek = oneDay * 7\n\n const langMap = {\n 'zh-cn': {\n justNow: '刚刚',\n secondsAgo: '秒前',\n minutesAgo: '分钟前',\n hoursAgo: '小时前',\n daysAgo: '天前',\n weeksAgo: '周前'\n },\n 'en-us': {\n justNow: ' just now',\n secondsAgo: ' seconds ago',\n minutesAgo: ' minutes ago',\n hoursAgo: ' hours ago',\n daysAgo: ' days ago',\n weeksAgo: ' weeks ago'\n }\n }\n const mapValue = langMap[lang.toLowerCase() as 'zh-cn' | 'en-us'] || langMap['en-us']\n\n if (diff < 10) {\n return mapValue.justNow\n }\n if (diff < oneMinute) {\n return `${Math.floor(diff / oneSeconds)}${mapValue.secondsAgo}`\n }\n if (diff < oneHour) {\n return `${Math.floor(diff / oneMinute)}${mapValue.minutesAgo}`\n }\n if (diff < oneDay) {\n return `${Math.floor(diff / oneHour)}${mapValue.hoursAgo}`\n }\n if (diff < oneWeek) {\n return `${Math.floor(diff / oneDay)}${mapValue.daysAgo}`\n }\n\n return formatDate(new Date(date), 'yyyy-MM-dd')\n}\n"],"mappings":"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","names":[]}