diff --git a/.changeset/great-crabs-march.md b/.changeset/great-crabs-march.md new file mode 100644 index 000000000000..5f58b2bb4111 --- /dev/null +++ b/.changeset/great-crabs-march.md @@ -0,0 +1,5 @@ +--- +'astro': patch +--- + +Correctly emit the middleware code during the build phase. The file emitted is now `dist/middleware.mjs` diff --git a/packages/astro/src/core/app/index.ts b/packages/astro/src/core/app/index.ts index 56d22eafcdf2..d9926f70cce5 100644 --- a/packages/astro/src/core/app/index.ts +++ b/packages/astro/src/core/app/index.ts @@ -236,12 +236,11 @@ export class App { site: this.#env.site, adapterName: this.#env.adapterName, }); - const onRequest = page.middleware?.onRequest; let response; - if (onRequest) { + if (page.onRequest) { response = await callMiddleware( this.#env.logging, - onRequest as MiddlewareResponseHandler, + page.onRequest as MiddlewareResponseHandler, apiContext, () => { return renderPage({ mod, renderContext, env: this.#env, apiContext }); @@ -287,7 +286,7 @@ export class App { 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.response.headers.get('X-Astro-Response') === 'Not-Found') { diff --git a/packages/astro/src/core/build/generate.ts b/packages/astro/src/core/build/generate.ts index a6a1ece54d4c..8fe090fc175e 100644 --- a/packages/astro/src/core/build/generate.ts +++ b/packages/astro/src/core/build/generate.ts @@ -12,6 +12,7 @@ import type { EndpointOutput, GetStaticPathsItem, ImageTransform, + MiddlewareHandler, MiddlewareResponseHandler, RouteData, RouteType, @@ -229,7 +230,7 @@ async function generatePage( .reduce(mergeInlineCss, []); const pageModulePromise = ssrEntry.page; - const middleware = ssrEntry.middleware; + const onRequest = ssrEntry.onRequest; if (!pageModulePromise) { throw new Error( @@ -264,7 +265,7 @@ async function generatePage( for (let i = 0; i < paths.length; i++) { const path = paths[i]; - await generatePath(path, opts, generationOptions, middleware); + await generatePath(path, opts, generationOptions, onRequest); const timeEnd = performance.now(); const timeChange = getTimeStat(timeStart, timeEnd); const timeIncrease = `(+${timeChange})`; @@ -448,7 +449,7 @@ async function generatePath( pathname: string, opts: StaticBuildOptions, gopts: GeneratePathOptions, - middleware?: AstroMiddlewareInstance + onRequest?: MiddlewareHandler ) { const { settings, logging, origin, routeCache } = opts; const { @@ -569,7 +570,7 @@ async function generatePath( env, renderContext, logging, - middleware as AstroMiddlewareInstance + onRequest as MiddlewareHandler ); if (result.type === 'response') { @@ -593,7 +594,6 @@ async function generatePath( adapterName: env.adapterName, }); - const onRequest = middleware?.onRequest; if (onRequest) { response = await callMiddleware( env.logging, diff --git a/packages/astro/src/core/build/plugins/plugin-middleware.ts b/packages/astro/src/core/build/plugins/plugin-middleware.ts index 6bd63b44f3a0..e65a112dd288 100644 --- a/packages/astro/src/core/build/plugins/plugin-middleware.ts +++ b/packages/astro/src/core/build/plugins/plugin-middleware.ts @@ -3,9 +3,12 @@ import { MIDDLEWARE_PATH_SEGMENT_NAME } from '../../constants.js'; import type { BuildInternals } from '../internal.js'; import type { AstroBuildPlugin } from '../plugin'; import type { StaticBuildOptions } from '../types'; +import { addRollupInput } from '../add-rollup-input.js'; export const MIDDLEWARE_MODULE_ID = '@astro-middleware'; +const EMPTY_MIDDLEWARE = '\0empty-middleware'; + export function vitePluginMiddleware( opts: StaticBuildOptions, _internals: BuildInternals @@ -13,6 +16,10 @@ export function vitePluginMiddleware( return { name: '@astro/plugin-middleware', + options(options) { + return addRollupInput(options, [MIDDLEWARE_MODULE_ID]); + }, + async resolveId(id) { if (id === MIDDLEWARE_MODULE_ID) { const middlewareId = await this.resolve( @@ -20,8 +27,19 @@ export function vitePluginMiddleware( ); if (middlewareId) { 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'; + } }, }; } diff --git a/packages/astro/src/core/build/plugins/plugin-pages.ts b/packages/astro/src/core/build/plugins/plugin-pages.ts index f767a9c5bd79..c6f89a558bee 100644 --- a/packages/astro/src/core/build/plugins/plugin-pages.ts +++ b/packages/astro/src/core/build/plugins/plugin-pages.ts @@ -82,8 +82,8 @@ function vitePluginPages(opts: StaticBuildOptions, internals: BuildInternals): V const middlewareModule = await this.resolve(MIDDLEWARE_MODULE_ID); if (middlewareModule) { - imports.push(`import * as middleware from "${middlewareModule.id}";`); - exports.push(`export { middleware };`); + imports.push(`import { onRequest } from "${middlewareModule.id}";`); + exports.push(`export { onRequest };`); } return `${imports.join('\n')}${exports.join('\n')}`; diff --git a/packages/astro/src/core/build/static-build.ts b/packages/astro/src/core/build/static-build.ts index 647b31983066..48f70a15e3cf 100644 --- a/packages/astro/src/core/build/static-build.ts +++ b/packages/astro/src/core/build/static-build.ts @@ -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 type { AllPagesData, PageBuildData, StaticBuildOptions } from './types'; import { getTimeStat } from './util.js'; +import { MIDDLEWARE_MODULE_ID } from './plugins/plugin-middleware.js'; export async function viteBuild(opts: StaticBuildOptions) { const { allPages, settings } = opts; @@ -176,12 +177,7 @@ async function ssrBuild( entryFileNames(chunkInfo) { if (chunkInfo.facadeModuleId?.startsWith(ASTRO_PAGE_RESOLVED_MODULE_ID)) { return makeAstroPageEntryPointFileName(chunkInfo.facadeModuleId, allPages); - } else if ( - // 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') - ) { + } else if (chunkInfo.facadeModuleId === MIDDLEWARE_MODULE_ID) { return 'middleware.mjs'; } else if (chunkInfo.facadeModuleId === SSR_VIRTUAL_MODULE_ID) { return opts.settings.config.build.serverEntry; diff --git a/packages/astro/src/core/build/types.ts b/packages/astro/src/core/build/types.ts index 772235697751..8409a8cff03c 100644 --- a/packages/astro/src/core/build/types.ts +++ b/packages/astro/src/core/build/types.ts @@ -6,6 +6,7 @@ import type { BuildConfig, ComponentInstance, ManifestData, + MiddlewareHandler, RouteData, RuntimeMode, SSRLoadedRenderer, @@ -51,7 +52,10 @@ type ImportComponentInstance = () => Promise; export interface SinglePageBuiltModule { page: ImportComponentInstance; - middleware: AstroMiddlewareInstance; + /** + * The `onRequest` hook exported by the middleware + */ + onRequest?: MiddlewareHandler; renderers: SSRLoadedRenderer[]; } diff --git a/packages/astro/src/core/endpoint/dev/index.ts b/packages/astro/src/core/endpoint/dev/index.ts index b829754765ec..04e11b578007 100644 --- a/packages/astro/src/core/endpoint/dev/index.ts +++ b/packages/astro/src/core/endpoint/dev/index.ts @@ -21,5 +21,5 @@ export async function call(options: SSROptions, logging: LogOptions) { mod: endpointHandler as any, }); - return await callEndpoint(endpointHandler, env, ctx, logging, middleware); + return await callEndpoint(endpointHandler, env, ctx, logging, middleware?.onRequest); } diff --git a/packages/astro/src/core/endpoint/index.ts b/packages/astro/src/core/endpoint/index.ts index 5822685cf987..5390b97dddb1 100644 --- a/packages/astro/src/core/endpoint/index.ts +++ b/packages/astro/src/core/endpoint/index.ts @@ -5,6 +5,7 @@ import type { EndpointHandler, EndpointOutput, MiddlewareEndpointHandler, + MiddlewareHandler, Params, } from '../../@types/astro'; import type { Environment, RenderContext } from '../render/index'; @@ -97,7 +98,7 @@ export async function callEndpoint env: Environment, ctx: RenderContext, logging: LogOptions, - middleware?: AstroMiddlewareInstance | undefined + onRequest?: MiddlewareHandler | undefined ): Promise { const context = createAPIContext({ request: ctx.request, @@ -108,11 +109,10 @@ export async function callEndpoint }); let response; - if (middleware && middleware.onRequest) { - const onRequest = middleware.onRequest as MiddlewareEndpointHandler; + if (onRequest) { response = await callMiddleware( env.logging, - onRequest, + onRequest as MiddlewareEndpointHandler, context, async () => { return await renderEndpoint(mod, context, env.ssr); diff --git a/packages/astro/src/core/redirects/component.ts b/packages/astro/src/core/redirects/component.ts index f76b82517887..fc6f07b54ef9 100644 --- a/packages/astro/src/core/redirects/component.ts +++ b/packages/astro/src/core/redirects/component.ts @@ -1,5 +1,6 @@ import type { AstroMiddlewareInstance, ComponentInstance } from '../../@types/astro'; import type { SinglePageBuiltModule } from '../build/types'; +import type { MiddlewareHandler } from '../../@types/astro'; // A stub of a component instance for a given route export const RedirectComponentInstance: ComponentInstance = { @@ -10,12 +11,8 @@ export const RedirectComponentInstance: ComponentInstance = { }, }; -const StaticMiddlewareInstance: AstroMiddlewareInstance = { - onRequest: (ctx, next) => next(), -}; - export const RedirectSinglePageBuiltModule: SinglePageBuiltModule = { page: () => Promise.resolve(RedirectComponentInstance), - middleware: StaticMiddlewareInstance, + onRequest: (ctx, next) => next(), renderers: [], };