ronantakizawa/codereview-bench huggingface dataset:
Repository: vitejs/vite
File: packages/vite/src/node/ssr/runtime/__tests__/server-source-maps.spec.ts (TypeScript)

Code before:

  it('deep stacktrace', async ({ runner, server }) => {
    const methodError = await getError(async () => {
      const mod = await runner.import('/fixtures/has-error-deep.ts')
      mod.main()
    })
    expect(serializeStackDeep(server, methodError).slice(0, 3)).toEqual([
      'Error: crash',
      '    at crash (<root>/fixtures/has-error-deep.ts:2:9)',
      '    at Module.main (<root>/fixtures/has-error-deep.ts:6:3)',
    ])
  })

  it('should not crash when sourceMappingURL pattern appears in string literals', async ({
    runner,
  }) => {
    const modules = runner.evaluatedModules

    const moduleId = '/test/string-literal-sourcemap.js'
    const moduleUrl = 'http://localhost:3000/test/string-literal-sourcemap.js'
    const node = modules.ensureModule(moduleId, moduleUrl)

    node.meta = {
      code: `const text = "//# sourceMappingURL=data:application/json;base64,invalidbase64";
console.log(text);`,
    }

    expect(() => {
      const sourceMap = modules.getModuleSourceMapById(moduleId)
      expect(sourceMap).toBeNull()
    }).not.toThrow()
  })
})


Review comment (suggestion):
@copilot Add a fixture and use `await getError` like above.

Code after:

  it('deep stacktrace', async ({ runner, server }) => {
    const methodError = await getError(async () => {
      const mod = await runner.import('/fixtures/has-error-deep.ts')
      mod.main()
    })
    expect(serializeStackDeep(server, methodError).slice(0, 3)).toEqual([
      'Error: crash',
      '    at crash (<root>/fixtures/has-error-deep.ts:2:9)',
      '    at Module.main (<root>/fixtures/has-error-deep.ts:6:3)',
    ])
  })

  it('should not crash when sourceMappingURL pattern appears in string literals', async ({
    runner,
    server,
  }) => {
    const mod = await runner.import('/fixtures/string-literal-sourcemap.ts')
    expect(mod.getMessage()).toBe(
      '//# sourceMappingURL=data:application/json;base64,invalidbase64',
    )
    const error = await getError(() => mod.throwError())
    expect(error.message).toBe('Test error for stacktrace')
    expect(serializeStackDeep(server, error).slice(0, 2)).toEqual([
      'Error: Test error for stacktrace',
      '    at Module.throwError (<root>/fixtures/string-literal-sourcemap.ts:11:9)',
    ])
  })
})
Repository: vitejs/vite
File: packages/vite/src/node/plugins/worker.ts (TypeScript)

Code before:
  referencedAssets: Set<string>
  watchedFiles: string[]
}

type WorkerBundleAsset = {
  fileName: string
  /** @deprecated */
  originalFileName: string | null
  originalFileNames: string[]
  source: string | Uint8Array
}

class WorkerOutputCache {
  /**
   * worker bundle information for each input id
   * used to bundle the same worker file only once
   */
  private bundles = new Map<
    /* inputId */ string,
    {
      entryFilename: string
      entryCode: string
      entryUrlPlaceholder: string
      referencedAssets: Set<string>
      watchedFiles: string[]
    }
  >()
  /** list of assets emitted for the worker bundles */
  private assets = new Map<string, WorkerBundleAsset>()
  private fileNameHash = new Map<
    /* hash */ string,
    /* entryFilename */ string
  >()
  private invalidatedBundles = new Set</* inputId */ string>()

