diff --git a/packages/astro/src/core/app/index.ts b/packages/astro/src/core/app/index.ts index 9cf01f82d..9b6f6f577 100644 --- a/packages/astro/src/core/app/index.ts +++ b/packages/astro/src/core/app/index.ts @@ -212,11 +212,11 @@ export class App { env: this.#pipeline.env, mod: handler as any, }); - } else { + } const pathname = prependForwardSlash(this.removeBase(url.pathname)); const info = this.#routeDataToRouteInfo.get(routeData)!; // may be used in the future for handling rel=modulepreload, rel=icon, rel=manifest etc. - const links = new Set(); + const links = new Set(info.links.map(props => ({ props, children: '' }))); const styles = createStylesheetElementSet(info.styles); let scripts = new Set(); @@ -245,7 +245,6 @@ export class App { mod, env: this.#pipeline.env, }); - } } /** diff --git a/packages/astro/src/core/app/types.ts b/packages/astro/src/core/app/types.ts index 0050b5d7a..69eb83d6c 100644 --- a/packages/astro/src/core/app/types.ts +++ b/packages/astro/src/core/app/types.ts @@ -16,7 +16,10 @@ export type StylesheetAsset = export interface RouteInfo { routeData: RouteData; file: string; - links: string[]; + links: Array<{ + href: string + rel: 'modulepreload' + }>; scripts: // Integration injected ( | { children: string; stage: string } diff --git a/packages/astro/src/core/build/generate.ts b/packages/astro/src/core/build/generate.ts index a5b316554..496b70fae 100644 --- a/packages/astro/src/core/build/generate.ts +++ b/packages/astro/src/core/build/generate.ts @@ -261,7 +261,7 @@ async function generatePage( const pageInfo = getPageDataByComponent(pipeline.getInternals(), pageData.route.component); // may be used in the future for handling rel=modulepreload, rel=icon, rel=manifest etc. - const linkIds: [] = []; + const links = [...pageInfo?.preload.modules ?? []].map(href => ({ rel: 'modulepreload' as const, href })); const scripts = pageInfo?.hoistedScript ?? null; const styles = pageData.styles .sort(cssOrder) @@ -291,7 +291,7 @@ async function generatePage( const generationOptions: Readonly = { pageData, - linkIds, + links, scripts, styles, mod: pageModule, @@ -425,7 +425,10 @@ function getInvalidRouteSegmentError( interface GeneratePathOptions { pageData: PageBuildData; - linkIds: string[]; + links: Array<{ + rel: 'modulepreload' + href: string + }>; scripts: { type: 'inline' | 'external'; value: string } | null; styles: StylesheetAsset[]; mod: ComponentInstance; @@ -490,7 +493,7 @@ function getUrlForPath( async function generatePath(pathname: string, gopts: GeneratePathOptions, pipeline: BuildPipeline) { const manifest = pipeline.getManifest(); - const { mod, scripts: hoistedScripts, styles: _styles, pageData } = gopts; + const { mod, links: _links, scripts: hoistedScripts, styles: _styles, pageData } = gopts; // This adds the page name to the array so it can be shown as part of stats. if (pageData.route.type === 'page') { @@ -500,7 +503,7 @@ async function generatePath(pathname: string, gopts: GeneratePathOptions, pipeli pipeline.getEnvironment().logger.debug('build', `Generating: ${pathname}`); // may be used in the future for handling rel=modulepreload, rel=icon, rel=manifest etc. - const links = new Set(); + const links = new Set(_links.map(props => ({ props, children: '' }))); const scripts = createModuleScriptsSet( hoistedScripts ? [hoistedScripts] : [], manifest.base, diff --git a/packages/astro/src/core/build/page-data.ts b/packages/astro/src/core/build/page-data.ts index da002a051..a61113238 100644 --- a/packages/astro/src/core/build/page-data.ts +++ b/packages/astro/src/core/build/page-data.ts @@ -55,6 +55,11 @@ export async function collectPagesData( propagatedStyles: new Map(), propagatedScripts: new Map(), hoistedScript: undefined, + preload: { + modules: new Set, + fonts: new Set, + styles: new Set + }, }; clearInterval(routeCollectionLogTimeout); @@ -78,6 +83,11 @@ export async function collectPagesData( propagatedStyles: new Map(), propagatedScripts: new Map(), hoistedScript: undefined, + preload: { + modules: new Set, + fonts: new Set, + styles: new Set + }, }; } diff --git a/packages/astro/src/core/build/plugins/plugin-hoisted-scripts.ts b/packages/astro/src/core/build/plugins/plugin-hoisted-scripts.ts index 5c6b40992..4b3055ae8 100644 --- a/packages/astro/src/core/build/plugins/plugin-hoisted-scripts.ts +++ b/packages/astro/src/core/build/plugins/plugin-hoisted-scripts.ts @@ -67,14 +67,17 @@ export function vitePluginHoistedScripts( }); for (const [id, output] of considerInlining.entries()) { + const canBeInlined = importedByOtherScripts.has(output.fileName) === false && output.imports.length === 0 && output.dynamicImports.length === 0 && Buffer.byteLength(output.code) <= assetInlineLimit; + let removeFromBundle = false; - const facadeId = output.facadeModuleId!; - const pages = internals.hoistedScriptIdToPagesMap.get(facadeId)!; + + const pages = internals.hoistedScriptIdToPagesMap.get(output.facadeModuleId!)!; + for (const pathname of pages) { const vid = viteID(new URL('.' + pathname, settings.config.root)); const pageInfo = getPageDataByViteID(internals, vid); @@ -91,6 +94,10 @@ export function vitePluginHoistedScripts( value: id, }; } + + for (const importedScript of output.imports) { + pageInfo.preload.modules.add(importedScript) + } } } diff --git a/packages/astro/src/core/build/plugins/plugin-manifest.ts b/packages/astro/src/core/build/plugins/plugin-manifest.ts index 41ceb282c..d4cd368e1 100644 --- a/packages/astro/src/core/build/plugins/plugin-manifest.ts +++ b/packages/astro/src/core/build/plugins/plugin-manifest.ts @@ -210,7 +210,7 @@ function buildManifest( } // may be used in the future for handling rel=modulepreload, rel=icon, rel=manifest etc. - const links: [] = []; + const links = [...pageData.preload.modules].map(href => ({ rel: 'modulepreload' as const, href })); const styles = pageData.styles .sort(cssOrder) diff --git a/packages/astro/src/core/build/types.ts b/packages/astro/src/core/build/types.ts index a51fc8d00..4d577d020 100644 --- a/packages/astro/src/core/build/types.ts +++ b/packages/astro/src/core/build/types.ts @@ -25,6 +25,11 @@ export interface PageBuildData { component: ComponentPath; route: RouteData; moduleSpecifier: string; + preload: { + modules: Set + fonts: Set + styles: Set + }; propagatedStyles: Map>; propagatedScripts: Map>; hoistedScript: { type: 'inline' | 'external'; value: string } | undefined;