summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Bjorn Lu <bjornlu.dev@gmail.com> 2023-06-29 21:19:43 +0800
committerGravatar GitHub <noreply@github.com> 2023-06-29 21:19:43 +0800
commitbaaeab0a67534f9c199afcdaee23e5de92e79d7d (patch)
tree2bad4b703a09b2da1ec01e0770c56f3b9d28342b
parent56f1b1229cf629a42a88d429f2a5fc6378613017 (diff)
downloadastro-baaeab0a67534f9c199afcdaee23e5de92e79d7d.tar.gz
astro-baaeab0a67534f9c199afcdaee23e5de92e79d7d.tar.zst
astro-baaeab0a67534f9c199afcdaee23e5de92e79d7d.zip
Refactor component and renderers loading flow (#7518)
Diffstat (limited to '')
-rw-r--r--packages/astro/src/core/endpoint/dev/index.ts10
-rw-r--r--packages/astro/src/core/render/dev/index.ts40
-rw-r--r--packages/astro/src/core/render/index.ts2
-rw-r--r--packages/astro/src/core/render/renderer.ts42
-rw-r--r--packages/astro/src/prerender/routing.ts13
-rw-r--r--packages/astro/src/vite-plugin-astro-server/route.ts16
-rw-r--r--packages/astro/test/units/render/jsx.test.js2
7 files changed, 43 insertions, 82 deletions
diff --git a/packages/astro/src/core/endpoint/dev/index.ts b/packages/astro/src/core/endpoint/dev/index.ts
index 04e11b578..1f0917166 100644
--- a/packages/astro/src/core/endpoint/dev/index.ts
+++ b/packages/astro/src/core/endpoint/dev/index.ts
@@ -5,12 +5,8 @@ import { createRenderContext } from '../../render/index.js';
import { callEndpoint } from '../index.js';
export async function call(options: SSROptions, logging: LogOptions) {
- const {
- env,
- preload: [, mod],
- middleware,
- } = options;
- const endpointHandler = mod as unknown as EndpointHandler;
+ const { env, preload, middleware } = options;
+ const endpointHandler = preload as unknown as EndpointHandler;
const ctx = await createRenderContext({
request: options.request,
@@ -18,7 +14,7 @@ export async function call(options: SSROptions, logging: LogOptions) {
pathname: options.pathname,
route: options.route,
env,
- mod: endpointHandler as any,
+ mod: preload,
});
return await callEndpoint(endpointHandler, env, ctx, logging, middleware?.onRequest);
diff --git a/packages/astro/src/core/render/dev/index.ts b/packages/astro/src/core/render/dev/index.ts
index 67d0b0581..5995bb711 100644
--- a/packages/astro/src/core/render/dev/index.ts
+++ b/packages/astro/src/core/render/dev/index.ts
@@ -5,17 +5,14 @@ import type {
MiddlewareResponseHandler,
RouteData,
SSRElement,
- SSRLoadedRenderer,
} from '../../../@types/astro';
import { PAGE_SCRIPT_ID } from '../../../vite-plugin-scripts/index.js';
import { createAPIContext } from '../../endpoint/index.js';
import { enhanceViteSSRError } from '../../errors/dev/index.js';
import { AggregateError, CSSError, MarkdownError } from '../../errors/index.js';
import { callMiddleware } from '../../middleware/callMiddleware.js';
-import type { ModuleLoader } from '../../module-loader/index';
import { isPage, resolveIdToUrl, viteID } from '../../util.js';
-import { createRenderContext, renderPage as coreRenderPage } from '../index.js';
-import { filterFoundRenderers, loadRenderer } from '../renderer.js';
+import { createRenderContext, renderPage as coreRenderPage, loadRenderers } from '../index.js';
import { getStylesForURL } from './css.js';
import type { DevelopmentEnvironment } from './environment';
import { getComponentMetadata } from './metadata.js';
@@ -32,8 +29,8 @@ export interface SSROptions {
origin: string;
/** the web request (needed for dynamic routes) */
pathname: string;
- /** The renderers and instance */
- preload: ComponentPreload;
+ /** The runtime component instance */
+ preload: ComponentInstance;
/** Request */
request: Request;
/** optional, in case we need to render something outside of a dev server */
@@ -44,36 +41,31 @@ export interface SSROptions {
middleware?: AstroMiddlewareInstance<unknown>;
}
-export type ComponentPreload = [SSRLoadedRenderer[], ComponentInstance];
-
-export async function loadRenderers(
- moduleLoader: ModuleLoader,
- settings: AstroSettings
-): Promise<SSRLoadedRenderer[]> {
- const loader = (entry: string) => moduleLoader.import(entry);
- const renderers = await Promise.all(settings.renderers.map((r) => loadRenderer(r, loader)));
- return filterFoundRenderers(renderers);
-}
-
export async function preload({
env,
filePath,
-}: Pick<SSROptions, 'env' | 'filePath'>): Promise<ComponentPreload> {
+}: {
+ env: DevelopmentEnvironment;
+ filePath: URL;
+}): Promise<ComponentInstance> {
// Important: This needs to happen first, in case a renderer provides polyfills.
- const renderers = await loadRenderers(env.loader, env.settings);
+ const renderers = await loadRenderers(env.settings, env.loader);
+ // Override the environment's renderers. This ensures that if renderers change (HMR)
+ // The new instances are passed through.
+ env.renderers = renderers;
try {
// Load the module from the Vite SSR Runtime.
const mod = (await env.loader.import(viteID(filePath))) as ComponentInstance;
- return [renderers, mod];
+ return mod;
} catch (error) {
// If the error came from Markdown or CSS, we already handled it and there's no need to enhance it
if (MarkdownError.is(error) || CSSError.is(error) || AggregateError.is(error)) {
throw error;
}
- throw enhanceViteSSRError({ error, filePath, loader: env.loader, renderers });
+ throw enhanceViteSSRError({ error, filePath, loader: env.loader });
}
}
@@ -156,11 +148,7 @@ async function getScriptsAndStyles({ env, filePath }: GetScriptsAndStylesParams)
}
export async function renderPage(options: SSROptions): Promise<Response> {
- const [renderers, mod] = options.preload;
-
- // Override the environment's renderers. This ensures that if renderers change (HMR)
- // The new instances are passed through.
- options.env.renderers = renderers;
+ const mod = options.preload;
const { scripts, links, styles, metadata } = await getScriptsAndStyles({
env: options.env,
diff --git a/packages/astro/src/core/render/index.ts b/packages/astro/src/core/render/index.ts
index 4e4df8239..372454f26 100644
--- a/packages/astro/src/core/render/index.ts
+++ b/packages/astro/src/core/render/index.ts
@@ -8,4 +8,4 @@ export {
} from './core.js';
export type { Environment } from './environment';
export { createBasicEnvironment, createEnvironment } from './environment.js';
-export { loadRenderer } from './renderer.js';
+export { loadRenderer, loadRenderers } from './renderer.js';
diff --git a/packages/astro/src/core/render/renderer.ts b/packages/astro/src/core/render/renderer.ts
index 3585a08c2..8e5e97202 100644
--- a/packages/astro/src/core/render/renderer.ts
+++ b/packages/astro/src/core/render/renderer.ts
@@ -1,36 +1,24 @@
-import type { AstroRenderer, SSRLoadedRenderer } from '../../@types/astro';
+import type { AstroRenderer, AstroSettings, SSRLoadedRenderer } from '../../@types/astro';
+import type { ModuleLoader } from '../module-loader/index.js';
-export type RendererServerEntrypointModule = {
- default: SSRLoadedRenderer['ssr'];
-};
-export type MaybeRendererServerEntrypointModule = Partial<RendererServerEntrypointModule>;
-export type RendererLoader = (entryPoint: string) => Promise<MaybeRendererServerEntrypointModule>;
+export async function loadRenderers(
+ settings: AstroSettings,
+ moduleLoader: ModuleLoader
+): Promise<SSRLoadedRenderer[]> {
+ const renderers = await Promise.all(settings.renderers.map((r) => loadRenderer(r, moduleLoader)));
+ return renderers.filter(Boolean) as SSRLoadedRenderer[];
+}
export async function loadRenderer(
renderer: AstroRenderer,
- loader: RendererLoader
+ moduleLoader: ModuleLoader
): Promise<SSRLoadedRenderer | undefined> {
- const mod = await loader(renderer.serverEntrypoint);
+ const mod = await moduleLoader.import(renderer.serverEntrypoint);
if (typeof mod.default !== 'undefined') {
- return createLoadedRenderer(renderer, mod as RendererServerEntrypointModule);
+ return {
+ ...renderer,
+ ssr: mod.default,
+ };
}
return undefined;
}
-
-export function filterFoundRenderers(
- renderers: Array<SSRLoadedRenderer | undefined>
-): SSRLoadedRenderer[] {
- return renderers.filter((renderer): renderer is SSRLoadedRenderer => {
- return !!renderer;
- });
-}
-
-export function createLoadedRenderer(
- renderer: AstroRenderer,
- mod: RendererServerEntrypointModule
-): SSRLoadedRenderer {
- return {
- ...renderer,
- ssr: mod.default,
- };
-}
diff --git a/packages/astro/src/prerender/routing.ts b/packages/astro/src/prerender/routing.ts
index fc01b0480..0282a12b4 100644
--- a/packages/astro/src/prerender/routing.ts
+++ b/packages/astro/src/prerender/routing.ts
@@ -1,10 +1,6 @@
-import type { AstroSettings, RouteData } from '../@types/astro';
+import type { AstroSettings, ComponentInstance, RouteData } from '../@types/astro';
import { RedirectComponentInstance, routeIsRedirect } from '../core/redirects/index.js';
-import {
- preload,
- type ComponentPreload,
- type DevelopmentEnvironment,
-} from '../core/render/dev/index.js';
+import { preload, type DevelopmentEnvironment } from '../core/render/dev/index.js';
import { getPrerenderStatus } from './metadata.js';
type GetSortedPreloadedMatchesParams = {
@@ -35,7 +31,7 @@ type PreloadAndSetPrerenderStatusParams = {
type PreloadAndSetPrerenderStatusResult = {
filePath: URL;
route: RouteData;
- preloadedComponent: ComponentPreload;
+ preloadedComponent: ComponentInstance;
};
async function preloadAndSetPrerenderStatus({
@@ -48,9 +44,8 @@ async function preloadAndSetPrerenderStatus({
const filePath = new URL(`./${route.component}`, settings.config.root);
if (routeIsRedirect(route)) {
- const preloadedComponent: ComponentPreload = [[], RedirectComponentInstance];
return {
- preloadedComponent,
+ preloadedComponent: RedirectComponentInstance,
route,
filePath,
};
diff --git a/packages/astro/src/vite-plugin-astro-server/route.ts b/packages/astro/src/vite-plugin-astro-server/route.ts
index a610b4b74..f7d8ba23f 100644
--- a/packages/astro/src/vite-plugin-astro-server/route.ts
+++ b/packages/astro/src/vite-plugin-astro-server/route.ts
@@ -7,11 +7,7 @@ import { throwIfRedirectNotAllowed } from '../core/endpoint/index.js';
import { AstroErrorData } from '../core/errors/index.js';
import { warn } from '../core/logger/core.js';
import { loadMiddleware } from '../core/middleware/loadMiddleware.js';
-import type {
- ComponentPreload,
- DevelopmentEnvironment,
- SSROptions,
-} from '../core/render/dev/index';
+import type { DevelopmentEnvironment, SSROptions } from '../core/render/dev/index';
import { preload, renderPage } from '../core/render/dev/index.js';
import { getParamsAndProps, GetParamsAndPropsError } from '../core/render/index.js';
import { createRequest } from '../core/request.js';
@@ -33,7 +29,7 @@ interface MatchedRoute {
route: RouteData;
filePath: URL;
resolvedPathname: string;
- preloadedComponent: ComponentPreload;
+ preloadedComponent: ComponentInstance;
mod: ComponentInstance;
}
@@ -54,9 +50,8 @@ export async function matchRoute(
for await (const { preloadedComponent, route: maybeRoute, filePath } of preloadedMatches) {
// attempt to get static paths
// if this fails, we have a bad URL match!
- const [, mod] = preloadedComponent;
const paramsAndPropsRes = await getParamsAndProps({
- mod,
+ mod: preloadedComponent,
route: maybeRoute,
routeCache,
pathname: pathname,
@@ -70,7 +65,7 @@ export async function matchRoute(
filePath,
resolvedPathname: pathname,
preloadedComponent,
- mod,
+ mod: preloadedComponent,
};
}
}
@@ -101,14 +96,13 @@ export async function matchRoute(
if (custom404) {
const filePath = new URL(`./${custom404.component}`, settings.config.root);
const preloadedComponent = await preload({ env, filePath });
- const [, mod] = preloadedComponent;
return {
route: custom404,
filePath,
resolvedPathname: pathname,
preloadedComponent,
- mod,
+ mod: preloadedComponent,
};
}
diff --git a/packages/astro/test/units/render/jsx.test.js b/packages/astro/test/units/render/jsx.test.js
index c249bcbd5..09cf79239 100644
--- a/packages/astro/test/units/render/jsx.test.js
+++ b/packages/astro/test/units/render/jsx.test.js
@@ -16,7 +16,7 @@ import { createAstroJSXComponent, renderer as jsxRenderer } from '../../../dist/
import { defaultLogging as logging } from '../../test-utils.js';
const createAstroModule = (AstroComponent) => ({ default: AstroComponent });
-const loadJSXRenderer = () => loadRenderer(jsxRenderer, (s) => import(s));
+const loadJSXRenderer = () => loadRenderer(jsxRenderer, { import: (s) => import(s) });
describe('core/render', () => {
describe('Astro JSX components', () => {