  saveWorkerBundle(
    file: string,
    watchedFiles: string[],
    outputEntryFilename: string,
    outputEntryCode: string,
    outputAssets: WorkerBundleAsset[],
    logger: Logger,
  ): WorkerBundle {
    for (const asset of outputAssets) {
      this.saveAsset(asset, logger)
    }
    const bundle: WorkerBundle = {
      entryFilename: outputEntryFilename,
      entryCode: outputEntryCode,
      entryUrlPlaceholder:
        this.generateEntryUrlPlaceholder(outputEntryFilename),

Review comment (suggestion):
Looks like we can use the `WorkerBundle` type here

Code after:
  referencedAssets: Set<string>
  watchedFiles: string[]
}

type WorkerBundleAsset = {
  fileName: string
  /** @deprecated */
  originalFileName: string | null
  originalFileNames: string[]
  source: string | Uint8Array
}

class WorkerOutputCache {
  /**
   * worker bundle information for each input id
   * used to bundle the same worker file only once
   */
  private bundles = new Map</* inputId */ string, WorkerBundle>()
  /** list of assets emitted for the worker bundles */
  private assets = new Map<string, WorkerBundleAsset>()
  private fileNameHash = new Map<
    /* hash */ string,
    /* entryFilename */ string
  >()
  private invalidatedBundles = new Set</* inputId */ string>()

  saveWorkerBundle(
    file: string,
    watchedFiles: string[],
    outputEntryFilename: string,
    outputEntryCode: string,
    outputAssets: WorkerBundleAsset[],
    logger: Logger,
  ): WorkerBundle {
    for (const asset of outputAssets) {
      this.saveAsset(asset, logger)
    }
    const bundle: WorkerBundle = {
      entryFilename: outputEntryFilename,
      entryCode: outputEntryCode,
      entryUrlPlaceholder:
        this.generateEntryUrlPlaceholder(outputEntryFilename),
      referencedAssets: new Set(outputAssets.map((asset) => asset.fileName)),
      watchedFiles,
    }
    this.bundles.set(file, bundle)
    return bundle
  }

  saveAsset(asset: WorkerBundleAsset, logger: Logger) {
    const duplicateAsset = this.assets.get(asset.fileName)
Repository: vitejs/vite
File: packages/vite/src/node/cli.ts (TypeScript)

Code before:
import path from 'node:path'
import fs from 'node:fs'
import { performance } from 'node:perf_hooks'
import { cac } from 'cac'
import colors from 'picocolors'
import { VERSION } from './constants'
import type { BuildEnvironmentOptions } from './build'
import type { ServerOptions } from './server'
import type { CLIShortcut } from './shortcuts'
import type { LogLevel } from './logger'
import { createLogger } from './logger'
import { resolveConfig } from './config'
import type { InlineConfig } from './config'

/**
 * Check if the current Node.js version is supported
 * @returns true if the version is supported, false otherwise
 */
export function checkNodeVersion(): boolean {
  const currentVersion = process.versions.node.split('.')
  const major = parseInt(currentVersion[0], 10)
  const minor = parseInt(currentVersion[1], 10)
  const patch = parseInt(currentVersion[2], 10)

  const isSupported =
    (major === 20 && (minor > 19 || (minor === 19 && patch >= 0))) ||
    (major === 22 && minor >= 12) ||
    major > 22

  return isSupported
}

// Check Node.js version before proceeding
if (!checkNodeVersion()) {
  // eslint-disable-next-line no-console
  console.warn(
    colors.yellow(
      `You are using Node.js ${process.versions.node}. ` +
        `Vite requires Node.js version 20.19+ or 22.12+. ` +
        `Please upgrade your Node.js version.`,
    ),
  )
}

const cli = cac('vite')

Review comment (suggestion):
@copilot receive `process.versions.node` as a parameter to avoid mocking `process.versions.node`.

Code after:
import path from 'node:path'
import fs from 'node:fs'
import { performance } from 'node:perf_hooks'
import { cac } from 'cac'
import colors from 'picocolors'
import { VERSION } from './constants'
import type { BuildEnvironmentOptions } from './build'
import type { ServerOptions } from './server'
import type { CLIShortcut } from './shortcuts'
import type { LogLevel } from './logger'
import { createLogger } from './logger'
import { resolveConfig } from './config'
import type { InlineConfig } from './config'

export function checkNodeVersion(nodeVersion: string): boolean {
  const currentVersion = nodeVersion.split('.')
  const major = parseInt(currentVersion[0], 10)
  const minor = parseInt(currentVersion[1], 10)
  const isSupported =
    (major === 20 && minor >= 19) || (major === 22 && minor >= 12) || major > 22
  return isSupported
}

if (!checkNodeVersion(process.versions.node)) {
  // eslint-disable-next-line no-console
  console.warn(
    colors.yellow(
      `You are using Node.js ${process.versions.node}. ` +
        `Vite requires Node.js version 20.19+ or 22.12+. ` +
        `Please upgrade your Node.js version.`,
    ),
  )
}

const cli = cac('vite')

// global options
interface GlobalCLIOptions {
  '--'?: string[]
  c?: boolean | string
  config?: string
  base?: string
  l?: LogLevel
  logLevel?: LogLevel
  clearScreen?: boolean
Repository: vitejs/vite
File: packages/vite/src/node/__tests__/cli.spec.ts (TypeScript)

Code before:
import { describe, expect, test } from 'vitest'
import { checkNodeVersion } from '../cli'

describe('CLI Node.js version checking', () => {
  test.each([
    // Unsupported versions
    ['18.20.0', false],
    ['20.18.5', false],
    ['22.11.0', false],
    // Supported versions
    ['20.19.0', true],
    ['20.20.1', true],
    ['22.12.0', true],
    ['22.13.1', true],
    ['23.0.0', true],
  ])('should return %p for Node.js version %s', (version, expected) => {
    const result = checkNodeVersion(version)
    expect(result).toBe(expected)
  })
})


Review comment (suggestion):
```suggestion
  ])('should return %1 for Node.js version %0', (version, expected) => {
```

Code after:
import { describe, expect, test } from 'vitest'
import { checkNodeVersion } from '../cli'

describe('CLI Node.js version checking', () => {
  test.each([
    // Unsupported versions
    ['18.20.0', false],
    ['20.18.5', false],
    ['22.11.0', false],
    // Supported versions
    ['20.19.0', true],
    ['20.20.1', true],
    ['22.12.0', true],
    ['22.13.1', true],
    ['23.0.0', true],
  ])('should return %1 for Node.js version %0', (version, expected) => {
    const result = checkNodeVersion(version)
    expect(result).toBe(expected)
  })
})
Repository: vitejs/vite
File: packages/vite/src/node/cli.ts (TypeScript)

Code before:
import path from 'node:path'
import fs from 'node:fs'
import { performance } from 'node:perf_hooks'
import { cac } from 'cac'
import colors from 'picocolors'
import { VERSION } from './constants'
import type { BuildEnvironmentOptions } from './build'
import type { ServerOptions } from './server'
import type { CLIShortcut } from './shortcuts'
import type { LogLevel } from './logger'
import { createLogger } from './logger'
import { resolveConfig } from './config'
import type { InlineConfig } from './config'

export function checkNodeVersion(nodeVersion: string): boolean {
  const currentVersion = nodeVersion.split('.')
  const major = parseInt(currentVersion[0], 10)
  const minor = parseInt(currentVersion[1], 10)
  const isSupported =
    (major === 20 && minor >= 19) ||
    (major === 22 && minor >= 12) ||
    major > 22
  return isSupported
}

if (!checkNodeVersion(process.versions.node)) {
  // eslint-disable-next-line no-console
  console.warn(
    colors.yellow(
      `You are using Node.js ${process.versions.node}. ` +
        `Vite requires Node.js version 20.19+ or 22.12+. ` +
        `Please upgrade your Node.js version.`,
    ),
  )
}

const cli = cac('vite')

// global options
interface GlobalCLIOptions {
  '--'?: string[]
  c?: boolean | string
  config?: string
  base?: string
  l?: LogLevel
  logLevel?: LogLevel
  clearScreen?: boolean

Review comment (suggestion):
```suggestion
  const isSupported =
    (major === 20 && minor >= 19) || (major === 22 && minor >= 12) || major > 22
```

Code after:
import path from 'node:path'
import fs from 'node:fs'
import { performance } from 'node:perf_hooks'
import { cac } from 'cac'
import colors from 'picocolors'
import { VERSION } from './constants'
import type { BuildEnvironmentOptions } from './build'
import type { ServerOptions } from './server'
import type { CLIShortcut } from './shortcuts'
import type { LogLevel } from './logger'
import { createLogger } from './logger'
import { resolveConfig } from './config'
import type { InlineConfig } from './config'

export function checkNodeVersion(nodeVersion: string): boolean {
  const currentVersion = nodeVersion.split('.')
  const major = parseInt(currentVersion[0], 10)
  const minor = parseInt(currentVersion[1], 10)
  const isSupported =
    (major === 20 && minor >= 19) || (major === 22 && minor >= 12) || major > 22
  return isSupported
}

if (!checkNodeVersion(process.versions.node)) {
  // eslint-disable-next-line no-console
  console.warn(
    colors.yellow(
      `You are using Node.js ${process.versions.node}. ` +
        `Vite requires Node.js version 20.19+ or 22.12+. ` +
        `Please upgrade your Node.js version.`,
    ),
  )
}

const cli = cac('vite')

// global options
interface GlobalCLIOptions {
  '--'?: string[]
  c?: boolean | string
  config?: string
  base?: string
  l?: LogLevel
  logLevel?: LogLevel
  clearScreen?: boolean
  configLoader?: 'bundle' | 'runner' | 'native'
  d?: boolean | string
Repository: vitejs/vite
File: packages/vite/src/node/plugins/terser.ts (TypeScript)

Code before:
        return null
      }

      // Lazy load worker.
      worker ||= makeWorker()

      const terserPath = loadTerserPath(config.root)
      try {
        const res = await worker.run(terserPath, code, {
          safari10: true,
          ...terserOptions,
          sourceMap: !!outputOptions.sourcemap,
          module: outputOptions.format.startsWith('es'),
          toplevel: outputOptions.format === 'cjs',
        })
        return {
          code: res.code!,
          map: res.map as any,
        }
      } catch (e) {
        e.loc = {
          file: chunk.fileName,
          line: e.line,
          column: e.col,
        }
        e.frame = generateCodeFrame(code, e.pos)
        throw e
      }
    },

    closeBundle() {
      worker?.stop()
    },
  }
}


Review comment (suggestion):
The code assumes that `e.pos` exists on the error object, but this property may not be present on all Terser errors. Consider adding a check like `if (e.pos !== undefined)` before calling `generateCodeFrame`.
```suggestion
        e.frame = e.pos !== undefined ? generateCodeFrame(code, e.pos) : undefined
```

Code after:
        return null
      }

      // Lazy load worker.
      worker ||= makeWorker()

      const terserPath = pathToFileURL(loadTerserPath(config.root)).href
      try {
        const res = await worker.run(terserPath, code, {
          safari10: true,
          ...terserOptions,
          sourceMap: !!outputOptions.sourcemap,
          module: outputOptions.format.startsWith('es'),
          toplevel: outputOptions.format === 'cjs',
        })
        return {
          code: res.code!,
          map: res.map as any,
        }
      } catch (e) {
        if (e.line !== undefined && e.col !== undefined) {
          e.loc = {
            file: chunk.fileName,
            line: e.line,
            column: e.col,
          }
        }
        if (e.pos !== undefined) {
          e.frame = generateCodeFrame(code, e.pos)
        }
        throw e
      }
    },

