From 87ca2bf8e42bfe0954b4fc9ce203ba8f7c722115 Mon Sep 17 00:00:00 2001 From: Adrien Cacciaguerra Date: Tue, 1 Sep 2026 12:48:55 +0000 Subject: [PATCH] fix(vitest-plugin): stop importing the deprecated vitest subpaths Vitest 4.1 moved the benchmark runner and the suite helpers to the main `vitest` entry point and deprecated the `vitest/runners` and `vitest/suite` subpaths, which now print a warning on every import. Add a compat module that reads `BenchmarkRunner` and the `TestRunner` statics from the main entry when they are available, and falls back to the subpaths otherwise, keeping the vitest 3.2 and 4.0 support the peer dependency range advertises. Resolution happens through a top-level await because the runner is needed as a base class, so the two runner bundles are built for es2022; `jsPlugins` now takes an optional target and keeps es2020 for every other entry point. Co-Authored-By: Claude --- packages/vitest-plugin/rollup.config.mjs | 6 ++-- .../src/__tests__/instrumented.test.ts | 6 ++-- packages/vitest-plugin/src/analysis.ts | 3 +- packages/vitest-plugin/src/common.ts | 2 +- packages/vitest-plugin/src/compat.ts | 35 +++++++++++++++++++ packages/vitest-plugin/src/walltime/index.ts | 2 +- packages/vitest-plugin/src/walltime/utils.ts | 2 +- rollup.options.mjs | 3 +- 8 files changed, 48 insertions(+), 11 deletions(-) create mode 100644 packages/vitest-plugin/src/compat.ts diff --git a/packages/vitest-plugin/rollup.config.mjs b/packages/vitest-plugin/rollup.config.mjs index 1b66840f..2fda2b6a 100644 --- a/packages/vitest-plugin/rollup.config.mjs +++ b/packages/vitest-plugin/rollup.config.mjs @@ -26,13 +26,15 @@ export default defineConfig([ { input: "src/analysis.ts", output: { file: "dist/analysis.mjs", format: "es" }, - plugins: jsPlugins(pkg.version), + // top-level await + plugins: jsPlugins(pkg.version, "es2022"), external: ["@codspeed/core", /^vitest/], }, { input: "src/walltime/index.ts", output: { file: "dist/walltime.mjs", format: "es" }, - plugins: jsPlugins(pkg.version), + // top-level await + plugins: jsPlugins(pkg.version, "es2022"), external: ["@codspeed/core", /^vitest/], }, ]); diff --git a/packages/vitest-plugin/src/__tests__/instrumented.test.ts b/packages/vitest-plugin/src/__tests__/instrumented.test.ts index ee880797..b749b236 100644 --- a/packages/vitest-plugin/src/__tests__/instrumented.test.ts +++ b/packages/vitest-plugin/src/__tests__/instrumented.test.ts @@ -1,7 +1,7 @@ import { fromPartial } from "@total-typescript/shoehorn"; import { describe, expect, it, vi, type RunnerTestSuite } from "vitest"; -import { getBenchFn } from "vitest/suite"; import { AnalysisRunner as CodSpeedRunner } from "../analysis"; +import { getBenchFn } from "../compat"; const coreMocks = vi.hoisted(() => { return { @@ -28,8 +28,8 @@ vi.mock("@codspeed/core", async (importOriginal) => { console.log = vi.fn(); -vi.mock("vitest/suite", async (importOriginal) => { - const actual = await importOriginal(); +vi.mock("../compat", async (importOriginal) => { + const actual = await importOriginal(); return { ...actual, getBenchFn: vi.fn(), diff --git a/packages/vitest-plugin/src/analysis.ts b/packages/vitest-plugin/src/analysis.ts index 424e1a70..ff1a6a57 100644 --- a/packages/vitest-plugin/src/analysis.ts +++ b/packages/vitest-plugin/src/analysis.ts @@ -8,13 +8,12 @@ import { wrapWithRootFrame, } from "@codspeed/core"; import { Benchmark, type RunnerTestSuite } from "vitest"; -import { NodeBenchmarkRunner } from "vitest/runners"; -import { getBenchFn } from "vitest/suite"; import { callSuiteHook, isVitestTaskBenchmark, patchRootSuiteWithFullFilePath, } from "./common"; +import { getBenchFn, NodeBenchmarkRunner } from "./compat"; const currentFileName = typeof __filename === "string" diff --git a/packages/vitest-plugin/src/common.ts b/packages/vitest-plugin/src/common.ts index 9ef422a7..e853c307 100644 --- a/packages/vitest-plugin/src/common.ts +++ b/packages/vitest-plugin/src/common.ts @@ -1,7 +1,7 @@ import { getGitDir } from "@codspeed/core"; import path from "path"; import { Benchmark, type RunnerTask, type RunnerTestSuite } from "vitest"; -import { getHooks } from "vitest/suite"; +import { getHooks } from "./compat"; type SuiteHooks = ReturnType; function getSuiteHooks(suite: RunnerTestSuite, name: keyof SuiteHooks) { diff --git a/packages/vitest-plugin/src/compat.ts b/packages/vitest-plugin/src/compat.ts new file mode 100644 index 00000000..d27baa71 --- /dev/null +++ b/packages/vitest-plugin/src/compat.ts @@ -0,0 +1,35 @@ +type VitestExports = typeof import("vitest"); + +/** + * Vitest 4.1 moved the benchmark runner and the suite helpers to the main + * `vitest` entry point and deprecated the `vitest/runners` and `vitest/suite` + * subpaths, which warn on import. + */ +async function resolveVitestApi() { + const { BenchmarkRunner, TestRunner }: Partial = + await import("vitest"); + + if (BenchmarkRunner && TestRunner) { + return { + NodeBenchmarkRunner: BenchmarkRunner, + getHooks: TestRunner.getSuiteHooks, + getBenchFn: TestRunner.getBenchFn, + getBenchOptions: TestRunner.getBenchOptions, + }; + } + + const [runners, suite] = await Promise.all([ + import("vitest/runners"), + import("vitest/suite"), + ]); + + return { + NodeBenchmarkRunner: runners.NodeBenchmarkRunner, + getHooks: suite.getHooks, + getBenchFn: suite.getBenchFn, + getBenchOptions: suite.getBenchOptions, + }; +} + +export const { NodeBenchmarkRunner, getHooks, getBenchFn, getBenchOptions } = + await resolveVitestApi(); diff --git a/packages/vitest-plugin/src/walltime/index.ts b/packages/vitest-plugin/src/walltime/index.ts index 18c71215..880d9279 100644 --- a/packages/vitest-plugin/src/walltime/index.ts +++ b/packages/vitest-plugin/src/walltime/index.ts @@ -12,8 +12,8 @@ import { RunnerTaskResultPack, type RunnerTestSuite, } from "vitest"; -import { NodeBenchmarkRunner } from "vitest/runners"; import { patchRootSuiteWithFullFilePath } from "../common"; +import { NodeBenchmarkRunner } from "../compat"; import { extractBenchmarkResults } from "./utils"; type Tinybench = typeof tinybench; diff --git a/packages/vitest-plugin/src/walltime/utils.ts b/packages/vitest-plugin/src/walltime/utils.ts index 2b3c1f33..e0e3313e 100644 --- a/packages/vitest-plugin/src/walltime/utils.ts +++ b/packages/vitest-plugin/src/walltime/utils.ts @@ -10,8 +10,8 @@ import { type RunnerTestSuite, type Benchmark as VitestBenchmark, } from "vitest"; -import { getBenchOptions } from "vitest/suite"; import { isVitestTaskBenchmark } from "../common"; +import { getBenchOptions } from "../compat"; export async function extractBenchmarkResults( suite: RunnerTestSuite, diff --git a/rollup.options.mjs b/rollup.options.mjs index a428f7e3..8fb1b3d2 100644 --- a/rollup.options.mjs +++ b/rollup.options.mjs @@ -13,9 +13,10 @@ import esbuild from "rollup-plugin-esbuild"; */ export const declarationsPlugin = (options) => [dts(options)]; -export const jsPlugins = (version) => [ +export const jsPlugins = (version, target = "es2020") => [ json(), esbuild({ + target, define: { __VERSION__: '"' + version + '"', },