diff --git a/.changeset/good-frogs-report.md b/.changeset/good-frogs-report.md new file mode 100644 index 000000000000..fdac3299ecdf --- /dev/null +++ b/.changeset/good-frogs-report.md @@ -0,0 +1,5 @@ +--- +'astro': patch +--- + +Emit middleware as an entrypoint during build diff --git a/packages/astro/src/core/build/plugins/index.ts b/packages/astro/src/core/build/plugins/index.ts index 982a90ce348e..235879c0e830 100644 --- a/packages/astro/src/core/build/plugins/index.ts +++ b/packages/astro/src/core/build/plugins/index.ts @@ -10,12 +10,14 @@ import { pluginInternals } from './plugin-internals.js'; import { pluginPages } from './plugin-pages.js'; import { pluginPrerender } from './plugin-prerender.js'; import { pluginSSR } from './plugin-ssr.js'; +import { pluginMiddleware } from './plugin-middleware.js'; export function registerAllPlugins({ internals, options, register }: AstroBuildPluginContainer) { register(pluginComponentEntry(internals)); register(pluginAliasResolve(internals)); register(pluginAnalyzer(internals)); register(pluginInternals(internals)); + register(pluginMiddleware(options, internals)); register(pluginPages(options, internals)); register(pluginCSS(options, internals)); register(astroHeadBuildPlugin(options, internals)); diff --git a/packages/astro/src/core/build/plugins/plugin-middleware.ts b/packages/astro/src/core/build/plugins/plugin-middleware.ts new file mode 100644 index 000000000000..507c4ae710a0 --- /dev/null +++ b/packages/astro/src/core/build/plugins/plugin-middleware.ts @@ -0,0 +1,63 @@ +import type { Plugin as VitePlugin } from 'vite'; +import { MIDDLEWARE_PATH_SEGMENT_NAME } from '../../constants.js'; +import { addRollupInput } from '../add-rollup-input.js'; +import type { BuildInternals } from '../internal.js'; +import type { AstroBuildPlugin } from '../plugin'; +import type { StaticBuildOptions } from '../types'; + +export const MIDDLEWARE_MODULE_ID = '@astro-middleware'; +export const RESOLVED_MIDDLEWARE_MODULE_ID = '\0@astro-middleware'; + +let inputs: Set = new Set(); +export function vitePluginMiddleware( + opts: StaticBuildOptions, + _internals: BuildInternals +): VitePlugin { + return { + name: '@astro/plugin-middleware', + options(options) { + if (opts.settings.config.experimental.middleware) { + return addRollupInput(options, [MIDDLEWARE_MODULE_ID]); + } + }, + + resolveId(id) { + if (id === MIDDLEWARE_MODULE_ID && opts.settings.config.experimental.middleware) { + return RESOLVED_MIDDLEWARE_MODULE_ID; + } + }, + + async load(id) { + if (id === RESOLVED_MIDDLEWARE_MODULE_ID && opts.settings.config.experimental.middleware) { + const imports: string[] = []; + const exports: string[] = []; + let middlewareId = await this.resolve( + `${opts.settings.config.srcDir.pathname}/${MIDDLEWARE_PATH_SEGMENT_NAME}` + ); + if (middlewareId) { + imports.push(`import { onRequest } from "${middlewareId.id}"`); + exports.push(`export { onRequest }`); + } + const result = [imports.join('\n'), exports.join('\n')]; + + return result.join('\n'); + } + }, + }; +} + +export function pluginMiddleware( + opts: StaticBuildOptions, + internals: BuildInternals +): AstroBuildPlugin { + return { + build: 'ssr', + hooks: { + 'build:before': () => { + return { + vitePlugin: vitePluginMiddleware(opts, internals), + }; + }, + }, + }; +} diff --git a/packages/astro/src/core/build/plugins/plugin-pages.ts b/packages/astro/src/core/build/plugins/plugin-pages.ts index ba4f0df32e50..68967c390005 100644 --- a/packages/astro/src/core/build/plugins/plugin-pages.ts +++ b/packages/astro/src/core/build/plugins/plugin-pages.ts @@ -1,10 +1,10 @@ import type { Plugin as VitePlugin } from 'vite'; import { pagesVirtualModuleId, resolvedPagesVirtualModuleId } from '../../app/index.js'; -import { MIDDLEWARE_PATH_SEGMENT_NAME } from '../../constants.js'; import { addRollupInput } from '../add-rollup-input.js'; import { eachPageData, type BuildInternals } from '../internal.js'; import type { AstroBuildPlugin } from '../plugin'; import type { StaticBuildOptions } from '../types'; +import { MIDDLEWARE_MODULE_ID } from './plugin-middleware.js'; function vitePluginPages(opts: StaticBuildOptions, internals: BuildInternals): VitePlugin { return { @@ -24,13 +24,6 @@ function vitePluginPages(opts: StaticBuildOptions, internals: BuildInternals): V async load(id) { if (id === resolvedPagesVirtualModuleId) { - let middlewareId = null; - if (opts.settings.config.experimental.middleware) { - middlewareId = await this.resolve( - `${opts.settings.config.srcDir.pathname}/${MIDDLEWARE_PATH_SEGMENT_NAME}` - ); - } - let importMap = ''; let imports = []; let i = 0; @@ -54,11 +47,15 @@ function vitePluginPages(opts: StaticBuildOptions, internals: BuildInternals): V const def = `${imports.join('\n')} -${middlewareId ? `import * as _middleware from "${middlewareId.id}";` : ''} +${ + opts.settings.config.experimental.middleware + ? `import * as _middleware from "${MIDDLEWARE_MODULE_ID}";` + : '' +} export const pageMap = new Map([${importMap}]); export const renderers = [${rendererItems}]; -${middlewareId ? `export const middleware = _middleware;` : ''} +${opts.settings.config.experimental.middleware ? `export const middleware = _middleware;` : ''} `; return def; diff --git a/packages/astro/src/core/build/static-build.ts b/packages/astro/src/core/build/static-build.ts index 7d5424eb459e..fbb0f431dc85 100644 --- a/packages/astro/src/core/build/static-build.ts +++ b/packages/astro/src/core/build/static-build.ts @@ -27,6 +27,7 @@ import { createPluginContainer, type AstroBuildPluginContainer } from './plugin. import { registerAllPlugins } from './plugins/index.js'; import type { PageBuildData, StaticBuildOptions } from './types'; import { getTimeStat } from './util.js'; +import { RESOLVED_MIDDLEWARE_MODULE_ID } from './plugins/plugin-middleware.js'; export async function viteBuild(opts: StaticBuildOptions) { const { allPages, settings } = opts; @@ -172,6 +173,8 @@ async function ssrBuild( entryFileNames(chunkInfo) { if (chunkInfo.facadeModuleId === resolvedPagesVirtualModuleId) { return opts.buildConfig.serverEntry; + } else if (chunkInfo.facadeModuleId === RESOLVED_MIDDLEWARE_MODULE_ID) { + return 'middleware.mjs'; } else { return '[name].mjs'; }