UNPKG

vite-plugin-mdx

Version:
105 lines 4.79 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.viteMdxTransclusion = void 0; const vite_1 = require("vite"); const quick_lru_1 = __importDefault(require("@alloc/quick-lru")); const path_1 = require("path"); const fs_1 = __importDefault(require("fs")); const common_1 = require("../common"); const remarkTransclusion_1 = require("./remarkTransclusion"); const createMdxAstCompiler_1 = require("./createMdxAstCompiler"); const ImportMap_1 = require("./ImportMap"); /** * 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. * */ 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_1.ImportMap(); astCache = new quick_lru_1.default({ maxAge: 30 * 6e4, 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); importers.forEach((importer) => { 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((0, remarkTransclusion_1.remarkTransclusion)({ astCache, importMap, resolve: (id, importer) => __awaiter(this, void 0, void 0, function* () { const resolved = yield this.resolve(id, importer); if (resolved) { id = (0, vite_1.normalizePath)(resolved.id); // Ensure files outside the Vite project root are watched. if (watcher && (0, path_1.isAbsolute)(id) && !id.startsWith(root + '/')) { watcher.add(id); } return id; } logger.warn(`Failed to resolve "${id}" imported by "${importer}"`); }), readFile: (filePath) => fs_1.default.promises.readFile(filePath, 'utf8'), getCompiler: (filePath) => (0, createMdxAstCompiler_1.createMdxAstCompiler)(root, (0, common_1.mergeArrays)(globalMdxOptions.remarkPlugins, getMdxOptions === null || getMdxOptions === void 0 ? void 0 : getMdxOptions(filePath).remarkPlugins)) })); } }; return plugin; } exports.viteMdxTransclusion = viteMdxTransclusion; //# sourceMappingURL=index.js.map