    closeBundle() {
      worker?.stop()
    },
  }
}
Repository: vitejs/vite
File: packages/vite/src/node/plugins/terser.ts (TypeScript)

Code before:
        return null
      }

      // Lazy load worker.
      worker ||= makeWorker()

      const terserPath = loadTerserPath(config.root)
      try {
        const res = await worker.run(terserPath, code, {
          safari10: true,
          ...terserOptions,
          sourceMap: !!outputOptions.sourcemap,
          module: outputOptions.format.startsWith('es'),
          toplevel: outputOptions.format === 'cjs',
        })
        return {
          code: res.code!,
          map: res.map as any,
        }
      } catch (e) {
        e.loc = {
          file: chunk.fileName,
          line: e.line,
          column: e.col,
        }
        e.frame =
          e.pos !== undefined ? generateCodeFrame(code, e.pos) : undefined
        throw e
      }
    },

    closeBundle() {
      worker?.stop()
    },
  }
}


Review comment (suggestion):
```suggestion
        if (e.line !== undefined && e.col !== undefined) {
          e.loc = {
            file: chunk.fileName,
            line: e.line,
            column: e.col,
          }
        }
        if (e.pos !== undefined) {
          e.frame = generateCodeFrame(code, e.pos)
        }
```

Maybe we can do this so the error is enhanced a bit more defensively in case the shape is different.

