refactor(astro): emit entry.mjs to import pages via dynamic import (#7036)

This commit is contained in:
Emanuele Stoppa 2023-05-19 15:30:03 +01:00 committed by GitHub
parent 96947fce96
commit 852d59a8d6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 24 additions and 10 deletions

View file

@ -0,0 +1,5 @@
---
'astro': patch
---
Emit pages as dynamic import chunks during the build

View file

@ -139,7 +139,7 @@ export class App {
defaultStatus = 404;
}
let mod = this.#manifest.pageMap.get(routeData.component)!;
let mod = await this.#manifest.pageMap.get(routeData.component)!();
if (routeData.type === 'page') {
let response = await this.#renderPage(request, routeData, mod, defaultStatus);
@ -148,7 +148,7 @@ export class App {
if (response.status === 500) {
const fiveHundredRouteData = matchRoute('/500', this.#manifestData);
if (fiveHundredRouteData) {
mod = this.#manifest.pageMap.get(fiveHundredRouteData.component)!;
mod = await this.#manifest.pageMap.get(fiveHundredRouteData.component)!();
try {
let fiveHundredResponse = await this.#renderPage(
request,

View file

@ -31,6 +31,7 @@ export interface RouteInfo {
export type SerializedRouteInfo = Omit<RouteInfo, 'routeData'> & {
routeData: SerializedRouteData;
};
type ImportComponentInstance = () => Promise<ComponentInstance>;
export interface SSRManifest {
adapterName: string;
@ -39,7 +40,7 @@ export interface SSRManifest {
base?: string;
assetsPrefix?: string;
markdown: MarkdownRenderingOptions;
pageMap: Map<ComponentPath, ComponentInstance>;
pageMap: Map<ComponentPath, ImportComponentInstance>;
renderers: SSRLoadedRenderer[];
/**
* Map of directive name (e.g. `load`) to the directive script code

View file

@ -169,15 +169,15 @@ async function generatePage(
.map(({ sheet }) => sheet)
.reduce(mergeInlineCss, []);
const pageModule = ssrEntry.pageMap?.get(pageData.component);
const pageModulePromise = ssrEntry.pageMap?.get(pageData.component);
const middleware = ssrEntry.middleware;
if (!pageModule) {
if (!pageModulePromise) {
throw new Error(
`Unable to find the module for ${pageData.component}. This is unexpected and likely a bug in Astro, please report.`
);
}
const pageModule = await pageModulePromise();
if (shouldSkipDraft(pageModule, opts.settings)) {
info(opts.logging, null, `${magenta('⚠️')} Skipping draft ${pageData.route.component}`);
return;

View file

@ -42,7 +42,10 @@ export function* walkParentInfos(
// Returns true if a module is a top-level page. We determine this based on whether
// it is imported by the top-level virtual module.
export function moduleIsTopLevelPage(info: ModuleInfo): boolean {
return info.importers[0] === resolvedPagesVirtualModuleId;
return (
info.importers[0] === resolvedPagesVirtualModuleId ||
info.dynamicImporters[0] == resolvedPagesVirtualModuleId
);
}
// This function walks the dependency graph, going up until it finds a page component.

View file

@ -29,7 +29,9 @@ function vitePluginPages(opts: StaticBuildOptions, internals: BuildInternals): V
let i = 0;
for (const pageData of eachPageData(internals)) {
const variable = `_page${i}`;
imports.push(`import * as ${variable} from ${JSON.stringify(pageData.moduleSpecifier)};`);
imports.push(
`const ${variable} = () => import(${JSON.stringify(pageData.moduleSpecifier)});`
);
importMap += `[${JSON.stringify(pageData.component)}, ${variable}],`;
i++;
}

View file

@ -3,6 +3,7 @@ import type { BuildInternals } from '../internal.js';
import type { AstroBuildPlugin } from '../plugin.js';
import type { StaticBuildOptions } from '../types';
import { extendManualChunks } from './util.js';
import path from 'node:path';
function vitePluginPrerender(opts: StaticBuildOptions, internals: BuildInternals): VitePlugin {
return {
@ -25,7 +26,7 @@ function vitePluginPrerender(opts: StaticBuildOptions, internals: BuildInternals
}
pageInfo.route.prerender = false;
// dynamic pages should all go in their own chunk in the pages/* directory
return `pages/all`;
return `pages/${path.basename(pageInfo.component)}`;
}
},
});

View file

@ -47,8 +47,10 @@ export interface StaticBuildOptions {
teardownCompiler: boolean;
}
type ImportComponentInstance = () => Promise<ComponentInstance>;
export interface SingleFileBuiltModule {
pageMap: Map<ComponentPath, ComponentInstance>;
pageMap: Map<ComponentPath, ImportComponentInstance>;
middleware: AstroMiddlewareInstance<unknown>;
renderers: SSRLoadedRenderer[];
}