Skip to content

Conversation

@yashuatla
Copy link
Owner

@yashuatla yashuatla commented Jun 24, 2025

PR Summary

Comprehensive Type System Refactoring and Deprecated API Removal

Overview

This PR performs a major refactoring of Vitest's type system, removing deprecated APIs, renaming types for consistency, and improving type safety across the codebase. It also includes significant changes to the coverage configuration system and fixes several timer-related issues.

Change Types

Type Description
Refactor Renamed and reorganized types across the codebase for better consistency
Removal Removed deprecated APIs including defineWorkspace, BasicReporter, and several type definitions
Enhancement Improved type safety with proper assertions and null checks
Bugfix Fixed timer-related issues in browser environments

Affected Modules

Module / File Change Description
vitest/src/types/ Renamed types (e.g., ErrorWithDiffTestError, UserConfigTestUserConfig)
vitest/src/public/ Removed deprecated exports and type definitions
vitest/src/node/coverage.ts Refactored coverage configuration system
vitest/src/defaults.ts Removed default coverage configuration settings
browser/src/ Fixed import paths and added type assertions
utils/src/timers.ts Fixed timer-related issues for browser environments

Breaking Changes

  • Removed defineWorkspace function (use projects field in root config instead)
  • Removed BasicReporter from reporter options
  • Renamed UserConfig to TestUserConfig for clarity
  • Removed ErrorWithDiff type in favor of TestError
  • Simplified coverage configuration by removing extension and all options

Notes for Reviewers

  • The PR includes many type assertion changes from specific types to any or Map<string, any> which reduces type safety but appears necessary for compatibility
  • Several timer-related fixes include null checks that may affect behavior in certain environments
  • Coverage configuration has been significantly simplified, which may affect existing test setups

Additional Context

  • This PR is part of a larger effort to improve type consistency and remove deprecated APIs
  • Many changes involve renaming types with more specific prefixes (e.g., adding "Runner" or "Test" prefixes)
  • The removal of defineWorkspace is a planned deprecation mentioned in TODO comments


public parseErrorStacktrace(
e: ErrorWithDiff,
e: TestError,
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🐛 Correctness Issue

Type incompatibility with parent class method.

Changing parameter type from ErrorWithDiff to TestError may cause runtime errors if the parent class still expects ErrorWithDiff.

Current Code (Diff):

-     e: TestError,
+     e: ErrorWithDiff,
📝 Committable suggestion

‼️ IMPORTANT
Trust, but verify! 🕵️ Please review this suggestion with the care of a code archaeologist - check that it perfectly replaces the highlighted code, preserves all lines, maintains proper indentation, and won't break anything in production. Your future self will thank you! 🚀

Suggested change
e: TestError,
e: ErrorWithDiff,

🔄 Dependencies Affected

packages/browser/src/node/project.ts

Function: ProjectBrowser.parseErrorStacktrace

Issue: Method delegates to parent.parseErrorStacktrace with potentially incompatible parameter type

Suggestion: Ensure parent class accepts TestError type or revert to ErrorWithDiff

Proposed Code:

public parseErrorStacktrace(
  e: ErrorWithDiff,
  options: StackTraceParserOptions = {},
): ParsedStack[] {
  return this.parent.parseErrorStacktrace(e, options)
}

const { nextTick: safeNextTick } = globalThis.process || {
nextTick: cb => cb(),
}
const { nextTick: safeNextTick } = globalThis.process || {}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🐛 Correctness Issue

Removed nextTick fallback causes undefined function.

Removing the fallback implementation for nextTick will cause runtime errors when timers.nextTick is called in environments where process.nextTick is unavailable.

Current Code (Diff):

-   const { nextTick: safeNextTick } = globalThis.process || {}
+   const { nextTick: safeNextTick } = globalThis.process || {
+     nextTick: cb => cb(),
+   }
📝 Committable suggestion

‼️ IMPORTANT
Trust, but verify! 🕵️ Please review this suggestion with the care of a code archaeologist - check that it perfectly replaces the highlighted code, preserves all lines, maintains proper indentation, and won't break anything in production. Your future self will thank you! 🚀

Suggested change
const { nextTick: safeNextTick } = globalThis.process || {}
const { nextTick: safeNextTick } = globalThis.process || {
nextTick: cb => cb(),
}

} from './json'

