diff --git a/.changeset/cool-birds-prove.md b/.changeset/cool-birds-prove.md new file mode 100644 index 0000000000..70c190b892 --- /dev/null +++ b/.changeset/cool-birds-prove.md @@ -0,0 +1,5 @@ +--- +'astro': patch +--- + +Fix missing styles for Markdoc files in development diff --git a/packages/astro/src/core/render/dev/vite.ts b/packages/astro/src/core/render/dev/vite.ts index b3efb34bb4..39df7d269c 100644 --- a/packages/astro/src/core/render/dev/vite.ts +++ b/packages/astro/src/core/render/dev/vite.ts @@ -46,44 +46,45 @@ export async function* crawlGraph( const entryIsStyle = isCSSRequest(id); for (const importedModule of entry.importedModules) { - // A propagation stopping point is a module with the ?astroPropagatedAssets flag. - // When we encounter one of these modules we don't want to continue traversing. - let isPropagationStoppingPoint = false; + if (!importedModule.id) continue; + // 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 && !isCSSRequest(importedModulePathname)) { - continue; - } - const isFileTypeNeedingSSR = fileExtensionsToSSR.has( - npath.extname(importedModulePathname) - ); - isPropagationStoppingPoint = ASTRO_PROPAGATED_ASSET_REGEX.test(importedModule.id); - if ( - isFileTypeNeedingSSR && - // Should not SSR a module with ?astroPropagatedAssets - !isPropagationStoppingPoint - ) { - const mod = loader.getModuleById(importedModule.id); - if (!mod?.ssrModule) { - try { - await loader.import(importedModule.id); - } catch { - /** Likely an out-of-date module entry! Silently continue. */ - } + + // 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 && !isCSSRequest(importedModulePathname)) { + continue; + } + + const isFileTypeNeedingSSR = fileExtensionsToSSR.has(npath.extname(importedModulePathname)); + // A propagation stopping point is a module with the ?astroPropagatedAssets flag. + // When we encounter one of these modules we don't want to continue traversing. + const isPropagationStoppingPoint = ASTRO_PROPAGATED_ASSET_REGEX.test(importedModule.id); + if ( + isFileTypeNeedingSSR && + // Should not SSR a module with ?astroPropagatedAssets + !isPropagationStoppingPoint + ) { + const mod = loader.getModuleById(importedModule.id); + if (!mod?.ssrModule) { + try { + await loader.import(importedModule.id); + } catch { + /** Likely an out-of-date module entry! Silently continue. */ } } } - if (urlDeps.includes(urlId(importedModule.url)) && !isPropagationStoppingPoint) { + + // Make sure the `importedModule` traversed is explicitly imported by the user, and not by HMR + if (urlDeps.includes(importedModule.url) && !isPropagationStoppingPoint) { importedModules.add(importedModule); } } @@ -102,18 +103,10 @@ export async function* crawlGraph( } } -// Virtual modules URL should start with /@id/ but do not -function urlId(url: string) { - if (url.startsWith('astro:scripts')) { - return '/@id/' + url; - } - return url; -} - function getDepsFromEntry(entry: ModuleNode) { let deps = entry.ssrTransformResult?.deps ?? []; if (entry.ssrTransformResult?.dynamicDeps) { - return deps.concat(entry.ssrTransformResult.dynamicDeps); + deps = deps.concat(entry.ssrTransformResult.dynamicDeps); } - return deps; + return deps.map((dep) => unwrapId(dep)); } diff --git a/packages/astro/src/core/util.ts b/packages/astro/src/core/util.ts index 122bf73969..2529e89c24 100644 --- a/packages/astro/src/core/util.ts +++ b/packages/astro/src/core/util.ts @@ -93,11 +93,14 @@ export function viteID(filePath: URL): string { } export const VALID_ID_PREFIX = `/@id/`; +export const NULL_BYTE_PLACEHOLDER = `__x00__`; -// Strip valid id prefix. This is prepended to resolved Ids that are -// not valid browser import specifiers by the importAnalysis plugin. +// Strip valid id prefix and replace null byte placeholder. Both are prepended to resolved ids +// as they are not valid browser import specifiers (by the Vite's importAnalysis plugin) export function unwrapId(id: string): string { - return id.startsWith(VALID_ID_PREFIX) ? id.slice(VALID_ID_PREFIX.length) : id; + return id.startsWith(VALID_ID_PREFIX) + ? id.slice(VALID_ID_PREFIX.length).replace(NULL_BYTE_PLACEHOLDER, '\0') + : id; } export function resolvePages(config: AstroConfig) {