modulepreload
This commit is contained in:
parent
a8b979ef40
commit
4eeca70fc6
7 changed files with 39 additions and 12 deletions
|
@ -212,11 +212,11 @@ export class App {
|
||||||
env: this.#pipeline.env,
|
env: this.#pipeline.env,
|
||||||
mod: handler as any,
|
mod: handler as any,
|
||||||
});
|
});
|
||||||
} else {
|
}
|
||||||
const pathname = prependForwardSlash(this.removeBase(url.pathname));
|
const pathname = prependForwardSlash(this.removeBase(url.pathname));
|
||||||
const info = this.#routeDataToRouteInfo.get(routeData)!;
|
const info = this.#routeDataToRouteInfo.get(routeData)!;
|
||||||
// may be used in the future for handling rel=modulepreload, rel=icon, rel=manifest etc.
|
// may be used in the future for handling rel=modulepreload, rel=icon, rel=manifest etc.
|
||||||
const links = new Set<never>();
|
const links = new Set(info.links.map(props => ({ props, children: '' })));
|
||||||
const styles = createStylesheetElementSet(info.styles);
|
const styles = createStylesheetElementSet(info.styles);
|
||||||
|
|
||||||
let scripts = new Set<SSRElement>();
|
let scripts = new Set<SSRElement>();
|
||||||
|
@ -245,7 +245,6 @@ export class App {
|
||||||
mod,
|
mod,
|
||||||
env: this.#pipeline.env,
|
env: this.#pipeline.env,
|
||||||
});
|
});
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -16,7 +16,10 @@ export type StylesheetAsset =
|
||||||
export interface RouteInfo {
|
export interface RouteInfo {
|
||||||
routeData: RouteData;
|
routeData: RouteData;
|
||||||
file: string;
|
file: string;
|
||||||
links: string[];
|
links: Array<{
|
||||||
|
href: string
|
||||||
|
rel: 'modulepreload'
|
||||||
|
}>;
|
||||||
scripts: // Integration injected
|
scripts: // Integration injected
|
||||||
(
|
(
|
||||||
| { children: string; stage: string }
|
| { children: string; stage: string }
|
||||||
|
|
|
@ -261,7 +261,7 @@ async function generatePage(
|
||||||
const pageInfo = getPageDataByComponent(pipeline.getInternals(), pageData.route.component);
|
const pageInfo = getPageDataByComponent(pipeline.getInternals(), pageData.route.component);
|
||||||
|
|
||||||
// may be used in the future for handling rel=modulepreload, rel=icon, rel=manifest etc.
|
// 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 scripts = pageInfo?.hoistedScript ?? null;
|
||||||
const styles = pageData.styles
|
const styles = pageData.styles
|
||||||
.sort(cssOrder)
|
.sort(cssOrder)
|
||||||
|
@ -291,7 +291,7 @@ async function generatePage(
|
||||||
|
|
||||||
const generationOptions: Readonly<GeneratePathOptions> = {
|
const generationOptions: Readonly<GeneratePathOptions> = {
|
||||||
pageData,
|
pageData,
|
||||||
linkIds,
|
links,
|
||||||
scripts,
|
scripts,
|
||||||
styles,
|
styles,
|
||||||
mod: pageModule,
|
mod: pageModule,
|
||||||
|
@ -425,7 +425,10 @@ function getInvalidRouteSegmentError(
|
||||||
|
|
||||||
interface GeneratePathOptions {
|
interface GeneratePathOptions {
|
||||||
pageData: PageBuildData;
|
pageData: PageBuildData;
|
||||||
linkIds: string[];
|
links: Array<{
|
||||||
|
rel: 'modulepreload'
|
||||||
|
href: string
|
||||||
|
}>;
|
||||||
scripts: { type: 'inline' | 'external'; value: string } | null;
|
scripts: { type: 'inline' | 'external'; value: string } | null;
|
||||||
styles: StylesheetAsset[];
|
styles: StylesheetAsset[];
|
||||||
mod: ComponentInstance;
|
mod: ComponentInstance;
|
||||||
|
@ -490,7 +493,7 @@ function getUrlForPath(
|
||||||
|
|
||||||
async function generatePath(pathname: string, gopts: GeneratePathOptions, pipeline: BuildPipeline) {
|
async function generatePath(pathname: string, gopts: GeneratePathOptions, pipeline: BuildPipeline) {
|
||||||
const manifest = pipeline.getManifest();
|
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.
|
// This adds the page name to the array so it can be shown as part of stats.
|
||||||
if (pageData.route.type === 'page') {
|
if (pageData.route.type === 'page') {
|
||||||
|
@ -500,7 +503,7 @@ async function generatePath(pathname: string, gopts: GeneratePathOptions, pipeli
|
||||||
pipeline.getEnvironment().logger.debug('build', `Generating: ${pathname}`);
|
pipeline.getEnvironment().logger.debug('build', `Generating: ${pathname}`);
|
||||||
|
|
||||||
// may be used in the future for handling rel=modulepreload, rel=icon, rel=manifest etc.
|
// may be used in the future for handling rel=modulepreload, rel=icon, rel=manifest etc.
|
||||||
const links = new Set<never>();
|
const links = new Set(_links.map(props => ({ props, children: '' })));
|
||||||
const scripts = createModuleScriptsSet(
|
const scripts = createModuleScriptsSet(
|
||||||
hoistedScripts ? [hoistedScripts] : [],
|
hoistedScripts ? [hoistedScripts] : [],
|
||||||
manifest.base,
|
manifest.base,
|
||||||
|
|
|
@ -55,6 +55,11 @@ export async function collectPagesData(
|
||||||
propagatedStyles: new Map(),
|
propagatedStyles: new Map(),
|
||||||
propagatedScripts: new Map(),
|
propagatedScripts: new Map(),
|
||||||
hoistedScript: undefined,
|
hoistedScript: undefined,
|
||||||
|
preload: {
|
||||||
|
modules: new Set,
|
||||||
|
fonts: new Set,
|
||||||
|
styles: new Set
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
clearInterval(routeCollectionLogTimeout);
|
clearInterval(routeCollectionLogTimeout);
|
||||||
|
@ -78,6 +83,11 @@ export async function collectPagesData(
|
||||||
propagatedStyles: new Map(),
|
propagatedStyles: new Map(),
|
||||||
propagatedScripts: new Map(),
|
propagatedScripts: new Map(),
|
||||||
hoistedScript: undefined,
|
hoistedScript: undefined,
|
||||||
|
preload: {
|
||||||
|
modules: new Set,
|
||||||
|
fonts: new Set,
|
||||||
|
styles: new Set
|
||||||
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -67,14 +67,17 @@ export function vitePluginHoistedScripts(
|
||||||
});
|
});
|
||||||
|
|
||||||
for (const [id, output] of considerInlining.entries()) {
|
for (const [id, output] of considerInlining.entries()) {
|
||||||
|
|
||||||
const canBeInlined =
|
const canBeInlined =
|
||||||
importedByOtherScripts.has(output.fileName) === false &&
|
importedByOtherScripts.has(output.fileName) === false &&
|
||||||
output.imports.length === 0 &&
|
output.imports.length === 0 &&
|
||||||
output.dynamicImports.length === 0 &&
|
output.dynamicImports.length === 0 &&
|
||||||
Buffer.byteLength(output.code) <= assetInlineLimit;
|
Buffer.byteLength(output.code) <= assetInlineLimit;
|
||||||
|
|
||||||
let removeFromBundle = false;
|
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) {
|
for (const pathname of pages) {
|
||||||
const vid = viteID(new URL('.' + pathname, settings.config.root));
|
const vid = viteID(new URL('.' + pathname, settings.config.root));
|
||||||
const pageInfo = getPageDataByViteID(internals, vid);
|
const pageInfo = getPageDataByViteID(internals, vid);
|
||||||
|
@ -91,6 +94,10 @@ export function vitePluginHoistedScripts(
|
||||||
value: id,
|
value: id,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (const importedScript of output.imports) {
|
||||||
|
pageInfo.preload.modules.add(importedScript)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -210,7 +210,7 @@ function buildManifest(
|
||||||
}
|
}
|
||||||
|
|
||||||
// may be used in the future for handling rel=modulepreload, rel=icon, rel=manifest etc.
|
// 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
|
const styles = pageData.styles
|
||||||
.sort(cssOrder)
|
.sort(cssOrder)
|
||||||
|
|
|
@ -25,6 +25,11 @@ export interface PageBuildData {
|
||||||
component: ComponentPath;
|
component: ComponentPath;
|
||||||
route: RouteData;
|
route: RouteData;
|
||||||
moduleSpecifier: string;
|
moduleSpecifier: string;
|
||||||
|
preload: {
|
||||||
|
modules: Set<string>
|
||||||
|
fonts: Set<string>
|
||||||
|
styles: Set<string>
|
||||||
|
};
|
||||||
propagatedStyles: Map<string, Set<StylesheetAsset>>;
|
propagatedStyles: Map<string, Set<StylesheetAsset>>;
|
||||||
propagatedScripts: Map<string, Set<string>>;
|
propagatedScripts: Map<string, Set<string>>;
|
||||||
hoistedScript: { type: 'inline' | 'external'; value: string } | undefined;
|
hoistedScript: { type: 'inline' | 'external'; value: string } | undefined;
|
||||||
|
|
Loading…
Reference in a new issue