Code after:
        return null
      }

      // Lazy load worker.
      worker ||= makeWorker()

      const terserPath = pathToFileURL(loadTerserPath(config.root)).href
      try {
        const res = await worker.run(terserPath, code, {
          safari10: true,
          ...terserOptions,
          sourceMap: !!outputOptions.sourcemap,
          module: outputOptions.format.startsWith('es'),
          toplevel: outputOptions.format === 'cjs',
        })
        return {
          code: res.code!,
          map: res.map as any,
        }
      } catch (e) {
        if (e.line !== undefined && e.col !== undefined) {
          e.loc = {
            file: chunk.fileName,
            line: e.line,
            column: e.col,
          }
        }
        if (e.pos !== undefined) {
          e.frame = generateCodeFrame(code, e.pos)
        }
        throw e
      }
    },

    closeBundle() {
      worker?.stop()
    },
  }
}
Repository: vitejs/vite
File: packages/create-vite/src/index.ts (TypeScript)

Code before:
  greenBright,
  magenta,
  red,
  redBright,
  reset,
  yellow,
} = colors

const argv = mri<{
  template?: string
  help?: boolean
  overwrite?: boolean
  interactive?: boolean
}>(process.argv.slice(2), {
  alias: { h: 'help', t: 'template' },
  boolean: ['help', 'overwrite', 'interactive'],
  string: ['template'],
})
const cwd = process.cwd()

