From 883710d21c5193677e2358b76549489b5f33b946 Mon Sep 17 00:00:00 2001 From: bholmesdev Date: Tue, 30 Aug 2022 10:45:51 -0400 Subject: [PATCH] fix: invalidate mod before crawling graph --- packages/astro/src/core/render/dev/vite.ts | 74 +++++++++++----------- 1 file changed, 38 insertions(+), 36 deletions(-) diff --git a/packages/astro/src/core/render/dev/vite.ts b/packages/astro/src/core/render/dev/vite.ts index 332607ff8..e05ac0ee2 100644 --- a/packages/astro/src/core/render/dev/vite.ts +++ b/packages/astro/src/core/render/dev/vite.ts @@ -5,54 +5,56 @@ import { STYLE_EXTENSIONS } from '../util.js'; const STRIP_QUERY_PARAMS_REGEX = /\?.*$/; +/** + * List of file extensions signalling we can (and should) SSR ahead-of-time + * See usage below + */ +const fileExtensionsToSSR = new Set(['.astro', '.md']); + /** recursively crawl the module graph to get all style files imported by parent id */ export async function* crawlGraph( viteServer: vite.ViteDevServer, _id: string, - isFile: boolean, + isRootFile: boolean, scanned = new Set() ): AsyncGenerator { const id = unwrapId(_id); const importedModules = new Set(); - const moduleEntriesForId = isFile - ? // If isFile = true, then you are at the root of your module import tree. - // The `id` arg is a filepath, so use `getModulesByFile()` to collect all - // nodes for that file. This is needed for advanced imports like Tailwind. - viteServer.moduleGraph.getModulesByFile(id) ?? new Set() - : // Otherwise, you are following an import in the module import tree. - // You are safe to use getModuleById() here because Vite has already - // resolved the correct `id` for you, by creating the import you followed here. - new Set([viteServer.moduleGraph.getModuleById(id)]); + if (isRootFile) { + // The module graph may be out-of-date when crawling + // ex. Tailwind PostCSS process takes time + // Use "onFileChange" to invalidate cache + viteServer.moduleGraph.onFileChange(id); + } + const entry = viteServer.moduleGraph.getModuleById(id); - // Collect all imported modules for the module(s). - for (const entry of moduleEntriesForId) { - // Handle this in case an module entries weren't found for ID - // This seems possible with some virtual IDs (ex: `astro:markdown/*.md`) - if (!entry) { - continue; - } - if (id === entry.id) { - scanned.add(id); - const entryIsStyle = STYLE_EXTENSIONS.has(npath.extname(id)); - for (const importedModule of entry.importedModules) { - // some dynamically imported modules are *not* server rendered in time - // to only SSR modules that we can safely transform, we check against - // a list of file extensions based on our built-in vite plugins - if (importedModule.id) { - // Strip special query params like "?content". - // NOTE: Cannot use `new URL()` here because not all IDs will be valid paths. - // For example, `virtual:image-loader` if you don't have the plugin installed. - const importedModulePathname = importedModule.id.replace(STRIP_QUERY_PARAMS_REGEX, ''); - // If the entry is a style, skip any modules that are not also styles. - // Tools like Tailwind might add HMR dependencies as `importedModules` - // but we should skip them--they aren't really imported. Without this, - // every hoisted script in the project is added to every page! - if (entryIsStyle && !STYLE_EXTENSIONS.has(npath.extname(importedModulePathname))) { - continue; + if (id === entry?.id) { + scanned.add(id); + const entryIsStyle = STYLE_EXTENSIONS.has(npath.extname(id)); + for (const importedModule of entry.importedModules) { + // some dynamically imported modules are *not* server rendered in time + // to only SSR modules that we can safely transform, we check against + // a list of file extensions based on our built-in vite plugins + if (importedModule.id) { + // Strip special query params like "?content". + // NOTE: Cannot use `new URL()` here because not all IDs will be valid paths. + // For example, `virtual:image-loader` if you don't have the plugin installed. + const importedModulePathname = importedModule.id.replace(STRIP_QUERY_PARAMS_REGEX, ''); + // If the entry is a style, skip any modules that are not also styles. + // Tools like Tailwind might add HMR dependencies as `importedModules` + // but we should skip them--they aren't really imported. Without this, + // every hoisted script in the project is added to every page! + if (entryIsStyle && !STYLE_EXTENSIONS.has(npath.extname(importedModulePathname))) { + continue; + } + if (fileExtensionsToSSR.has(npath.extname(importedModulePathname))) { + const mod = viteServer.moduleGraph.getModuleById(importedModule.id); + if (!mod?.ssrModule) { + await viteServer.ssrLoadModule(importedModule.id); } } - importedModules.add(importedModule); } + importedModules.add(importedModule); } }