Skip to content

Commit 5f6a5e8

Browse files
authored
feat(coverage): switch to @vitest/istanbuljs packages (#11053)
1 parent 58e7130 commit 5f6a5e8

30 files changed

Lines changed: 315 additions & 637 deletions

AGENTS.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,7 @@ Other blocking CI jobs:
202202
- Add deps with `pnpm add <pkg>` inside the target package: `catalogMode: prefer` writes `catalog:` into package.json and adds the version to the default catalog in `pnpm-workspace.yaml` automatically. To bump a shared dep, edit its catalog entry, never per-package ranges.
203203
- The `overrides` in `pnpm-workspace.yaml` force one version of `vite`, `rollup`, `@types/node`, `acorn`, and `mlly` across the workspace; editing a range in an individual package.json changes what gets published, not what installs locally.
204204
- The workspace develops against the latest supported Vite major, but `vitest` supports the full peer range and CI runs a dedicated job against the previous major (`pnpm override-vite7` reproduces it locally). Do not rely on newest-Vite-only APIs without a fallback.
205-
- Deps listed under `patchedDependencies` (`acorn`, `cac`, `@sinonjs/fake-timers`, `rrweb-snapshot`, istanbul-lib-*) are version-locked. Bumping one requires regenerating the patch with `pnpm patch` and updating the version-keyed entry in `pnpm-workspace.yaml`.
205+
- Deps listed under `patchedDependencies` (`acorn`, `cac`, `@sinonjs/fake-timers`, `rrweb-snapshot`) are version-locked. Bumping one requires regenerating the patch with `pnpm patch` and updating the version-keyed entry in `pnpm-workspace.yaml`.
206206
- Dependency build scripts run only for packages listed under `allowBuilds` in `pnpm-workspace.yaml`; a new dep with a postinstall step installs unbuilt unless added there.
207207
- pnpm enforces a 24h `minimumReleaseAge`: installing a version published less than a day ago either resolves to an older version or appends the pick to `minimumReleaseAgeExclude` in `pnpm-workspace.yaml`. Both outcomes are expected; commit the yaml change instead of reverting it.
208208

docs/api/advanced/reporters.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -187,10 +187,10 @@ export default new MyReporter()
187187
function onCoverage(coverage: unknown): Awaitable<void>
188188
```
189189

190-
This hook is called after coverage results have been processed. Coverage provider's reporters are called after this hook. The typings of `coverage` depends on the `coverage.provider`. For Vitest's default built-in providers you can import the types from `istanbul-lib-coverage` package:
190+
This hook is called after coverage results have been processed. Coverage provider's reporters are called after this hook. The typings of `coverage` depends on the `coverage.provider`. For Vitest's default built-in providers you can import the types from `@vitest/istanbul-lib-coverage` package:
191191

192192
```ts
193-
import type { CoverageMap } from 'istanbul-lib-coverage'
193+
import type { CoverageMap } from '@vitest/istanbul-lib-coverage'
194194
195195
declare function onCoverage(coverage: CoverageMap): Awaitable<void>
196196
```

docs/config/coverage.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ Directory to write coverage report to.
9898
- **Available for providers:** `'v8' | 'istanbul'`
9999
- **CLI:** `--coverage.reporter=<reporter>`, `--coverage.reporter=<reporter1> --coverage.reporter=<reporter2>`
100100

101-
Coverage reporters to use. See [istanbul documentation](https://istanbul.js.org/docs/advanced/alternative-reporters/) for detailed list of all reporters. See [`@types/istanbul-reports`](https://github.com/DefinitelyTyped/DefinitelyTyped/blob/276d95e4304b3670eaf6e8e5a7ea9e265a14e338/types/istanbul-reports/index.d.ts) for details about reporter specific options.
101+
Coverage reporters to use. See [istanbul documentation](https://istanbul.js.org/docs/advanced/alternative-reporters/) for detailed list of all reporters. See [`@vitest/istanbul-lib-report`](https://github.com/vitest-dev/istanbuljs/tree/main/packages/istanbul-lib-report/src/reports) for details about reporter specific options.
102102

103103
The reporter has three different types:
104104

@@ -459,7 +459,7 @@ Concurrency limit used when processing the coverage results.
459459
- **Type:** `(options: InstrumenterOptions) => CoverageInstrumenter`
460460
- **Available for providers:** `'istanbul'`
461461

462-
Factory for a custom instrumenter to use in place of the default `istanbul-lib-instrument`. Vitest calls the factory once during initialization and reuses the returned instrumenter for every file. The rest of the Istanbul pipeline (collection, merging, reporting) is unchanged.
462+
Factory for a custom instrumenter to use in place of the default `@vitest/istanbul-lib-instrument`. Vitest calls the factory once during initialization and reuses the returned instrumenter for every file. The rest of the Istanbul pipeline (collection, merging, reporting) is unchanged.
463463

464464
The factory receives an `InstrumenterOptions` object with Vitest's runtime coverage settings, and must return an object implementing the `CoverageInstrumenter` interface. Both types are exported from `vitest/node`.
465465

docs/guide/coverage.md

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -257,10 +257,36 @@ export default defineConfig({
257257
})
258258
```
259259

260-
Custom reporters are loaded by Istanbul and must match its reporter interface. See [built-in reporters' implementation](https://github.com/istanbuljs/istanbuljs/tree/master/packages/istanbul-reports/lib) for reference.
260+
Custom reporters are loaded by `@vitest/istanbul-lib-report` and must match its reporter interface. See [built-in reporters' implementation](https://github.com/vitest-dev/istanbuljs/tree/main/packages/istanbul-lib-report/src/reports) for reference.
261261

262+
::: code-group
263+
```js [custom-reporter.mjs]
264+
import { ReportBase } from '@vitest/istanbul-lib-report'
265+
266+
export default class CustomReporter extends ReportBase {
267+
constructor(opts) {
268+
super()
269+
270+
if (!opts.file) {
271+
throw new Error('File is required as custom reporter parameter')
272+
}
273+
274+
this.file = opts.file
275+
}
276+
277+
onStart(root, context) {
278+
this.contentWriter = context.writer.writeFile(this.file)
279+
this.contentWriter.println('Start of custom coverage report ESM')
280+
}
281+
282+
onEnd() {
283+
this.contentWriter.println('End of custom coverage report ESM')
284+
this.contentWriter.close()
285+
}
286+
}
287+
```
262288
```js [custom-reporter.cjs]
263-
const { ReportBase } = require('istanbul-lib-report')
289+
const { ReportBase } = require('@vitest/istanbul-lib-report')
264290

265291
module.exports = class CustomReporter extends ReportBase {
266292
constructor(opts) {
@@ -281,6 +307,7 @@ module.exports = class CustomReporter extends ReportBase {
281307
}
282308
}
283309
```
310+
:::
284311

285312
## Custom Coverage Provider
286313

knip.jsonc

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,7 @@
6464
]
6565
},
6666
"packages/coverage-istanbul": {
67-
"entry": ["src/{browser,index,provider}.ts"],
68-
"ignoreDependencies": ["@babel/core"]
67+
"entry": ["src/{browser,index,provider}.ts"]
6968
},
7069
"packages/coverage-v8": {
7170
"entry": ["src/{browser,index,provider}.ts"],

packages/coverage-istanbul/package.json

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -48,25 +48,17 @@
4848
"vitest": "workspace:*"
4949
},
5050
"dependencies": {
51-
"@babel/core": "^7.29.7",
52-
"@istanbuljs/schema": "^0.1.6",
5351
"@jridgewell/gen-mapping": "^0.3.13",
5452
"@jridgewell/trace-mapping": "catalog:",
55-
"istanbul-lib-coverage": "catalog:",
56-
"istanbul-lib-report": "catalog:",
57-
"istanbul-reports": "catalog:",
53+
"@vitest/istanbul-lib-coverage": "catalog:",
54+
"@vitest/istanbul-lib-instrument": "^1.0.0",
55+
"@vitest/istanbul-lib-report": "catalog:",
56+
"@vitest/istanbul-lib-source-maps": "^1.0.0",
5857
"magicast": "catalog:",
5958
"obug": "catalog:",
6059
"tinyrainbow": "catalog:"
6160
},
6261
"devDependencies": {
63-
"@types/istanbul-lib-coverage": "catalog:",
64-
"@types/istanbul-lib-instrument": "^1.7.8",
65-
"@types/istanbul-lib-report": "catalog:",
66-
"@types/istanbul-lib-source-maps": "catalog:",
67-
"@types/istanbul-reports": "catalog:",
68-
"istanbul-lib-instrument": "^6.0.3",
69-
"istanbul-lib-source-maps": "catalog:",
7062
"pathe": "catalog:",
7163
"vitest": "workspace:*"
7264
}

packages/coverage-istanbul/rollup.config.js

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import { builtinModules, createRequire } from 'node:module'
2-
import commonjs from '@rollup/plugin-commonjs'
32
import json from '@rollup/plugin-json'
43
import nodeResolve from '@rollup/plugin-node-resolve'
54
import { join } from 'pathe'
@@ -21,9 +20,6 @@ const external = [
2120
...Object.keys(pkg.dependencies || {}),
2221
...Object.keys(pkg.peerDependencies || {}),
2322
/^@?vitest(\/|$)/,
24-
25-
// We bundle istanbul-lib-instrument but don't want to bundle its babel dependency
26-
'@babel/core',
2723
]
2824

2925
const dtsUtils = createDtsUtils()
@@ -32,11 +28,6 @@ const plugins = [
3228
...dtsUtils.isolatedDecl(),
3329
nodeResolve(),
3430
json(),
35-
commonjs({
36-
// "istanbul-lib-source-maps > @jridgewell/trace-mapping" is not CJS
37-
// "istanbul-lib-instrument > @jridgewell/trace-mapping" is not CJS
38-
esmExternals: ['@jridgewell/trace-mapping'],
39-
}),
4031
oxc({
4132
transform: { target: 'node20' },
4233
}),
@@ -62,16 +53,5 @@ export default defineConfig(() => [
6253
watch: false,
6354
external,
6455
plugins: dtsUtils.dts(),
65-
onLog(level, log, handler) {
66-
// we don't control the source of "istanbul-lib-coverage"
67-
if (
68-
level === 'warn'
69-
&& log.exporter === 'istanbul-lib-coverage'
70-
&& log.message.includes('"Range" is imported')
71-
) {
72-
return
73-
}
74-
handler(level, log)
75-
},
7656
},
7757
])

packages/coverage-istanbul/src/base.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import type { CoverageMapData } from 'istanbul-lib-coverage'
1+
import type { CoverageMapData } from '@vitest/istanbul-lib-coverage'
22
import type { IstanbulCoverageProvider } from './provider'
33
import { COVERAGE_STORE_KEY } from './constants'
44

packages/coverage-istanbul/src/provider.ts

Lines changed: 10 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,14 @@
1-
import type { CoverageMap } from 'istanbul-lib-coverage'
2-
import type { Instrumenter } from 'istanbul-lib-instrument'
1+
import type { CoverageMap } from '@vitest/istanbul-lib-coverage'
2+
import type { Instrumenter } from '@vitest/istanbul-lib-instrument'
33
import type { ProxifiedModule } from 'magicast'
44
import type { CoverageProvider, ReportContext, Vite, Vitest } from 'vitest/node'
55
import { existsSync, promises as fs } from 'node:fs'
6-
// @ts-expect-error missing types
7-
import { defaults as istanbulDefaults } from '@istanbuljs/schema'
86
import { addMapping, GenMapping, toEncodedMap } from '@jridgewell/gen-mapping'
97
import { eachMapping, TraceMap } from '@jridgewell/trace-mapping'
10-
import libCoverage from 'istanbul-lib-coverage'
11-
import { createInstrumenter } from 'istanbul-lib-instrument'
12-
import libReport from 'istanbul-lib-report'
13-
import libSourceMaps from 'istanbul-lib-source-maps'
14-
import reports from 'istanbul-reports'
8+
import * as libCoverage from '@vitest/istanbul-lib-coverage'
9+
import { createInstrumenter } from '@vitest/istanbul-lib-instrument'
10+
import * as libReport from '@vitest/istanbul-lib-report'
11+
import * as libSourceMaps from '@vitest/istanbul-lib-source-maps'
1512
import { parseModule } from 'magicast'
1613
import { createDebug } from 'obug'
1714
import c from 'tinyrainbow'
@@ -58,16 +55,6 @@ export class IstanbulCoverageProvider extends BaseCoverageProvider implements Co
5855
coverageGlobalScope: 'globalThis',
5956
coverageGlobalScopeFunc: false,
6057
ignoreClassMethods: this.options.ignoreClassMethods,
61-
parserPlugins: [
62-
...istanbulDefaults.instrumenter.parserPlugins,
63-
['importAttributes', { deprecatedAssertSyntax: true }],
64-
],
65-
generatorOpts: {
66-
// @ts-expect-error missing type
67-
importAttributesKeyword: 'with',
68-
},
69-
70-
// Custom option from the patched istanbul-lib-instrument: https://github.com/istanbuljs/istanbuljs/pull/835
7158
ignoreLines: true,
7259
})
7360
}
@@ -206,13 +193,14 @@ export class IstanbulCoverageProvider extends BaseCoverageProvider implements Co
206193

