feat(coverage): replace acorn with @babel/parser for JS and TS support#152
feat(coverage): replace acorn with @babel/parser for JS and TS support#152sohil-kshirsagar merged 5 commits intomainfrom
acorn with @babel/parser for JS and TS support#152Conversation
…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)
acorn with @babel/parser for JS and TS support
| // (may fail for TS files, but the outer try/catch handles that) | ||
| } | ||
| } | ||
| const babelParser = require("@babel/parser"); |
There was a problem hiding this comment.
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.
Reviewed by Cursor Bugbot for commit babc196. Configure here.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
There are 2 total unresolved issues (including 1 from previous review).
❌ 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.
Generated 25 tests - 25 passedTip New to Tusk Unit Tests? Learn more here. Test Summary
ResultsTusk's tests all pass. The test suite validates the core parser plugin selection logic for the Babel migration across all file types ( View check history
Was Tusk helpful? Give feedback by reacting with 👍 or 👎 |




Replace
acornandacorn-typescriptwith@babel/parserfor parsing source files during coverage collection.Problem
Coverage needs to parse source files into an AST for
ast-v8-to-istanbul. Previously we usedacornfor JS andacorn-typescriptfor TS files.acorn-typescriptis unmaintained (last updated Jan 2024), and the maintained fork (@sveltejs/acorn-typescript) fails on complex TypeScript (decorators, certain import patterns). This blocked coverage forts-node,ts-node-dev, and--experimental-strip-typesusers where V8 reports.tsfile URLs directly.Fix
Use
@babel/parserfor all files — JS and TypeScript. Babel handles every TypeScript syntax variant and is actively maintained.ast-v8-to-istanbulofficially tests against babel's AST format.Plugins used:
decorators-legacy(supports TypeScript's experimental parameter decorators used by inversify, NestJS, TypeORM, Angular, etc.)typescriptjsx(in addition to above)Uses
decorators-legacyinstead of TC39decoratorsbecause 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: falsein tsconfig.json), we could detect this from tsconfig.json or fall back automatically — but this is not needed yet.What this enables
ts-nodeandts-node-devcoverage (V8 reports.tsURLs, babel parses them directly)--experimental-strip-typescoverageDependencies
@babel/parseracorn,acorn-typescriptTesting
example-express-server(CJS, JS): 39.1% lines on single test, line-level accuracy verified against sourceexample-express-ts-server(CJS via tsc, TS): 85.9% lines, 57.1% branchestusk/backend(ts-node, 600+ TS files with inversify decorators): 19.3% lines, 428 files — verifiedUsersResolver.ts,UsersService.tsnow included (were silently dropped with thedecoratorsplugin)drift-node-demo(--experimental-strip-types): coverage detected on.tsfiles directlyLine accuracy verification
Exported JSON coverage for
example-express-ts-serverand 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.