Next.js의 router-loader.ts #prefetchViaDom()

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) 역할을 하며 주요 특징은 다음과 같다.

  • 이미 prefetch 또는 preload된 리소스인지 확인.
  • 새로운 요소를 생성하여 리소스를 prefetch.
  • 로드 성공 또는 실패 시 적절한 처리.

Webpack의 Mini CSS Extract Plugin에서 CSS 청크 로드 실패 시 에러 처리 코드를 볼 수 있다.

 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);",
]),

이 코드는 CSS 청크 로드 실패 시 발생하는 에러를 처리하며 주요 특징은 다음과 같다.

  1. 에러 타입과 실제 URL을 파악.
  2. 상세한 에러 메시지를 생성.
  3. 에러 객체에 추가 정보(name, code, type, request)를 설정.
  4. 실패한 <link> 태그를 DOM에서 제거.
  5. Promisereject하여 에러를 전파.

이 플러그인은 CSS를 별도의 파일로 추출하는 데 사용되며, 위 코드는 그 과정에서 발생할 수 있는 오류를 처리하는 중요한 부분.

#306