// prettier-ignore
const helpMessage = `\
Usage: create-vite [OPTION]... [DIRECTORY]

Create a new Vite project in JavaScript or TypeScript.
If it is run in TTY, the CLI will start in interactive mode.

Options:
  -t, --template NAME                   use a specific template
  --interactive / --no-interactive      force interactive / non-interactive mode

Available templates:
${yellow    ('vanilla-ts     vanilla'  )}
${green     ('vue-ts         vue'      )}
${cyan      ('react-ts       react'    )}
${cyan      ('react-swc-ts   react-swc')}
${magenta   ('preact-ts      preact'   )}
${redBright ('lit-ts         lit'      )}
${red       ('svelte-ts      svelte'   )}
${blue      ('solid-ts       solid'    )}
${blueBright('qwik-ts        qwik'     )}`

type ColorFunc = (str: string | number) => string
type Framework = {
  name: string
  display: string
  color: ColorFunc
  variants: FrameworkVariant[]
}
type FrameworkVariant = {
  name: string

Review comment (suggestion):
I think it should be "running" here:

```suggestion
If it is running in TTY, the CLI will start in interactive mode.
```

Or maybe it can be shorter like

```suggestion
When running in TTY, the CLI will start in interactive mode.
```

Code after:
  greenBright,
  magenta,
  red,
  redBright,
  reset,
  yellow,
} = colors

const argv = mri<{
  template?: string
  help?: boolean
  overwrite?: boolean
  interactive?: boolean
}>(process.argv.slice(2), {
  alias: { h: 'help', t: 'template' },
  boolean: ['help', 'overwrite', 'interactive'],
  string: ['template'],
})
const cwd = process.cwd()