export const ReportersMap = {
'default': DefaultReporter as typeof DefaultReporter,
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🐛 Correctness Issue

Breaking API Change: Removed 'basic' Reporter Option.

Removing the 'basic' reporter option from ReportersMap will break any code that references this option, causing runtime exceptions.

/**
* Exclude globs for test files
* @default ['**\/node_modules/**', '**\/dist/**', '**\/cypress/**', '**\/.{idea,git,cache,output,temp}/**', '**\/{karma,rollup,webpack,vite,vitest,jest,ava,babel,nyc,cypress,tsup,build,eslint,prettier}.config.*']
* @default ['**\/node_modules/**', '**\/.git/**']
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🐛 Correctness Issue

Critical reduction in default test exclusion patterns.

Drastically reducing default exclude patterns will cause tests to run against build artifacts, config files, and temp directories, leading to unexpected behavior and performance issues.

Current Code (Diff):

-    * @default ['**\/node_modules/**', '**\/.git/**']
+    * @default ['**\/node_modules/**', '**\/dist/**', '**\/cypress/**', '**\/.{idea,git,cache,output,temp}/**', '**\/{karma,rollup,webpack,vite,vitest,jest,ava,babel,nyc,cypress,tsup,build,eslint,prettier}.config.*']
📝 Committable suggestion

‼️ IMPORTANT
Trust, but verify! 🕵️ Please review this suggestion with the care of a code archaeologist - check that it perfectly replaces the highlighted code, preserves all lines, maintains proper indentation, and won't break anything in production. Your future self will thank you! 🚀

Suggested change
* @default ['**\/node_modules/**', '**\/.git/**']
* @default ['**\/node_modules/**', '**\/dist/**', '**\/cypress/**', '**\/.{idea,git,cache,output,temp}/**', '**\/{karma,rollup,webpack,vite,vitest,jest,ava,babel,nyc,cypress,tsup,build,eslint,prettier}.config.*']

globalThis.clearImmediate = currentClearImmediate

if (globalThis.process) {
if (globalThis.process && nextTick) {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🐛 Correctness Issue

Potential Runtime Exception: Unchecked Function Call.

The code attempts to call nextTick() without verifying it exists, which could cause a runtime exception if nextTick is undefined.

Current Code (Diff):

-     if (globalThis.process) {
+     if (globalThis.process && nextTick) {
📝 Committable suggestion

‼️ IMPORTANT
Trust, but verify! 🕵️ Please review this suggestion with the care of a code archaeologist - check that it perfectly replaces the highlighted code, preserves all lines, maintains proper indentation, and won't break anything in production. Your future self will thank you! 🚀

Suggested change
if (globalThis.process && nextTick) {
if (globalThis.process && nextTick) {

private snapshotClient = getSnapshotClient()
private workerState = getWorkerState()
private __vitest_executor!: VitestExecutor
private __vitest_executor!: any
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🐛 Correctness Issue

Type Safety Removal: VitestExecutor to any.

Changing the type from VitestExecutor to any removes compile-time type checking, which could lead to runtime crashes if executeId() method doesn't exist.

Current Code (Diff):

-   private __vitest_executor!: any
+   private __vitest_executor!: VitestExecutor
📝 Committable suggestion

‼️ IMPORTANT
Trust, but verify! 🕵️ Please review this suggestion with the care of a code archaeologist - check that it perfectly replaces the highlighted code, preserves all lines, maintains proper indentation, and won't break anything in production. Your future self will thank you! 🚀

Suggested change
private __vitest_executor!: any
private __vitest_executor!: VitestExecutor

🔄 Dependencies Affected

packages/vitest/src/runtime/runners/test.ts

Function: VitestTestRunner.importFile

Issue: Method relies on executeId() being available on __vitest_executor

Suggestion: Keep the strong typing to ensure executeId() method exists at compile time

Proposed Code:

  async importFile(filepath: string) {
    return this.__vitest_executor.executeId(filepath)
  }

continue
}

const [_, __, from] = (line.includes('with')
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🐛 Correctness Issue

Unsafe regex destructuring could cause runtime errors.

The destructuring assignment doesn't handle the case where the regex doesn't match, potentially causing 'cannot read property of undefined' errors at runtime.

Current Code (Diff):

-     const [_, __, from] = (line.includes('with')
-       ? /Imported via '(.*)' from file '(.*)' with/.exec(line)
-       : /Imported via '(.*)' from file '(.*)'/.exec(line)) ?? []
+     const match = line.includes('with')
+       ? /Imported via '(.*)' from file '(.*)' with/.exec(line)
+       : /Imported via '(.*)' from file '(.*)'/.exec(line)
+     
+     if (!match) continue
+     
+     const [_, __, from] = match
📝 Committable suggestion

‼️ IMPORTANT
Trust, but verify! 🕵️ Please review this suggestion with the care of a code archaeologist - check that it perfectly replaces the highlighted code, preserves all lines, maintains proper indentation, and won't break anything in production. Your future self will thank you! 🚀

Suggested change
const [_, __, from] = (line.includes('with')
const match = line.includes('with')
? /Imported via '(.*)' from file '(.*)' with/.exec(line)
: /Imported via '(.*)' from file '(.*)'/.exec(line)
if (!match) continue
const [_, __, from] = match

@@ -0,0 +1,3 @@
export function uncovered(condition: boolean) {
return condition ? 1 : 0
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🐛 Correctness Issue

Missing semicolon causing syntax error.

The return statement is missing a semicolon which will cause compilation failure in strict TypeScript environments.

Current Code (Diff):

-   return condition ? 1 : 0
+   return condition ? 1 : 0;
📝 Committable suggestion

‼️ IMPORTANT
Trust, but verify! 🕵️ Please review this suggestion with the care of a code archaeologist - check that it perfectly replaces the highlighted code, preserves all lines, maintains proper indentation, and won't break anything in production. Your future self will thank you! 🚀

Suggested change
return condition ? 1 : 0
return condition ? 1 : 0;

import type { TestUserConfig } from 'vitest/config'
import { assertType, describe, expectTypeOf, test } from 'vitest'
import { defineConfig, defineProject, defineWorkspace, mergeConfig } from 'vitest/config'
import { defineConfig, defineProject, mergeConfig } from 'vitest/config'
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🐛 Correctness Issue

Removed defineWorkspace import breaks tests.

The defineWorkspace import was removed but it's still used in tests, which will cause compilation failures.

Current Code (Diff):

- import { defineConfig, defineProject, mergeConfig } from 'vitest/config'
+ import { defineConfig, defineProject, defineWorkspace, mergeConfig } from 'vitest/config'
📝 Committable suggestion

‼️ IMPORTANT
Trust, but verify! 🕵️ Please review this suggestion with the care of a code archaeologist - check that it perfectly replaces the highlighted code, preserves all lines, maintains proper indentation, and won't break anything in production. Your future self will thank you! 🚀

Suggested change
import { defineConfig, defineProject, mergeConfig } from 'vitest/config'
import { defineConfig, defineProject, defineWorkspace, mergeConfig } from 'vitest/config'

🔄 Dependencies Affected

test/config-types.test-d.ts

Function: describe('define workspace helper')

Issue: Test block uses defineWorkspace but the import is removed

Suggestion: Keep the defineWorkspace import to maintain test functionality


...config.coverage,
provider: provider === 'v8-ast-aware' ? 'v8' : provider,
experimentalAstAwareRemapping: provider === 'v8-ast-aware',
provider,
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🐛 Correctness Issue

Breaking change: v8-ast-aware provider handling removed.

Removing special handling for 'v8-ast-aware' provider will break tests that rely on this provider being transformed to 'v8' with experimentalAstAwareRemapping enabled.

Current Code (Diff):

- provider,
+ provider: provider === 'v8-ast-aware' ? 'v8' : provider,
+ experimentalAstAwareRemapping: provider === 'v8-ast-aware',
📝 Committable suggestion

‼️ IMPORTANT
Trust, but verify! 🕵️ Please review this suggestion with the care of a code archaeologist - check that it perfectly replaces the highlighted code, preserves all lines, maintains proper indentation, and won't break anything in production. Your future self will thank you! 🚀

Suggested change
provider,
provider: provider === 'v8-ast-aware' ? 'v8' : provider,
experimentalAstAwareRemapping: provider === 'v8-ast-aware',

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants