Next.js Route Loader & Mini CSS Extract Plugin - prefetch와 CSS chunk 에러 처리
prefetchViaDom - route-loader.ts
function prefetchViaDom(
href: string,
as: string,
link?: HTMLLinkElement
): Promise<any> {
return new Promise<void>((resolve, reject) => {
const selector = `
link[rel="prefetch"][href^="${href}"],
link[rel="preload"][href^="${href}"],
script[src^="${href}"]`
if (document.querySelector(selector)) {
return resolve()
}
link = document.createElement('link')
// The order of property assignment here is intentional:
if (as) link!.as = as
link!.rel = `prefetch`
link!.crossOrigin = process.env.__NEXT_CROSS_ORIGIN!
link!.onload = resolve as any
link!.onerror = () =>
reject(markAssetError(new Error(`Failed to prefetch: ${href}`)))
// `href` should always be last:
link!.href = href
document.head.appendChild(link)
})
}
- 이미 prefetch/preload된 리소스면 스킵
<link rel="prefetch">생성 후 head에 추가href는 항상 마지막에 설정 (브라우저 요청 타이밍 제어)
CSS Chunk Load Error - Mini CSS Extract Plugin
Template.indent([
"var errorType = event && event.type;",
"var realHref = event && event.target && event.target.href || fullhref;",
'var err = new Error("Loading CSS chunk " + chunkId + " failed.\\n(" + errorType + ": " + realHref + ")");',
'err.name = "ChunkLoadError";',
// TODO remove `code` in the future major release to align with webpack
'err.code = "CSS_CHUNK_LOAD_FAILED";',
"err.type = errorType;",
"err.request = realHref;",
"if (linkTag.parentNode) linkTag.parentNode.removeChild(linkTag)",
"reject(err);",
]),
ChunkLoadError커스텀 에러 생성- 실패한
<link>태그 DOM에서 제거 후 reject