Repository: vitejs/vite
File: packages/vite/src/node/optimizer/scan.ts (TypeScript)

Code before:
    const deps: Record<string, string> = {}
    const missing: Record<string, string> = {}

    let context: BuildContext | undefined
    try {
      esbuildContext = prepareEsbuildScanner(
        environment,
        entries,
        deps,
        missing,
      )
      context = await esbuildContext
      if (scanContext.cancelled) return

      try {
        await context!.rebuild()
        return {
          // Ensure a fixed order so hashes are stable and improve logs
          deps: orderedDependencies(deps),
          missing,
        }
      } catch (e) {
        if (e.errors && e.message.includes('The build was canceled')) {
          // esbuild logs an error when cancelling, but this is expected so
          // return an empty result instead
          return { deps: {}, missing: {} }
        }

        const prependMessage = colors.red(`\
  Failed to scan for dependencies from entries:
  ${entries.join('\n')}

  `)
        if (e.errors) {
          const msgs = await formatMessages(e.errors, {
            kind: 'error',
            color: true,
          })
          e.message = prependMessage + msgs.join('\n')
        } else {
          e.message = prependMessage + e.message
        }
        throw e
      } finally {
        if (debug) {
          const duration = (performance.now() - start).toFixed(2)
          const depsStr =
            Object.keys(orderedDependencies(deps))
              .sort()
              .map((id) => `\n  ${colors.cyan(id)} -> ${colors.dim(deps[id])}`)
              .join('') || colors.dim('no dependencies found')

Review comment (suggestion):
Should this return `undefined` like in line 168? Now that there is a fallback at 222, maybe it is good to normalize it. Or if not, return `{ deps: {}, missing: {} }` everywhere instead of the fallback 

Code after:
    const deps: Record<string, string> = {}
    const missing: Record<string, string> = {}

    let context: BuildContext | undefined
    try {
      esbuildContext = prepareEsbuildScanner(
        environment,
        entries,
        deps,
        missing,
      )
      context = await esbuildContext
      if (scanContext.cancelled) return

      try {
        await context!.rebuild()
        return {
          // Ensure a fixed order so hashes are stable and improve logs
          deps: orderedDependencies(deps),
          missing,
        }
      } catch (e) {
        if (e.errors && e.message.includes('The build was canceled')) {
          // esbuild logs an error when cancelling, but this is expected so
          // return an empty result instead
          return
        }

        const prependMessage = colors.red(`\
  Failed to scan for dependencies from entries:
  ${entries.join('\n')}

  `)
        if (e.errors) {
          const msgs = await formatMessages(e.errors, {
            kind: 'error',
            color: true,
          })
          e.message = prependMessage + msgs.join('\n')
        } else {
          e.message = prependMessage + e.message
        }
        throw e
      } finally {
        if (debug) {
          const duration = (performance.now() - start).toFixed(2)
          const depsStr =
            Object.keys(orderedDependencies(deps))
              .sort()
              .map((id) => `\n  ${colors.cyan(id)} -> ${colors.dim(deps[id])}`)
              .join('') || colors.dim('no dependencies found')