0
Fork 0
mirror of https://github.com/withastro/astro.git synced 2025-01-13 22:11:20 -05:00

feat: accept URL for entry points (#12226)

Co-authored-by: Bjorn Lu <bjornlu.dev@gmail.com>
This commit is contained in:
Emanuele Stoppa 2024-10-15 15:07:18 +01:00 committed by GitHub
parent a393154906
commit 51d13e2f6c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
19 changed files with 74 additions and 21 deletions

View file

@ -0,0 +1,14 @@
---
'astro': minor
---
The following renderer fields and integration fields now accept `URL` as a type:
**Renderers**:
- `AstroRenderer.clientEntrpoint`
- `AstroRenderer.serverEntrypoint`
**Integrations**:
- `InjectedRoute.entrypoint`
- `AstroIntegrationMiddleware.entrypoint`
- `DevToolbarAppEntry.entrypoint`

View file

@ -4,7 +4,11 @@ import { build } from 'esbuild';
/**
* Build a client directive entrypoint into code that can directly run in a `<script>` tag.
*/
export async function buildClientDirectiveEntrypoint(name: string, entrypoint: string, root: URL) {
export async function buildClientDirectiveEntrypoint(
name: string,
entrypoint: string | URL,
root: URL,
) {
const stringifiedName = JSON.stringify(name);
const stringifiedEntrypoint = JSON.stringify(entrypoint);

View file

@ -67,7 +67,7 @@ export default async function preview(inlineConfig: AstroInlineConfig): Promise<
// preview entrypoint of the integration package, relative to the user's project root.
const require = createRequire(settings.config.root);
const previewEntrypointUrl = pathToFileURL(
require.resolve(settings.adapter.previewEntrypoint),
require.resolve(settings.adapter.previewEntrypoint.toString()),
).href;
const previewModule = (await import(previewEntrypointUrl)) as Partial<PreviewModule>;

View file

@ -6,7 +6,7 @@ export async function loadRenderer(
renderer: AstroRenderer,
moduleLoader: ModuleLoader,
): Promise<SSRLoadedRenderer | undefined> {
const mod = await moduleLoader.import(renderer.serverEntrypoint);
const mod = await moduleLoader.import(renderer.serverEntrypoint.toString());
if (typeof mod.default !== 'undefined') {
return {
...renderer,

View file

@ -281,7 +281,7 @@ function createInjectedRoutes({ settings, cwd }: CreateRouteManifestParams): Rou
for (const injectedRoute of settings.injectedRoutes) {
const { pattern: name, entrypoint, prerender: prerenderInjected } = injectedRoute;
const { resolved, component } = resolveInjectedRoute(entrypoint, config.root, cwd);
const { resolved, component } = resolveInjectedRoute(entrypoint.toString(), config.root, cwd);
const segments = removeLeadingForwardSlash(name)
.split(path.posix.sep)

View file

@ -236,7 +236,9 @@ export async function runHookConfigSetup({
order === 'pre' ? 'before' : 'after'
} any application middleware you define.`,
);
updatedSettings.middlewares[order].push(entrypoint);
updatedSettings.middlewares[order].push(
typeof entrypoint === 'string' ? entrypoint : fileURLToPath(entrypoint),
);
},
createCodegenDir: () => {
const codegenDir = new URL(normalizeCodegenDir(integration.name), settings.dotAstroDir);

View file

@ -158,7 +158,9 @@ export async function generateHydrateScript(
// Add renderer url
if (renderer.clientEntrypoint) {
island.props['component-export'] = componentExport.value;
island.props['renderer-url'] = await result.resolve(decodeURI(renderer.clientEntrypoint));
island.props['renderer-url'] = await result.resolve(
decodeURI(renderer.clientEntrypoint.toString()),
);
island.props['props'] = escapeHTML(serializeProps(props, metadata));
}

View file

@ -66,9 +66,9 @@ export default function astroDevToolbar({ settings, logger }: AstroPluginOptions
`safeLoadPlugin(${JSON.stringify(
plugin,
)}, async () => (await import(${JSON.stringify(
typeof plugin === 'string' ? plugin : plugin.entrypoint,
typeof plugin === 'string' ? plugin : plugin.entrypoint.toString(),
)})).default, ${JSON.stringify(
typeof plugin === 'string' ? plugin : plugin.entrypoint,
typeof plugin === 'string' ? plugin : plugin.entrypoint.toString(),
)})`,
)
.join(',')}]));

View file

@ -49,16 +49,16 @@ export type ClientDirective = (
export interface ClientDirectiveConfig {
name: string;
entrypoint: string;
entrypoint: string | URL;
}
export interface AstroRenderer {
/** Name of the renderer. */
name: string;
/** Import entrypoint for the client/browser renderer. */
clientEntrypoint?: string;
clientEntrypoint?: string | URL;
/** Import entrypoint for the server/build/ssr renderer. */
serverEntrypoint: string;
serverEntrypoint: string | URL;
}
export type AdapterSupportsKind =
@ -84,8 +84,8 @@ export interface AstroAdapterFeatures {
export interface AstroAdapter {
name: string;
serverEntrypoint?: string;
previewEntrypoint?: string;
serverEntrypoint?: string | URL;
previewEntrypoint?: string | URL;
exports?: string[];
args?: any;
adapterFeatures?: AstroAdapterFeatures;
@ -140,7 +140,7 @@ export type InjectedScriptStage = 'before-hydration' | 'head-inline' | 'page' |
export interface InjectedRoute {
pattern: string;
entrypoint: string;
entrypoint: string | URL;
prerender?: boolean;
}
@ -155,7 +155,7 @@ export interface InjectedType {
export type AstroIntegrationMiddleware = {
order: 'pre' | 'post';
entrypoint: string;
entrypoint: string | URL;
};
export type HookParameters<

View file

@ -45,7 +45,7 @@ type DevToolbarAppMeta = {
// The param passed to `addDevToolbarApp` in the integration
export type DevToolbarAppEntry = DevToolbarAppMeta & {
entrypoint: string;
entrypoint: string | URL;
};
// Public API for the dev toolbar

View file

@ -18,7 +18,7 @@ import type { SSRLoadedRenderer } from '../types/public/internal.js';
export async function loadRenderers(renderers: AstroRenderer[]) {
const loadedRenderers = await Promise.all(
renderers.map(async (renderer) => {
const mod = await import(renderer.serverEntrypoint);
const mod = await import(renderer.serverEntrypoint.toString());
if (typeof mod.default !== 'undefined') {
return {
...renderer,

View file

@ -35,7 +35,7 @@ async function resolveEntryPoint(
this: PluginContext,
route: InjectedRoute,
): Promise<ResolvedInjectedRoute> {
const resolvedId = await this.resolve(route.entrypoint)
const resolvedId = await this.resolve(route.entrypoint.toString())
.then((res) => res?.id)
.catch(() => undefined);
if (!resolvedId) return route;

View file

@ -16,6 +16,11 @@ export default defineConfig({
entrypoint: fileURLToPath(new URL('./integration-middleware-post.js', import.meta.url)),
order: 'post'
});
addMiddleware({
entrypoint: new URL('./integration-middleware-url.js', import.meta.url),
order: 'post'
});
}
}
}

View file

@ -0,0 +1,9 @@
import { defineMiddleware } from 'astro:middleware';
export const onRequest = defineMiddleware((context, next) => {
if (context.url.pathname === '/url') {
return Response.json({ post: 'works' });
}
return next();
});

View file

@ -7,7 +7,7 @@ export default function() {
addRenderer({
name: 'renderer-two',
clientEntrypoint: null,
serverEntrypoint: '@test/astro-renderer-two/server.mjs',
serverEntrypoint: new URL('server.mjs', import.meta.url),
});
}
}

View file

@ -6,7 +6,7 @@ export default defineConfig({
{
name: 'astropi',
hooks: {
'astro:config:setup': async ({ injectRoute }) => {
'astro:config:setup': async ({ injectRoute, config }) => {
injectRoute({
pattern: `/injected-a`,
entrypoint: './src/to-inject.astro',
@ -27,6 +27,11 @@ export default defineConfig({
entrypoint: './src/[id].astro',
prerender: true,
});
injectRoute({
pattern: `/dynamic-c/[id]`,
entrypoint: new URL('./[id].astro', config.srcDir),
prerender: true,
})
},
},
},

View file

@ -128,6 +128,12 @@ describe('Integration hooks with no user middleware', () => {
const json = await res.json();
assert.equal(json.post, 'works');
});
it('Integration middleware marked as "url" runs', async () => {
const res = await fixture.fetch('/url');
const json = await res.json();
assert.equal(json.post, 'works');
});
});
describe('Middleware in PROD mode, SSG', () => {

View file

@ -43,6 +43,12 @@ const routes = [
h1: '[id].astro',
p: 'id-2',
},
{
description: 'matches /dynamic-c/id-2 to [id].astro when the route is injected with a URL',
url: '/dynamic-c/id-2',
h1: '[id].astro',
p: 'id-2',
},
];
function appendForwardSlash(path) {