diff --git a/.changeset/stupid-pants-press.md b/.changeset/stupid-pants-press.md new file mode 100644 index 000000000000..c5807d9923ef --- /dev/null +++ b/.changeset/stupid-pants-press.md @@ -0,0 +1,5 @@ +--- +'astro': patch +--- + +Ensure that injected routes from `node_modules` are properly detected diff --git a/packages/astro/src/@types/astro.ts b/packages/astro/src/@types/astro.ts index 1c7152fec261..6bcb011bb274 100644 --- a/packages/astro/src/@types/astro.ts +++ b/packages/astro/src/@types/astro.ts @@ -1316,16 +1316,20 @@ export interface AstroUserConfig { */ export type InjectedScriptStage = 'before-hydration' | 'head-inline' | 'page' | 'page-ssr'; -/** - * Resolved Astro Config - * Config with user settings along with all defaults filled in. - */ - export interface InjectedRoute { pattern: string; entryPoint: string; prerender?: boolean; } + +export interface ResolvedInjectedRoute extends InjectedRoute { + resolvedEntryPoint?: URL; +} + +/** + * Resolved Astro Config + * Config with user settings along with all defaults filled in. + */ export interface AstroConfig extends z.output { // Public: // This is a more detailed type than zod validation gives us. @@ -1414,6 +1418,7 @@ export interface AstroSettings { config: AstroConfig; adapter: AstroAdapter | undefined; injectedRoutes: InjectedRoute[]; + resolvedInjectedRoutes: ResolvedInjectedRoute[]; pageExtensions: string[]; contentEntryTypes: ContentEntryType[]; dataEntryTypes: DataEntryType[]; diff --git a/packages/astro/src/core/config/settings.ts b/packages/astro/src/core/config/settings.ts index b15961e5076c..c0274f60293f 100644 --- a/packages/astro/src/core/config/settings.ts +++ b/packages/astro/src/core/config/settings.ts @@ -21,6 +21,7 @@ export function createBaseSettings(config: AstroConfig): AstroSettings { adapter: undefined, injectedRoutes: [], + resolvedInjectedRoutes: [], pageExtensions: ['.astro', '.html', ...SUPPORTED_MARKDOWN_FILE_EXTENSIONS], contentEntryTypes: [markdownContentEntryType], dataEntryTypes: [ diff --git a/packages/astro/src/core/util.ts b/packages/astro/src/core/util.ts index c3f537243183..ff41a5ed6d6a 100644 --- a/packages/astro/src/core/util.ts +++ b/packages/astro/src/core/util.ts @@ -113,8 +113,9 @@ function isInPagesDir(file: URL, config: AstroConfig): boolean { } function isInjectedRoute(file: URL, settings: AstroSettings) { - for (const route of settings.injectedRoutes) { - if (file.toString().endsWith(route.entryPoint)) return true; + let fileURL = file.toString(); + for (const route of settings.resolvedInjectedRoutes) { + if (route.resolvedEntryPoint && fileURL === route.resolvedEntryPoint.toString()) return true; } return false; } diff --git a/packages/astro/src/vite-plugin-integrations-container/index.ts b/packages/astro/src/vite-plugin-integrations-container/index.ts index 0169a6f71560..54c4d5ee3431 100644 --- a/packages/astro/src/vite-plugin-integrations-container/index.ts +++ b/packages/astro/src/vite-plugin-integrations-container/index.ts @@ -1,6 +1,9 @@ import type { Plugin as VitePlugin } from 'vite'; -import type { AstroSettings } from '../@types/astro.js'; +import type { PluginContext } from 'rollup'; +import type { AstroSettings, InjectedRoute, ResolvedInjectedRoute } from '../@types/astro.js'; import type { LogOptions } from '../core/logger/core.js'; + +import { normalizePath } from 'vite'; import { runHookServerSetup } from '../integrations/index.js'; /** Connect Astro integrations into Vite, as needed. */ @@ -16,5 +19,19 @@ export default function astroIntegrationsContainerPlugin({ configureServer(server) { runHookServerSetup({ config: settings.config, server, logging }); }, + async buildStart() { + // Ensure the injectedRoutes are all resolved to their final paths through Rollup + settings.resolvedInjectedRoutes = await Promise.all(settings.injectedRoutes.map(route => resolveEntryPoint.call(this, route))) + }, }; } + +async function resolveEntryPoint(this: PluginContext, route: InjectedRoute): Promise { + const resolvedId = await this.resolve(route.entryPoint) + .then(res => res?.id) + .catch(() => undefined); + if (!resolvedId) return route; + + const resolvedEntryPoint = new URL(`file://${normalizePath(resolvedId)}`); + return { ...route, resolvedEntryPoint }; +}