From cc50ee68d436c97d6548a225e41c11f5d95654b8 Mon Sep 17 00:00:00 2001 From: bholmesdev Date: Wed, 26 Apr 2023 16:06:02 -0400 Subject: [PATCH] refactor: generated `.json` to in-memory map --- .../src/content/template/virtual-mod.mjs | 4 ++- packages/astro/src/content/types-generator.ts | 19 ++++++----- packages/astro/src/content/utils.ts | 7 ++-- .../vite-plugin-content-virtual-mod.ts | 33 +++++++++++++------ 4 files changed, 39 insertions(+), 24 deletions(-) diff --git a/packages/astro/src/content/template/virtual-mod.mjs b/packages/astro/src/content/template/virtual-mod.mjs index e68e5bc48..a649804ce 100644 --- a/packages/astro/src/content/template/virtual-mod.mjs +++ b/packages/astro/src/content/template/virtual-mod.mjs @@ -28,9 +28,11 @@ const collectionToEntryMap = createCollectionToGlobResultMap({ contentDir, }); +let lookupMap = {}; +/* @@LOOKUP_MAP_ASSIGNMENT@@ */ + function createGlobLookup(glob) { return async (collection, lookupId) => { - const { default: lookupMap } = await import('@@LOOKUP_MAP_PATH@@'); const filePath = lookupMap[collection]?.[lookupId]; if (!filePath) return undefined; diff --git a/packages/astro/src/content/types-generator.ts b/packages/astro/src/content/types-generator.ts index 2ad4f2f9e..da0505ca9 100644 --- a/packages/astro/src/content/types-generator.ts +++ b/packages/astro/src/content/types-generator.ts @@ -8,7 +8,7 @@ import type { AstroSettings, ContentEntryType } from '../@types/astro.js'; import { AstroError, AstroErrorData } from '../core/errors/index.js'; import { info, warn, type LogOptions } from '../core/logger/core.js'; import { isRelativePath } from '../core/path.js'; -import { CONTENT_TYPES_FILE } from './consts.js'; +import { CONTENT_TYPES_FILE, VIRTUAL_MODULE_ID } from './consts.js'; import { getContentPaths, getEntryInfo, @@ -21,7 +21,6 @@ import { type ContentObservable, type ContentPaths, type EntryInfo, - updateLookupMaps, getContentEntryConfigByExtMap, } from './utils.js'; @@ -280,12 +279,7 @@ export async function createContentTypesGenerator({ contentConfig: observable.status === 'loaded' ? observable.config : undefined, contentEntryTypes: settings.contentEntryTypes, }); - await updateLookupMaps({ - contentEntryConfigByExt, - contentPaths, - root: settings.config.root, - fs, - }); + invalidateVirtualMod(viteServer); if (observable.status === 'loaded' && ['info', 'warn'].includes(logLevel)) { warnNonexistentCollections({ logging, @@ -298,6 +292,15 @@ export async function createContentTypesGenerator({ return { init, queueEvent }; } +// The virtual module contains a lookup map from slugs to content imports. +// Invalidate whenever content types change. +function invalidateVirtualMod(viteServer: ViteDevServer) { + const virtualMod = viteServer.moduleGraph.getModuleById('\0' + VIRTUAL_MODULE_ID); + if (!virtualMod) return; + + viteServer.moduleGraph.invalidateModule(virtualMod); +} + function addCollection(contentMap: ContentTypes, collectionKey: string) { contentMap[collectionKey] = {}; } diff --git a/packages/astro/src/content/utils.ts b/packages/astro/src/content/utils.ts index 91c6f1a77..77f6056e0 100644 --- a/packages/astro/src/content/utils.ts +++ b/packages/astro/src/content/utils.ts @@ -388,7 +388,7 @@ function search(fs: typeof fsMod, srcDir: URL) { return { exists: false, url: paths[0] }; } -export async function updateLookupMaps({ +export async function getStringifiedLookupMap({ contentPaths, contentEntryConfigByExt, root, @@ -434,10 +434,7 @@ export async function updateLookupMaps({ filePathByLookupId[collection][slug] = rootRelativePath(root, filePath); } - await fs.promises.writeFile( - new URL('lookup-map.json', contentPaths.cacheDir), - JSON.stringify(filePathByLookupId, null, 2) - ); + return JSON.stringify(filePathByLookupId); } export function getExtGlob(exts: string[]) { diff --git a/packages/astro/src/content/vite-plugin-content-virtual-mod.ts b/packages/astro/src/content/vite-plugin-content-virtual-mod.ts index cf8f03fa7..934245183 100644 --- a/packages/astro/src/content/vite-plugin-content-virtual-mod.ts +++ b/packages/astro/src/content/vite-plugin-content-virtual-mod.ts @@ -2,7 +2,13 @@ import fsMod from 'node:fs'; import type { Plugin } from 'vite'; import type { AstroSettings } from '../@types/astro.js'; import { VIRTUAL_MODULE_ID } from './consts.js'; -import { getContentEntryExts, getContentPaths, getExtGlob } from './utils.js'; +import { + getContentEntryConfigByExtMap, + getContentEntryExts, + getContentPaths, + getExtGlob, + getStringifiedLookupMap, +} from './utils.js'; import { rootRelativePath } from '../core/util.js'; interface AstroContentVirtualModPluginParams { @@ -14,17 +20,14 @@ export function astroContentVirtualModPlugin({ }: AstroContentVirtualModPluginParams): Plugin { const contentPaths = getContentPaths(settings.config); const relContentDir = rootRelativePath(settings.config.root, contentPaths.contentDir); - const contentEntryExts = getContentEntryExts(settings); - const extGlob = - contentEntryExts.length === 1 - ? // Wrapping {...} breaks when there is only one extension - contentEntryExts[0] - : `{${contentEntryExts.join(',')}}`; + const contentEntryConfigByExt = getContentEntryConfigByExtMap(settings); + const contentEntryExts = [...contentEntryConfigByExt.keys()]; + + const extGlob = getExtGlob(contentEntryExts); const entryGlob = `${relContentDir}**/*${extGlob}`; const virtualModContents = fsMod .readFileSync(contentPaths.virtualModTemplate, 'utf-8') - .replace('@@LOOKUP_MAP_PATH@@', new URL('lookup-map.json', contentPaths.cacheDir).pathname) .replace('@@CONTENT_DIR@@', relContentDir) .replace('@@ENTRY_GLOB_PATH@@', entryGlob) .replace('@@RENDER_ENTRY_GLOB_PATH@@', entryGlob); @@ -39,10 +42,20 @@ export function astroContentVirtualModPlugin({ return astroContentVirtualModuleId; } }, - load(id) { + async load(id) { + const stringifiedLookupMap = await getStringifiedLookupMap({ + fs: fsMod, + contentPaths, + contentEntryConfigByExt, + root: settings.config.root, + }); + if (id === astroContentVirtualModuleId) { return { - code: virtualModContents, + code: virtualModContents.replace( + '/* @@LOOKUP_MAP_ASSIGNMENT@@ */', + `lookupMap = ${stringifiedLookupMap};` + ), }; } },