207194
for (const reporter of this.options.reporter) {
208195
// Type assertion required for custom reporters
209-
reports
210-
.create(reporter[0] as Parameters<typeof reports.create>[0], {
196+
const reportInstance = await libReport
197+
.createAsync(reporter[0] as Parameters<typeof libReport.create>[0], {
211198
skipFull: this.options.skipFull,
212199
projectRoot: this.ctx.config.root,
213200
...reporter[1],
214201
})
215-
.execute(context)
202+
203+
reportInstance.execute(context)
216204
}
217205

218206
if (this.options.thresholds) {

packages/coverage-v8/package.json

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -55,19 +55,15 @@
5555
},
5656
"dependencies": {
5757
"@bcoe/v8-coverage": "^1.0.2",
58+
"@vitest/istanbul-lib-coverage": "catalog:",
59+
"@vitest/istanbul-lib-report": "catalog:",
5860
"ast-v8-to-istanbul": "^1.0.5",
59-
"istanbul-lib-coverage": "catalog:",
60-
"istanbul-lib-report": "catalog:",
61-
"istanbul-reports": "catalog:",
6261
"magicast": "catalog:",
6362
"obug": "catalog:",
6463
"std-env": "catalog:",
6564
"tinyrainbow": "catalog:"
6665
},
6766
"devDependencies": {
68-
"@types/istanbul-lib-coverage": "catalog:",
69-
"@types/istanbul-lib-report": "catalog:",
70-
"@types/istanbul-reports": "catalog:",
7167
"@vitest/browser": "workspace:*",
7268
"@vitest/browser-playwright": "workspace:*",
7369
"pathe": "catalog:",

0 commit comments

Comments
 (0)