feat: expose page and assets on build hooks TransformContext

pull/2104/head
Evan You 2 years ago
parent b86988333b
commit 468c049ccd

@ -59,6 +59,12 @@ export async function build(
(chunk) => chunk.type === 'asset' && chunk.fileName.endsWith('.css') (chunk) => chunk.type === 'asset' && chunk.fileName.endsWith('.css')
) as OutputAsset ) as OutputAsset
const assets = (siteConfig.mpa ? serverResult : clientResult).output
.filter(
(chunk) => chunk.type === 'asset' && !chunk.fileName.endsWith('.css')
)
.map((asset) => siteConfig.site.base + asset.fileName)
// We embed the hash map and site config strings into each page directly // We embed the hash map and site config strings into each page directly
// so that it doesn't alter the main chunk's hash on every build. // so that it doesn't alter the main chunk's hash on every build.
// It's also embedded as a string and JSON.parsed from the client because // It's also embedded as a string and JSON.parsed from the client because
@ -79,6 +85,7 @@ export async function build(
clientResult, clientResult,
appChunk, appChunk,
cssChunk, cssChunk,
assets,
pageToHashMap, pageToHashMap,
hashMapString, hashMapString,
siteDataString siteDataString

@ -26,6 +26,7 @@ export async function renderPage(
result: RollupOutput | null, result: RollupOutput | null,
appChunk: OutputChunk | undefined, appChunk: OutputChunk | undefined,
cssChunk: OutputAsset | undefined, cssChunk: OutputAsset | undefined,
assets: string[],
pageToHashMap: Record<string, string>, pageToHashMap: Record<string, string>,
hashMapString: string, hashMapString: string,
siteDataString: string siteDataString: string
@ -86,21 +87,18 @@ export async function renderPage(
preloadLinks = preloadLinks.filter((link) => shouldPreload(link, page)) preloadLinks = preloadLinks.filter((link) => shouldPreload(link, page))
} }
const preloadLinksString = preloadLinks const toHeadTags = (files: string[], rel: string): HeadConfig[] =>
.map((file) => { files.map((file) => [
return `<link rel="modulepreload" href="${ 'link',
EXTERNAL_URL_RE.test(file) ? '' : siteData.base // don't add base to external urls {
}${file}">` rel,
}) // don't add base to external urls
.join('\n ') href: (EXTERNAL_URL_RE.test(file) ? '' : siteData.base) + file
}
])
const prefetchLinkString = prefetchLinks const preloadHeadTags = toHeadTags(preloadLinks, 'modulepreload')
.map((file) => { const prefetchHeadTags = toHeadTags(prefetchLinks, 'prefetch')
return `<link rel="prefetch" href="${
EXTERNAL_URL_RE.test(file) ? '' : siteData.base // don't add base to external urls
}${file}">`
})
.join('\n ')
const stylesheetLink = cssChunk const stylesheetLink = cssChunk
? `<link rel="preload stylesheet" href="${siteData.base}${cssChunk.fileName}" as="style">` ? `<link rel="preload stylesheet" href="${siteData.base}${cssChunk.fileName}" as="style">`
@ -109,21 +107,27 @@ export async function renderPage(
const title: string = createTitle(siteData, pageData) const title: string = createTitle(siteData, pageData)
const description: string = pageData.description || siteData.description const description: string = pageData.description || siteData.description
const headBeforeTransform = mergeHead( const headBeforeTransform = [
siteData.head, ...preloadHeadTags,
filterOutHeadDescription(pageData.frontmatter.head) ...prefetchHeadTags,
) ...mergeHead(
siteData.head,
filterOutHeadDescription(pageData.frontmatter.head)
)
]
const head = mergeHead( const head = mergeHead(
headBeforeTransform, headBeforeTransform,
(await config.transformHead?.({ (await config.transformHead?.({
page,
siteConfig: config, siteConfig: config,
siteData, siteData,
pageData, pageData,
title, title,
description, description,
head: headBeforeTransform, head: headBeforeTransform,
content content,
assets
})) || [] })) || []
) )
@ -165,8 +169,6 @@ export async function renderPage(
? `<script type="module" src="${siteData.base}${appChunk.fileName}"></script>` ? `<script type="module" src="${siteData.base}${appChunk.fileName}"></script>`
: `` : ``
} }
${preloadLinksString}
${prefetchLinkString}
${await renderHead(head)} ${await renderHead(head)}
</head> </head>
<body>${teleports?.body || ''} <body>${teleports?.body || ''}
@ -179,13 +181,15 @@ export async function renderPage(
await fs.ensureDir(path.dirname(htmlFileName)) await fs.ensureDir(path.dirname(htmlFileName))
const transformedHtml = await config.transformHtml?.(html, htmlFileName, { const transformedHtml = await config.transformHtml?.(html, htmlFileName, {
page,
siteConfig: config, siteConfig: config,
siteData, siteData,
pageData, pageData,
title, title,
description, description,
head, head,
content content,
assets
}) })
await fs.writeFile(htmlFileName, transformedHtml || html) await fs.writeFile(htmlFileName, transformedHtml || html)
} }

@ -43,6 +43,7 @@ export interface UserConfig<ThemeConfig = any>
srcExclude?: string[] srcExclude?: string[]
outDir?: string outDir?: string
cacheDir?: string cacheDir?: string
shouldPreload?: (link: string, page: string) => boolean shouldPreload?: (link: string, page: string) => boolean
locales?: LocaleConfig<ThemeConfig> locales?: LocaleConfig<ThemeConfig>
@ -142,6 +143,7 @@ export interface UserConfig<ThemeConfig = any>
} }
export interface TransformContext { export interface TransformContext {
page: string
siteConfig: SiteConfig siteConfig: SiteConfig
siteData: SiteData siteData: SiteData
pageData: PageData pageData: PageData
@ -149,6 +151,7 @@ export interface TransformContext {
description: string description: string
head: HeadConfig[] head: HeadConfig[]
content: string content: string
assets: string[]
} }
export type RawConfigExports<ThemeConfig = any> = export type RawConfigExports<ThemeConfig = any> =

Loading…
Cancel
Save