diff --git a/.changeset/unlucky-paws-own.md b/.changeset/unlucky-paws-own.md new file mode 100644 index 0000000000000..e48bf31e535cd --- /dev/null +++ b/.changeset/unlucky-paws-own.md @@ -0,0 +1,5 @@ +--- +'astro': patch +--- + +Correctly emit pre-rendered pages when `build.split` is set to `true` diff --git a/packages/astro/src/core/build/generate.ts b/packages/astro/src/core/build/generate.ts index b53360d125a51..73b21adfd2a17 100644 --- a/packages/astro/src/core/build/generate.ts +++ b/packages/astro/src/core/build/generate.ts @@ -17,6 +17,7 @@ import type { RouteType, SSRError, SSRLoadedRenderer, + SSRManifest, } from '../../@types/astro'; import { generateImage as generateImageInternal, @@ -148,9 +149,17 @@ export async function generatePages(opts: StaticBuildOptions, internals: BuildIn for (const [pageData, filePath] of eachPageDataFromEntryPoint(internals)) { if (pageData.route.prerender) { const ssrEntryURLPage = createEntryURL(filePath, outFolder); - const ssrEntryPage: SinglePageBuiltModule = await import(ssrEntryURLPage.toString()); - - await generatePage(opts, internals, pageData, ssrEntryPage, builtPaths); + const ssrEntryPage = await import(ssrEntryURLPage.toString()); + // forcing to use undefined, so we fail in an expected way if the module is not even there. + const manifest: SSRManifest | undefined = ssrEntryPage.manifest; + const ssrEntry = manifest?.pageModule; + if (ssrEntry) { + await generatePage(opts, internals, pageData, ssrEntry, builtPaths); + } else { + throw new Error( + `Unable to find the manifest for the module ${ssrEntryURLPage.toString()}. This is unexpected and likely a bug in Astro, please report.` + ); + } } } for (const pageData of eachRedirectPageData(internals)) { diff --git a/packages/astro/src/core/build/internal.ts b/packages/astro/src/core/build/internal.ts index 8c7da07d4319a..565c2ec574680 100644 --- a/packages/astro/src/core/build/internal.ts +++ b/packages/astro/src/core/build/internal.ts @@ -3,9 +3,13 @@ import type { RouteData, SSRResult } from '../../@types/astro'; import type { PageOptions } from '../../vite-plugin-astro/types'; import { prependForwardSlash, removeFileExtension } from '../path.js'; import { viteID } from '../util.js'; -import { ASTRO_PAGE_MODULE_ID, getVirtualModulePageIdFromPath } from './plugins/plugin-pages.js'; +import { + ASTRO_PAGE_RESOLVED_MODULE_ID, + getVirtualModulePageIdFromPath, +} from './plugins/plugin-pages.js'; import { ASTRO_PAGE_EXTENSION_POST_PATTERN } from './plugins/util.js'; import type { PageBuildData, StylesheetAsset, ViteID } from './types'; +import { RESOLVED_SPLIT_MODULE_ID } from './plugins/plugin-ssr.js'; export interface BuildInternals { /** @@ -234,7 +238,13 @@ export function* eachPageDataFromEntryPoint( internals: BuildInternals ): Generator<[PageBuildData, string]> { for (const [entryPoint, filePath] of internals.entrySpecifierToBundleMap) { - if (entryPoint.includes(ASTRO_PAGE_MODULE_ID)) { + // virtual pages can be emitted with different prefixes: + // - the classic way are pages emitted with prefix ASTRO_PAGE_RESOLVED_MODULE_ID -> plugin-pages + // - pages emitted using `build.split`, in this case pages are emitted with prefix RESOLVED_SPLIT_MODULE_ID + if ( + entryPoint.includes(ASTRO_PAGE_RESOLVED_MODULE_ID) || + entryPoint.includes(RESOLVED_SPLIT_MODULE_ID) + ) { const [, pageName] = entryPoint.split(':'); const pageData = internals.pagesByComponent.get( `${pageName.replace(ASTRO_PAGE_EXTENSION_POST_PATTERN, '.')}` diff --git a/packages/astro/test/fixtures/ssr-split-manifest/src/pages/prerender.astro b/packages/astro/test/fixtures/ssr-split-manifest/src/pages/prerender.astro new file mode 100644 index 0000000000000..2eec6dbf13c93 --- /dev/null +++ b/packages/astro/test/fixtures/ssr-split-manifest/src/pages/prerender.astro @@ -0,0 +1,12 @@ +--- +export const prerender = true +--- + + +
+