Skip to content

Fix injectRoute #7943

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 12 commits into from
Aug 7, 2023
5 changes: 5 additions & 0 deletions .changeset/stupid-pants-press.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'astro': patch
---

Ensure that injected routes from `node_modules` are properly detected
15 changes: 10 additions & 5 deletions packages/astro/src/@types/astro.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<typeof AstroConfigSchema> {
// Public:
// This is a more detailed type than zod validation gives us.
Expand Down Expand Up @@ -1414,6 +1418,7 @@ export interface AstroSettings {
config: AstroConfig;
adapter: AstroAdapter | undefined;
injectedRoutes: InjectedRoute[];
resolvedInjectedRoutes: ResolvedInjectedRoute[];
pageExtensions: string[];
contentEntryTypes: ContentEntryType[];
dataEntryTypes: DataEntryType[];
Expand Down
1 change: 1 addition & 0 deletions packages/astro/src/core/config/settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ export function createBaseSettings(config: AstroConfig): AstroSettings {

adapter: undefined,
injectedRoutes: [],
resolvedInjectedRoutes: [],
pageExtensions: ['.astro', '.html', ...SUPPORTED_MARKDOWN_FILE_EXTENSIONS],
contentEntryTypes: [markdownContentEntryType],
dataEntryTypes: [
Expand Down
5 changes: 3 additions & 2 deletions packages/astro/src/core/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
20 changes: 19 additions & 1 deletion packages/astro/src/vite-plugin-integrations-container/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { Plugin as VitePlugin } from 'vite';
import { normalizePath, type Plugin as VitePlugin } from 'vite';
import type { AstroSettings } from '../@types/astro.js';
import type { LogOptions } from '../core/logger/core.js';
import { runHookServerSetup } from '../integrations/index.js';
Expand All @@ -11,10 +11,28 @@ export default function astroIntegrationsContainerPlugin({
settings: AstroSettings;
logging: LogOptions;
}): VitePlugin {
let hasResolvedInjectedRoutes = false;
return {
name: 'astro:integration-container',
configureServer(server) {
runHookServerSetup({ config: settings.config, server, logging });
},
// Run `load` hook once just to get access to `PluginContext.resolve`
// which allows us to resolve each injectedRoute entryPoint to a real file URL on disk
async load() {
if (hasResolvedInjectedRoutes) return;
// Ensure the injectedRoutes are all resolved to their final paths through Rollup
settings.resolvedInjectedRoutes = await Promise.all(settings.injectedRoutes.map(async injectedRoute => {
let resolvedEntryPoint: URL | undefined;
try {
const resolvedId = await this.resolve(injectedRoute.entryPoint).then(res => res?.id ?? injectedRoute.entryPoint)
const filename = normalizePath(resolvedId);
resolvedEntryPoint = new URL(`file://${filename}`);
} catch {}
return { ...injectedRoute, resolvedEntryPoint }
}))
hasResolvedInjectedRoutes = true;
return;
},
};
}