// prettier-ignore
const helpMessage = `\
Usage: create-vite [OPTION]... [DIRECTORY]

Create a new Vite project in JavaScript or TypeScript.
When running in TTY, the CLI will start in interactive mode.

Options:
  -t, --template NAME                   use a specific template
  --interactive / --no-interactive      force interactive / non-interactive mode

Available templates:
${yellow    ('vanilla-ts     vanilla'  )}
${green     ('vue-ts         vue'      )}
${cyan      ('react-ts       react'    )}
${cyan      ('react-swc-ts   react-swc')}
${magenta   ('preact-ts      preact'   )}
${redBright ('lit-ts         lit'      )}
${red       ('svelte-ts      svelte'   )}
${blue      ('solid-ts       solid'    )}
${blueBright('qwik-ts        qwik'     )}`

type ColorFunc = (str: string | number) => string
type Framework = {
  name: string
  display: string
  color: ColorFunc
  variants: FrameworkVariant[]
}
type FrameworkVariant = {
  name: string
Repository: vitejs/vite
File: packages/vite/src/node/server/pluginContainer.ts (TypeScript)

Code before:
      debugPluginResolve?.(
        timeFrom(pluginResolveStart),
        plugin.name,
        prettifyUrl(id, this.environment.config.root),
      )

      // resolveId() is hookFirst - first non-null result is returned.
      break
    }

    if (debugResolve && rawId !== id && !rawId.startsWith(FS_PREFIX)) {
      const key = rawId + id
      // avoid spamming
      if (!this._seenResolves[key]) {
        this._seenResolves[key] = true
        debugResolve(
          `${timeFrom(resolveStart)} ${colors.cyan(rawId)} -> ${colors.dim(
            id,
          )}`,
        )
      }
    }

    if (id) {
      partial.id =
        isExternalUrl(id) || id.startsWith('\0') ? id : normalizePath(id)
      return partial as PartialResolvedId
    } else {
      return null
    }
  }

  async load(id: string): Promise<LoadResult | null> {
    let ssr = this.environment.config.consumer === 'server'
    const topLevelConfig = this.environment.getTopLevelConfig()
    const options = { ssr }
    const ctx = new LoadPluginContext(this)
    for (const plugin of this.getSortedPlugins('load')) {
      if (this._closed && this.environment.config.dev.recoverable)
        throwClosedServerError()

      const filter = getCachedFilterForPlugin(plugin, 'load')
      if (filter && !filter(id)) continue

      ctx._plugin = plugin

      if (
        isFutureDeprecationEnabled(
          topLevelConfig,
          'removePluginHookSsrArgument',
        )

Review comment (suggestion):
```suggestion
        isExternalUrl(id) || id[0] === '\0' ? id : normalizePath(id)
```
Keep the code style consistent with other places.

Code after:
      debugPluginResolve?.(
        timeFrom(pluginResolveStart),
        plugin.name,
        prettifyUrl(id, this.environment.config.root),
      )

      // resolveId() is hookFirst - first non-null result is returned.
      break
    }

    if (debugResolve && rawId !== id && !rawId.startsWith(FS_PREFIX)) {
      const key = rawId + id
      // avoid spamming
      if (!this._seenResolves[key]) {
        this._seenResolves[key] = true
        debugResolve(
          `${timeFrom(resolveStart)} ${colors.cyan(rawId)} -> ${colors.dim(
            id,
          )}`,
        )
      }
    }

    if (id) {
      partial.id = isExternalUrl(id) || id[0] === '\0' ? id : normalizePath(id)
      return partial as PartialResolvedId
    } else {
      return null
    }
  }

  async load(id: string): Promise<LoadResult | null> {
    let ssr = this.environment.config.consumer === 'server'
    const topLevelConfig = this.environment.getTopLevelConfig()
    const options = { ssr }
    const ctx = new LoadPluginContext(this)
    for (const plugin of this.getSortedPlugins('load')) {
      if (this._closed && this.environment.config.dev.recoverable)
        throwClosedServerError()

      const filter = getCachedFilterForPlugin(plugin, 'load')
      if (filter && !filter(id)) continue

      ctx._plugin = plugin

      if (
        isFutureDeprecationEnabled(
          topLevelConfig,
          'removePluginHookSsrArgument',
        )
      ) {