Skip to content

Commit d104278

Browse files
adriencacciaclaude
andcommitted
fix(vitest-plugin): migrate deprecated vitest/runners and vitest/suite imports
Vitest 4.1 deprecated the `vitest/runners` and `vitest/suite` subpath imports, printing console warnings on every load. Introduce a compat module that dynamically resolves imports: on vitest 4.1+ it uses the main `vitest` entry point (BenchmarkRunner, TestRunner statics), and on vitest 3.x it falls back to the old subpath imports (no warnings on either version). Also bump vitest devDependency from 4.0.18 to 4.1.1, revert vite devDependency to ^7 to keep compatibility with Node 20.5.1 (vite 8 + rolldown requires Node 20.19+), and remove the now-unnecessary rolldown devDependency and tsconfig paths workaround. Co-Authored-By: Claude <noreply@anthropic.com>
1 parent 1a48730 commit d104278

11 files changed

Lines changed: 488 additions & 499 deletions

File tree

packages/vitest-plugin/package.json

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,8 @@
3838
"devDependencies": {
3939
"@total-typescript/shoehorn": "^0.1.1",
4040
"execa": "^8.0.1",
41-
"rolldown": "1.0.0-rc.11",
4241
"tinybench": "^2.9.0",
43-
"vite": "^8.0.0",
44-
"vitest": "^4.0.18"
42+
"vite": "^7.0.0",
43+
"vitest": "^4.1.1"
4544
}
4645
}

packages/vitest-plugin/rollup.config.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
import { defineConfig } from "rollup";
2-
import { declarationsPlugin, jsPlugins } from "../../rollup.options";
2+
import {
3+
declarationsPlugin,
4+
jsPlugins,
5+
jsPluginsWithTarget,
6+
} from "../../rollup.options";
37
import pkg from "./package.json" assert { type: "json" };
48

