fix: correctly emit middleware file name (#7427)

This commit is contained in:
Emanuele Stoppa 2023-06-20 17:32:30 +01:00 committed by GitHub
parent 008af95a75
commit e314a04bfb
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 47 additions and 28 deletions

View file

@ -0,0 +1,5 @@
---
'astro': patch
---
Correctly emit the middleware code during the build phase. The file emitted is now `dist/middleware.mjs`

View file

@ -236,12 +236,11 @@ export class App {
site: this.#env.site, site: this.#env.site,
adapterName: this.#env.adapterName, adapterName: this.#env.adapterName,
}); });
const onRequest = page.middleware?.onRequest;
let response; let response;
if (onRequest) { if (page.onRequest) {
response = await callMiddleware<Response>( response = await callMiddleware<Response>(
this.#env.logging, this.#env.logging,
onRequest as MiddlewareResponseHandler, page.onRequest as MiddlewareResponseHandler,
apiContext, apiContext,
() => { () => {
return renderPage({ mod, renderContext, env: this.#env, apiContext }); return renderPage({ mod, renderContext, env: this.#env, apiContext });
@ -287,7 +286,7 @@ export class App {
mod: handler as any, mod: handler as any,
}); });
const result = await callEndpoint(handler, this.#env, ctx, this.#logging, page.middleware); const result = await callEndpoint(handler, this.#env, ctx, this.#logging, page.onRequest);
if (result.type === 'response') { if (result.type === 'response') {
if (result.response.headers.get('X-Astro-Response') === 'Not-Found') { if (result.response.headers.get('X-Astro-Response') === 'Not-Found') {

View file

@ -12,6 +12,7 @@ import type {
EndpointOutput, EndpointOutput,
GetStaticPathsItem, GetStaticPathsItem,
ImageTransform, ImageTransform,
MiddlewareHandler,
MiddlewareResponseHandler, MiddlewareResponseHandler,
RouteData, RouteData,
RouteType, RouteType,
@ -229,7 +230,7 @@ async function generatePage(
.reduce(mergeInlineCss, []); .reduce(mergeInlineCss, []);
const pageModulePromise = ssrEntry.page; const pageModulePromise = ssrEntry.page;
const middleware = ssrEntry.middleware; const onRequest = ssrEntry.onRequest;
if (!pageModulePromise) { if (!pageModulePromise) {
throw new Error( throw new Error(
@ -264,7 +265,7 @@ async function generatePage(
for (let i = 0; i < paths.length; i++) { for (let i = 0; i < paths.length; i++) {
const path = paths[i]; const path = paths[i];
await generatePath(path, opts, generationOptions, middleware); await generatePath(path, opts, generationOptions, onRequest);
const timeEnd = performance.now(); const timeEnd = performance.now();
const timeChange = getTimeStat(timeStart, timeEnd); const timeChange = getTimeStat(timeStart, timeEnd);
const timeIncrease = `(+${timeChange})`; const timeIncrease = `(+${timeChange})`;
@ -448,7 +449,7 @@ async function generatePath(
pathname: string, pathname: string,
opts: StaticBuildOptions, opts: StaticBuildOptions,
gopts: GeneratePathOptions, gopts: GeneratePathOptions,
middleware?: AstroMiddlewareInstance<unknown> onRequest?: MiddlewareHandler<unknown>
) { ) {
const { settings, logging, origin, routeCache } = opts; const { settings, logging, origin, routeCache } = opts;
const { const {
@ -569,7 +570,7 @@ async function generatePath(
env, env,
renderContext, renderContext,
logging, logging,
middleware as AstroMiddlewareInstance<Response | EndpointOutput> onRequest as MiddlewareHandler<Response | EndpointOutput>
); );
if (result.type === 'response') { if (result.type === 'response') {
@ -593,7 +594,6 @@ async function generatePath(
adapterName: env.adapterName, adapterName: env.adapterName,
}); });
const onRequest = middleware?.onRequest;
if (onRequest) { if (onRequest) {
response = await callMiddleware<Response>( response = await callMiddleware<Response>(
env.logging, env.logging,

View file

@ -3,9 +3,12 @@ import { MIDDLEWARE_PATH_SEGMENT_NAME } from '../../constants.js';
import type { BuildInternals } from '../internal.js'; import type { BuildInternals } from '../internal.js';
import type { AstroBuildPlugin } from '../plugin'; import type { AstroBuildPlugin } from '../plugin';
import type { StaticBuildOptions } from '../types'; import type { StaticBuildOptions } from '../types';
import { addRollupInput } from '../add-rollup-input.js';
export const MIDDLEWARE_MODULE_ID = '@astro-middleware'; export const MIDDLEWARE_MODULE_ID = '@astro-middleware';
const EMPTY_MIDDLEWARE = '\0empty-middleware';
export function vitePluginMiddleware( export function vitePluginMiddleware(
opts: StaticBuildOptions, opts: StaticBuildOptions,
_internals: BuildInternals _internals: BuildInternals
@ -13,6 +16,10 @@ export function vitePluginMiddleware(
return { return {
name: '@astro/plugin-middleware', name: '@astro/plugin-middleware',
options(options) {
return addRollupInput(options, [MIDDLEWARE_MODULE_ID]);
},
async resolveId(id) { async resolveId(id) {
if (id === MIDDLEWARE_MODULE_ID) { if (id === MIDDLEWARE_MODULE_ID) {
const middlewareId = await this.resolve( const middlewareId = await this.resolve(
@ -20,8 +27,19 @@ export function vitePluginMiddleware(
); );
if (middlewareId) { if (middlewareId) {
return middlewareId.id; return middlewareId.id;
} else {
return EMPTY_MIDDLEWARE;
} }
} }
if (id === EMPTY_MIDDLEWARE) {
return EMPTY_MIDDLEWARE;
}
},
load(id) {
if (id === EMPTY_MIDDLEWARE) {
return 'export const onRequest = undefined';
}
}, },
}; };
} }

View file

@ -82,8 +82,8 @@ function vitePluginPages(opts: StaticBuildOptions, internals: BuildInternals): V
const middlewareModule = await this.resolve(MIDDLEWARE_MODULE_ID); const middlewareModule = await this.resolve(MIDDLEWARE_MODULE_ID);
if (middlewareModule) { if (middlewareModule) {
imports.push(`import * as middleware from "${middlewareModule.id}";`); imports.push(`import { onRequest } from "${middlewareModule.id}";`);
exports.push(`export { middleware };`); exports.push(`export { onRequest };`);
} }
return `${imports.join('\n')}${exports.join('\n')}`; return `${imports.join('\n')}${exports.join('\n')}`;

View file

@ -32,6 +32,7 @@ import { RESOLVED_RENDERERS_MODULE_ID } from './plugins/plugin-renderers.js';
import { SSR_VIRTUAL_MODULE_ID } from './plugins/plugin-ssr.js'; import { SSR_VIRTUAL_MODULE_ID } from './plugins/plugin-ssr.js';
import type { AllPagesData, PageBuildData, StaticBuildOptions } from './types'; import type { AllPagesData, PageBuildData, StaticBuildOptions } from './types';
import { getTimeStat } from './util.js'; import { getTimeStat } from './util.js';
import { MIDDLEWARE_MODULE_ID } from './plugins/plugin-middleware.js';
export async function viteBuild(opts: StaticBuildOptions) { export async function viteBuild(opts: StaticBuildOptions) {
const { allPages, settings } = opts; const { allPages, settings } = opts;
@ -176,12 +177,7 @@ async function ssrBuild(
entryFileNames(chunkInfo) { entryFileNames(chunkInfo) {
if (chunkInfo.facadeModuleId?.startsWith(ASTRO_PAGE_RESOLVED_MODULE_ID)) { if (chunkInfo.facadeModuleId?.startsWith(ASTRO_PAGE_RESOLVED_MODULE_ID)) {
return makeAstroPageEntryPointFileName(chunkInfo.facadeModuleId, allPages); return makeAstroPageEntryPointFileName(chunkInfo.facadeModuleId, allPages);
} else if ( } else if (chunkInfo.facadeModuleId === MIDDLEWARE_MODULE_ID) {
// checks if the path of the module we have middleware, e.g. middleware.js / middleware/index.js
chunkInfo.moduleIds.find((m) => m.includes('middleware')) !== undefined &&
// checks if the file actually export the `onRequest` function
chunkInfo.exports.includes('_middleware')
) {
return 'middleware.mjs'; return 'middleware.mjs';
} else if (chunkInfo.facadeModuleId === SSR_VIRTUAL_MODULE_ID) { } else if (chunkInfo.facadeModuleId === SSR_VIRTUAL_MODULE_ID) {
return opts.settings.config.build.serverEntry; return opts.settings.config.build.serverEntry;

View file

@ -6,6 +6,7 @@ import type {
BuildConfig, BuildConfig,
ComponentInstance, ComponentInstance,
ManifestData, ManifestData,
MiddlewareHandler,
RouteData, RouteData,
RuntimeMode, RuntimeMode,
SSRLoadedRenderer, SSRLoadedRenderer,
@ -51,7 +52,10 @@ type ImportComponentInstance = () => Promise<ComponentInstance>;
export interface SinglePageBuiltModule { export interface SinglePageBuiltModule {
page: ImportComponentInstance; page: ImportComponentInstance;
middleware: AstroMiddlewareInstance<unknown>; /**
* The `onRequest` hook exported by the middleware
*/
onRequest?: MiddlewareHandler<unknown>;
renderers: SSRLoadedRenderer[]; renderers: SSRLoadedRenderer[];
} }

View file

@ -21,5 +21,5 @@ export async function call(options: SSROptions, logging: LogOptions) {
mod: endpointHandler as any, mod: endpointHandler as any,
}); });
return await callEndpoint(endpointHandler, env, ctx, logging, middleware); return await callEndpoint(endpointHandler, env, ctx, logging, middleware?.onRequest);
} }

View file

@ -5,6 +5,7 @@ import type {
EndpointHandler, EndpointHandler,
EndpointOutput, EndpointOutput,
MiddlewareEndpointHandler, MiddlewareEndpointHandler,
MiddlewareHandler,
Params, Params,
} from '../../@types/astro'; } from '../../@types/astro';
import type { Environment, RenderContext } from '../render/index'; import type { Environment, RenderContext } from '../render/index';
@ -97,7 +98,7 @@ export async function callEndpoint<MiddlewareResult = Response | EndpointOutput>
env: Environment, env: Environment,
ctx: RenderContext, ctx: RenderContext,
logging: LogOptions, logging: LogOptions,
middleware?: AstroMiddlewareInstance<MiddlewareResult> | undefined onRequest?: MiddlewareHandler<MiddlewareResult> | undefined
): Promise<EndpointCallResult> { ): Promise<EndpointCallResult> {
const context = createAPIContext({ const context = createAPIContext({
request: ctx.request, request: ctx.request,
@ -108,11 +109,10 @@ export async function callEndpoint<MiddlewareResult = Response | EndpointOutput>
}); });
let response; let response;
if (middleware && middleware.onRequest) { if (onRequest) {
const onRequest = middleware.onRequest as MiddlewareEndpointHandler;
response = await callMiddleware<Response | EndpointOutput>( response = await callMiddleware<Response | EndpointOutput>(
env.logging, env.logging,
onRequest, onRequest as MiddlewareEndpointHandler,
context, context,
async () => { async () => {
return await renderEndpoint(mod, context, env.ssr); return await renderEndpoint(mod, context, env.ssr);

View file

@ -1,5 +1,6 @@
import type { AstroMiddlewareInstance, ComponentInstance } from '../../@types/astro'; import type { AstroMiddlewareInstance, ComponentInstance } from '../../@types/astro';
import type { SinglePageBuiltModule } from '../build/types'; import type { SinglePageBuiltModule } from '../build/types';
import type { MiddlewareHandler } from '../../@types/astro';
// A stub of a component instance for a given route // A stub of a component instance for a given route
export const RedirectComponentInstance: ComponentInstance = { export const RedirectComponentInstance: ComponentInstance = {
@ -10,12 +11,8 @@ export const RedirectComponentInstance: ComponentInstance = {
}, },
}; };
const StaticMiddlewareInstance: AstroMiddlewareInstance<unknown> = {
onRequest: (ctx, next) => next(),
};
export const RedirectSinglePageBuiltModule: SinglePageBuiltModule = { export const RedirectSinglePageBuiltModule: SinglePageBuiltModule = {
page: () => Promise.resolve(RedirectComponentInstance), page: () => Promise.resolve(RedirectComponentInstance),
middleware: StaticMiddlewareInstance, onRequest: (ctx, next) => next(),
renderers: [], renderers: [],
}; };