Skip to content

feat(coverage): replace acorn with @babel/parser for JS and TS support#152

Merged
sohil-kshirsagar merged 5 commits intomainfrom
sohil/feat/babel-parser-for-ts
Apr 9, 2026
Merged

feat(coverage): replace acorn with @babel/parser for JS and TS support#152
sohil-kshirsagar merged 5 commits intomainfrom
sohil/feat/babel-parser-for-ts

Conversation

@sohil-kshirsagar
Copy link
Copy Markdown
Contributor

@sohil-kshirsagar sohil-kshirsagar commented Apr 8, 2026

Replace acorn and acorn-typescript with @babel/parser for parsing source files during coverage collection.

Problem

Coverage needs to parse source files into an AST for ast-v8-to-istanbul. Previously we used acorn for JS and acorn-typescript for TS files. acorn-typescript is unmaintained (last updated Jan 2024), and the maintained fork (@sveltejs/acorn-typescript) fails on complex TypeScript (decorators, certain import patterns). This blocked coverage for ts-node, ts-node-dev, and --experimental-strip-types users where V8 reports .ts file URLs directly.

Fix

Use @babel/parser for all files — JS and TypeScript. Babel handles every TypeScript syntax variant and is actively maintained. ast-v8-to-istanbul officially tests against babel's AST format.

Plugins used:

  • All files: decorators-legacy (supports TypeScript's experimental parameter decorators used by inversify, NestJS, TypeORM, Angular, etc.)
  • TS files: typescript
  • TSX files: jsx (in addition to above)

Uses decorators-legacy instead of TC39 decorators because parameter decorators (@inject() on constructor params) are rejected by the TC39 plugin. This covers ~99% of TypeScript codebases. If a project uses TC39 Stage 3 decorators (experimentalDecorators: false in tsconfig.json), we could detect this from tsconfig.json or fall back automatically — but this is not needed yet.

What this enables

  • ts-node and ts-node-dev coverage (V8 reports .ts URLs, babel parses them directly)
  • --experimental-strip-types coverage
  • Full support for parameter decorators (inversify, NestJS, TypeORM) — previously these files were silently dropped

Dependencies

  • Added: @babel/parser
  • Removed: acorn, acorn-typescript
  • No bundle size change (still 1.8MB)

Testing

  • example-express-server (CJS, JS): 39.1% lines on single test, line-level accuracy verified against source
  • example-express-ts-server (CJS via tsc, TS): 85.9% lines, 57.1% branches
  • tusk/backend (ts-node, 600+ TS files with inversify decorators): 19.3% lines, 428 files — verified UsersResolver.ts, UsersService.ts now included (were silently dropped with the decorators plugin)
  • drift-node-demo (--experimental-strip-types): coverage detected on .ts files directly

Line accuracy verification

Exported JSON coverage for example-express-ts-server and cross-referenced every covered/uncovered line against the source. Covered lines correctly map to: imports + app setup (startup), the tested handler, health endpoint (readiness check), and main/listen. Uncovered lines correctly map to: untested handlers and error paths.

…rage

acorn-typescript is unmaintained (last updated Jan 2024) and its maintained
fork (@sveltejs/acorn-typescript) fails on complex TypeScript syntax.

@babel/parser handles all TypeScript syntax (decorators, generics, import type,
satisfies, path aliases) and is actively maintained as part of core Babel.
ast-v8-to-istanbul officially supports babel's AST format.

- .ts/.tsx files: parsed with @babel/parser (typescript + decorators plugins)
- .js files: still parsed with acorn (lighter, no plugins needed)
- No bundle size increase (still 1.8MB)
- Use @babel/parser uniformly for JS and TS files (was split between acorn for JS, acorn-typescript for TS)
- Removes acorn and acorn-typescript dependencies entirely
- Babel plugins: typescript, decorators, decoratorAutoAccessors, jsx (for .tsx)
- No bundle size change (1.8MB)
@sohil-kshirsagar sohil-kshirsagar changed the title feat(coverage): replace acorn-typescript with @babel/parser for TS support feat(coverage): replace acorn with @babel/parser for JS and TS support Apr 8, 2026
@sohil-kshirsagar sohil-kshirsagar changed the title feat(coverage): replace acorn with @babel/parser for JS and TS support feat(coverage): replace acorn with @babel/parser for JS and TS support Apr 8, 2026
// (may fail for TS files, but the outer try/catch handles that)
}
}
const babelParser = require("@babel/parser");
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Lazy require moved inside silent catch swallows dependency errors

Medium Severity

The require("@babel/parser") call was moved from outside the for loop (where require("acorn") previously lived, alongside require("ast-v8-to-istanbul") at line 210) to inside the per-script try/catch block. If @babel/parser fails to load (broken install, bundling issue), the error is silently caught at line 349 and every script is skipped via continue, resulting in empty coverage with no error surfaced. Previously, require("acorn") at the same level as require("ast-v8-to-istanbul") would throw immediately before the loop, letting the caller see the failure.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit babc196. Configure here.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

False positive — require("@babel/parser") is at line 231, outside any try/catch. The try/catch at line 243 only wraps the parse attempt (script vs module fallback), not the require.

— Claude Code

…, NestJS, TypeORM)

The TC39 decorators plugin rejects parameter decorators (@Inject on constructor
params) which are widely used by inversify, NestJS, and TypeORM. decorators-legacy
follows TypeScript's experimental decorators which support all decorator positions.

This fixes 265 files being silently dropped from coverage in inversify-based projects.
@sohil-kshirsagar sohil-kshirsagar marked this pull request as ready for review April 8, 2026 21:22
Copy link
Copy Markdown

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

There are 2 total unresolved issues (including 1 from previous review).

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 80d5585. Configure here.

Comment thread src/core/coverageProcessor.ts
Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

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

No issues found across 4 files

@tusk-dev
Copy link
Copy Markdown
Contributor

tusk-dev bot commented Apr 8, 2026

Generated 25 tests - 25 passed

Commit tests View tests

Tip

New to Tusk Unit Tests? Learn more here.

Test Summary

  • isTSX - 6 ✓
  • isTypeScript - 9 ✓
  • processV8CoverageFile - 10 ✓

Results

Tusk's tests all pass. The test suite validates the core parser plugin selection logic for the Babel migration across all file types (.ts, .tsx, .mts, .cts, .js, .mjs, .cjs). Critical paths covered: isTypeScript and isTSX regex matchers ensure correct file classification, and processV8CoverageFile verifies that each file type gets the right Babel plugin combination — notably decorators-legacy for all files (enabling NestJS/inversify/TypeORM support), plus typescript for TS variants and jsx for TSX. The tests confirm parameter decorators parse correctly, which unblocks coverage for the ~99% of TypeScript codebases using them. This directly addresses the PR's goal: replacing the unmaintained acorn-typescript with Babel to support ts-node, ts-node-dev, and --experimental-strip-types workflows where V8 reports .ts URLs directly.

View check history

Commit Status Output Created (UTC)
80d5585 Generated 25 tests - 25 passed Tests Apr 8, 2026 9:22PM
9c545e0 Generated 25 tests - 25 passed Tests Apr 8, 2026 10:53PM

Was Tusk helpful? Give feedback by reacting with 👍 or 👎

@sohil-kshirsagar sohil-kshirsagar merged commit 7a6219e into main Apr 9, 2026
19 checks passed
@sohil-kshirsagar sohil-kshirsagar deleted the sohil/feat/babel-parser-for-ts branch April 9, 2026 03:57
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.

2 participants