import react, { reactCompilerPreset } from "@vitejs/plugin-react" import babel from "@rolldown/plugin-babel" import tailwindcss from "@tailwindcss/vite" import { icones } from "@icones/vite" import { readFile } from "node:fs/promises" import { fileURLToPath } from "node:url" import { defineConfig, type Plugin } from "vite" import satteri from "vite-plugin-satteri" const packagesDirectory = fileURLToPath(new URL("../packages", import.meta.url)) /** * Vite 默认监听 docs 根目录。现有的外部 MDX 会作为模块被监听,但新建 package * 或新建 MDX 文件在首次进入模块图之前不会触发 import.meta.glob 重新计算。 */ function watchPackageDocs(): Plugin { return { name: "watch-package-docs", configureServer(server) { server.watcher.add(packagesDirectory) }, } } function loadDocSearchSources(): Plugin { const suffix = "?docs-search-raw" const virtualPrefix = "\0docs-search-raw:" return { name: "load-doc-search-sources", enforce: "pre", async resolveId(id, importer) { if (!id.endsWith(suffix)) return const sourceId = id.slice(0, -suffix.length) const resolved = await this.resolve(sourceId, importer, { skipSelf: true, }) const filename = resolved?.id ?? sourceId return `${virtualPrefix}${encodeURIComponent(filename)}.js` }, async load(id) { if (!id.startsWith(virtualPrefix)) return const sourceId = decodeURIComponent( id.slice(virtualPrefix.length, -".js".length) ) const filename = sourceId.startsWith("/@fs/") ? sourceId.slice("/@fs".length) : sourceId this.addWatchFile(filename) const source = await readFile(filename, "utf8") return `export default ${JSON.stringify(source)}` }, } } // https://vite.dev/config/ export default defineConfig({ plugins: [ watchPackageDocs(), loadDocSearchSources(), satteri({ features: { frontmatter: true, gfm: true, headingAttributes: true, }, mdx: { jsxImportSource: "react", }, }), tailwindcss(), icones({ mode: "symbol", emitData: false, }), react(), babel({ presets: [reactCompilerPreset()] }), ], })