Configuring nyc, tape and ts-node
⋅ 1 min readI've been writing a lot of TypeScript in the last few years, and have come to love it for writing my Node.js projects.
My workflow
For tests, I religiously use tape
because unlike mocha
, it does not need a test-runner — tape
tests can be run as regular Node modules. tape
also doesn't pollute global
with "magic" functions, which mocha
does with abandon.
nyc
is pretty much the only choice for code coverage in Node-land. It is a CLI-wrapper around instanbuljs
and is regularly maintained.
I prefer to use ts-node
for tests as it lets me rapidly test without having to run tsc
every time to transpile tests to JS.
The problem
One of the biggest pain points in using this combination is correctly configuring them.
Most of the folks that use these same tools run into weird coverage issues (inconsistent results across runs, 0% coverage, runtime errors. etc.)
A Google search lands in istanbuljs/nyc/issues #497, which has conflicting information. Not to mention the officially recommended config preset nyc-config-typescript
had an issue that was only just fixed.
The solution
After a lot of trial and error, here's what works best.
-
nyc
config — I'd recommend saving this in.nycrc.json
in your project's root directory. Saving it as a.json
file gives you better syntax highlighting in the editor of your choice.{ "extension": [ ".ts" ], "require": [ "ts-node/register/transpile-only" ], "exclude": [ "**/*.d.ts", "coverage/", "test/" ], "reporter": [ "text", "lcov" ], "cache": false }
-
npm
scripts —{ "scripts": { "test": "tape -r ts-node/register/transpile-only test/**/*.test.ts test/*.test.ts", "coverage": "nyc tape -r ts-node/register/transpile-only test/**/*.test.ts test/*.test.ts", } }
You can replace ts-node/register/transpile-only
with ts-node/register
if you run into unexpected issues, but in most cases it works and is ~50% faster in my experience.
Happy testing! 🥳