59
export default defineConfig([
@@ -23,13 +27,13 @@ export default defineConfig([
2327
{
2428
input: "src/analysis.ts",
2529
output: { file: "dist/analysis.mjs", format: "es" },
26-
plugins: jsPlugins(pkg.version),
30+
plugins: jsPluginsWithTarget(pkg.version, "esnext"),
2731
external: ["@codspeed/core", /^vitest/],
2832
},
2933
{
3034
input: "src/walltime/index.ts",
3135
output: { file: "dist/walltime.mjs", format: "es" },
32-
plugins: jsPlugins(pkg.version),
36+
plugins: jsPluginsWithTarget(pkg.version, "esnext"),
3337
external: ["@codspeed/core", /^vitest/],
3438
},
3539
]);

packages/vitest-plugin/src/__tests__/instrumented.test.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { fromPartial } from "@total-typescript/shoehorn";
22
import { describe, expect, it, vi, type RunnerTestSuite } from "vitest";
3-
import { getBenchFn } from "vitest/suite";
3+
import { getBenchFn } from "../compat";
44
import { AnalysisRunner as CodSpeedRunner } from "../analysis";
55

66
const coreMocks = vi.hoisted(() => {
@@ -28,8 +28,8 @@ vi.mock("@codspeed/core", async (importOriginal) => {
2828

2929
console.log = vi.fn();
3030

31-
vi.mock("vitest/suite", async (importOriginal) => {
32-
const actual = await importOriginal<typeof import("vitest/suite")>();
31+
vi.mock("../compat", async (importOriginal) => {
32+
const actual = await importOriginal<typeof import("../compat")>();
3333
return {
3434
...actual,
3535
getBenchFn: vi.fn(),

packages/vitest-plugin/src/analysis.ts

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,7 @@ import {
77
teardownCore,
88
} from "@codspeed/core";
99
import { Benchmark, type RunnerTestSuite } from "vitest";
10-
import { NodeBenchmarkRunner } from "vitest/runners";
11-
import { getBenchFn } from "vitest/suite";
10+
import { getBenchFn, NodeBenchmarkRunner } from "./compat";
1211
import {
1312
callSuiteHook,
1413
isVitestTaskBenchmark,
@@ -39,7 +38,6 @@ async function runAnalysisBench(
3938

4039
await optimizeFunction(async () => {
4140
await callSuiteHook(suite, benchmark, "beforeEach");
42-
// @ts-expect-error we do not need to bind the function to an instance of tinybench's Bench
4341
await fn();
4442
await callSuiteHook(suite, benchmark, "afterEach");
4543
});
@@ -49,7 +47,6 @@ async function runAnalysisBench(
4947
global.gc?.();
5048
await (async function __codspeed_root_frame__() {
5149
InstrumentHooks.startBenchmark();
52-
// @ts-expect-error we do not need to bind the function to an instance of tinybench's Bench
5350
await fn();
5451
InstrumentHooks.stopBenchmark();
5552
InstrumentHooks.setExecutedBenchmark(process.pid, uri);

packages/vitest-plugin/src/common.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
import { getGitDir } from "@codspeed/core";
22
import path from "path";
33
import { Benchmark, type RunnerTask, type RunnerTestSuite } from "vitest";
4-
import { getHooks } from "vitest/suite";
5-
type SuiteHooks = ReturnType<typeof getHooks>;
4+
import { getHooks } from "./compat";
5+
6+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
7+
type SuiteHooks = Record<string, any[]>;
68

79
function getSuiteHooks(suite: RunnerTestSuite, name: keyof SuiteHooks) {
810
return getHooks(suite)?.[name] ?? [];
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
/**
2+
* Compatibility layer for vitest imports across versions.
3+
*
4+
* Vitest 4.1 deprecated `vitest/runners` and `vitest/suite` subpath imports,
5+
* moving exports to the main `vitest` entry point. This module resolves
6+
* the correct imports at runtime to avoid deprecation warnings while
7+
* maintaining compatibility with vitest 3.2+.
8+
*/
9+
10+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
11+
type AnyClass = new (...args: any[]) => any;
12+
13+
// Resolve NodeBenchmarkRunner: vitest >= 4.1 exports it as BenchmarkRunner
14+
// from the main entry; older versions export it from vitest/runners.
15+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
16+
const vitestMod: any = await import("vitest");
17+
const _BenchmarkRunner: AnyClass | undefined = vitestMod.BenchmarkRunner;
18+
19+
let _NodeBenchmarkRunner: AnyClass;
20+
if (_BenchmarkRunner) {
21+
_NodeBenchmarkRunner = _BenchmarkRunner;
22+
} else {
23+
const runners = await import("vitest/runners");
24+
_NodeBenchmarkRunner = runners.NodeBenchmarkRunner;
25+
}
26+
export const NodeBenchmarkRunner = _NodeBenchmarkRunner;
27+
28+
// Resolve suite helpers: vitest >= 4.1 exposes them as TestRunner static
29+
// methods; older versions export them from vitest/suite.
30+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
31+
type SuiteFn = (...args: any[]) => any;
32+
let _getHooks: SuiteFn;
33+
let _getBenchFn: SuiteFn;
34+
let _getBenchOptions: SuiteFn;
35+
36+
const TestRunner = vitestMod.TestRunner;
37+
if (TestRunner?.getSuiteHooks) {
38+
_getHooks = TestRunner.getSuiteHooks;
39+
_getBenchFn = TestRunner.getBenchFn;
40+
_getBenchOptions = TestRunner.getBenchOptions;
41+
} else {
42+
const suite = await import("vitest/suite");
43+
_getHooks = suite.getHooks;
44+
_getBenchFn = suite.getBenchFn;
45+
_getBenchOptions = suite.getBenchOptions;
46+
}
47+
48+
export const getHooks = _getHooks;
49+
export const getBenchFn = _getBenchFn;
50+
export const getBenchOptions = _getBenchOptions;

packages/vitest-plugin/src/walltime/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import {
99
RunnerTaskResultPack,
1010
type RunnerTestSuite,
1111
} from "vitest";
12-
import { NodeBenchmarkRunner } from "vitest/runners";
12+
import { NodeBenchmarkRunner } from "../compat";
1313
import { patchRootSuiteWithFullFilePath } from "../common";
1414
import { extractBenchmarkResults } from "./utils";
1515

packages/vitest-plugin/src/walltime/utils.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import {
1010
type RunnerTaskResult,
1111
type RunnerTestSuite,
1212
} from "vitest";
13-
import { getBenchOptions } from "vitest/suite";
13+
import { getBenchOptions } from "../compat";
1414
import { isVitestTaskBenchmark } from "../common";
1515

1616
export async function extractBenchmarkResults(

packages/vitest-plugin/tsconfig.json

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,7 @@
33
"compilerOptions": {
44
"outDir": "dist",
55
"rootDir": "src",
6-
"baseUrl": ".",
7-
"typeRoots": ["node_modules/@types", "../../node_modules/@types"],
8-
"paths": {
9-
"vite": ["node_modules/vite/dist/node"]
10-
}
6+
"typeRoots": ["node_modules/@types", "../../node_modules/@types"]
117
},
128
"references": [{ "path": "../core" }],
139
"include": ["src/**/*.ts"]

0 commit comments

Comments
 (0)