standard-things / esm

Tomorrow's ECMAScript modules today!
Other
5.27k stars 147 forks source link

nyc issues and workarounds #910

Open davidlehn opened 2 years ago

davidlehn commented 2 years ago

I'm not sure what the maintenance status is of esm, but for future readers, here's some notes on nyc related issues and workarounds with nyc v15, esm v3.2.25, and node v14.

Problem

When esm is in use, running regular tests creates node_modules/.cache/esm, then running nyc apparently tries to reuse those files and the coverage output is wrong, usually reported at always 100%, but is not really 100% and the coverage output is nonsense in some way (incorrect source lines or other issues).

Something simple like this fails:

# npm test
# nyc npm test

Running the reverse way works since instrumented nyc code gets cached, and regular tests can run it.

ESM_DISABLE_CACHE

One might think you could avoid cache issues with:

# ESM_DISABLE_CACHE=true nyc npm test

However, that env var is only checked in an onExit() handler and cleans up the cache after tests are run. This is confusing, and a second coverage run would work fine since the cache got deleted at the end of the last run.

The docs are not clear on this, or it's misbehaving.

It really seems like this var should disable caching just like the other cache option does. I'm not sure what the reasoning is here.

It is possible to run a pre-command just to clear the caches. Something that sets the env var then loads everything through esm. But this is an odd workaround to need.

ESM_OPTIONS

Two approaches that seem to work use ESM_OPTIONS. (With some escaped double quotes needed when in package.json.)

Setup a special coverage cache dir. It seems useful to put the cache next the regular esm cache dir. Regular tests and coverage tests will just use different cache dirs.

# ESM_OPTIONS='{cache:"node_modules/.cache/esm-nyc"}' nyc npm test

A less verbose version can just disable the cache if your use case doesn't really need to worry about speed for coverage testing:

# ESM_OPTIONS='{cache:false}' nyc npm test

isNyc check

Suggestions