next.js/packages/next/src/build/babel/loader/index.ts
index.ts83 lines2.3 KB
import type { Span } from '../../../trace'
import transform from './transform'
import type { NextJsLoaderContext } from './types'
import type { SourceMap } from './util'
import type { webpack } from 'next/dist/compiled/webpack/webpack'

async function nextBabelLoader(
  ctx: NextJsLoaderContext,
  parentTrace: Span,
  inputSource: string,
  inputSourceMap: SourceMap | null | undefined
): Promise<[string, SourceMap | null | undefined]> {
  const filename = ctx.resourcePath

  // Ensure `.d.ts` are not processed.
  if (filename.endsWith('.d.ts')) {
    return [inputSource, inputSourceMap]
  }

  const target = ctx.target
  const loaderOptions: any = parentTrace
    .traceChild('get-options')
    // @ts-ignore TODO: remove ignore once webpack 5 types are used
    .traceFn(() => ctx.getOptions())

  if (loaderOptions.exclude && loaderOptions.exclude(filename)) {
    return [inputSource, inputSourceMap]
  }

  const loaderSpanInner = parentTrace.traceChild('next-babel-turbo-transform')
  const { code: transformedSource, map: outputSourceMap } =
    await loaderSpanInner.traceAsyncFn(
      async () =>
        await transform(
          ctx,
          inputSource,
          inputSourceMap,
          loaderOptions,
          filename,
          target,
          loaderSpanInner
        )
    )

  return [transformedSource, outputSourceMap]
}

function nextBabelLoaderOuter(
  this: NextJsLoaderContext,
  inputSource: string,
  // webpack's source map format is compatible with babel, but the type signature doesn't match
  inputSourceMap?: any
) {
  const callback = this.async()

  const loaderSpan = this.currentTraceSpan.traceChild('next-babel-turbo-loader')
  loaderSpan
    .traceAsyncFn(() =>
      nextBabelLoader(this, loaderSpan, inputSource, inputSourceMap)
    )
    .then(
      ([transformedSource, outputSourceMap]) =>
        callback?.(
          /* err */ null,
          transformedSource,
          outputSourceMap ?? inputSourceMap
        ),
      (err) => {
        callback?.(err)
      }
    )
}

// check this type matches `webpack.LoaderDefinitionFunction`, but be careful
// not to publicly rely on the webpack type since the generated typescript
// declarations will be wrong.
const _nextBabelLoaderOuter: webpack.LoaderDefinitionFunction<
  {},
  NextJsLoaderContext
> = nextBabelLoaderOuter

export default nextBabelLoaderOuter
Quest for Codev2.0.0
/
SIGN IN