UNPKG

@brendonovich/kobalte__solidbase

Version:

Fully featured, fully customisable static site generation for SolidStart

91 lines 3.66 kB
import fs from "node:fs"; import { isAbsolute } from "node:path"; import LRUCache from "@alloc/quick-lru"; import { normalizePath, } from "vite"; import { mergeArrays } from "../common.js"; import { ImportMap } from "./ImportMap.js"; import { createMdxAstCompiler } from "./createMdxAstCompiler.js"; import { remarkTransclusion } from "./remarkTransclusion.js"; /** * With transclusion enabled, an `.mdx` file can import other `.mdx` or `.md` * files without an import specifier. * * import "../other.mdx" * * The file extension is required. * * The imported file is inlined into its importer, but the imported file can * still have its own Remark plugins. * */ export function viteMdxTransclusion(globalMdxOptions, getMdxOptions) { /** * To recompile an importer when its transcluded files are changed, * we need to track the relationships between them. */ let importMap; /** * To avoid redundant parsing and processing, we cache the MDX syntax trees * of transcluded files to serve as a fast path when an importer is recompiled. */ let astCache; let resolvedConfig; let watcher; const plugin = { name: "mdx:transclusion", configResolved(config) { resolvedConfig = config; }, configureServer(server) { watcher = server.watcher; importMap = new ImportMap(); astCache = new LRUCache({ maxAge: 30 * 6e4, // 30 minutes maxSize: 100, }); // When a transcluded file changes, recompile its importers. // Also, clean up the import map when an importer is deleted. watcher.on("all", (event, filePath) => { if (/\.mdx?$/.test(filePath)) { if (event === "unlink") { importMap.deleteImporter(filePath); } const importers = importMap.importers.get(filePath); if (importers) { astCache.delete(filePath); for (const importer of importers) { // @ts-ignore watcher.emit("change", importer); } } } }); }, buildStart() { if (!resolvedConfig) throw new Error("vite-plugin-mdx: configResolved hook should be called before calling buildStart hook"); const { root, logger } = resolvedConfig; globalMdxOptions.remarkPlugins.push(remarkTransclusion({ astCache, importMap, resolve: async (_id, importer) => { let id = _id; const resolved = await this.resolve(id, importer); if (resolved) { id = normalizePath(resolved.id); // Ensure files outside the Vite project root are watched. if (watcher && isAbsolute(id) && !id.startsWith(`${root}/`)) { watcher.add(id); } return id; } logger.warn(`Failed to resolve "${id}" imported by "${importer}"`); }, readFile: (filePath) => fs.promises.readFile(filePath, "utf8"), getCompiler: (filePath) => createMdxAstCompiler(root, mergeArrays(globalMdxOptions.remarkPlugins, getMdxOptions?.(filePath).remarkPlugins)), })); }, }; return plugin; } //# sourceMappingURL=index.js.map