Missing file/package in import statement misreported as ESM error
See original GitHub issuePrerequisites
- Checked that your issue hasn’t already been filed by cross-referencing issues with the
faq
label - Checked next-gen ES issues and syntax problems by using the same environment and/or transpiler configuration without Mocha to ensure it isn’t just a feature that actually isn’t supported in the environment in question or a bug in your code.
- ‘Smoke tested’ the code to be tested by running it outside the real test suite to get a better sense of whether the problem is in the code under test, your usage of Mocha, or Mocha itself
- Ensured that there is no discrepancy between the locally and globally installed versions of Mocha. You can find them with:
node node_modules/.bin/mocha --version
(Local) andmocha --version
(Global). We recommend that you not install Mocha globally.
Description
This lead me down the garden path: A bad import statement (where the targeted package doesn’t exist) results in mocha claiming the containing file was not interpreted as ESM despite containing an import
(and mocha swallows the actual, correct error message).
Error from Mocha:
/…/test.jsx:1
import {
^^^^^^
SyntaxError: Cannot use import statement outside a module
Error from Node.js:
Error [ERR_MODULE_NOT_FOUND]: Cannot find package '@testing-library/jest-dom'
imported from /…/test.jsx
The bug originates from https://github.com/mochajs/mocha/blob/v9.1.3/lib/nodejs/esm-utils.js#L51
Steps to Reproduce
test.jsx
Without installing @testing-library/jest-dom
:
import '@testing-library/jest-dom';
NODE_ENV=test NODE_OPTIONS="--loader=./loader.mjs" npx mocha ./test.jsx
(The loader live-transpiles jsx via esbuild and marks the file as esm; it’s not especially important for the reproduction but it did help me find the bug in Mocha).
Expected behavior: Mocha reports the correct error (that the targeted package doesn’t exist, as node correctly reports).
Actual behavior: Mocha wrongly reports a different, unrelated error.
Reproduces how often: 100%
Versions
- The output of
mocha --version
andnode node_modules/.bin/mocha --version
: 9.1.3 (also occurs in 8.3.0) - The output of
node --version
: 17.2.0 - Your operating system
- name and version: macOS 12.1
- architecture (32 or 64-bit): 64 bit
- Your shell (e.g., bash, zsh, PowerShell, cmd): bash
- Your browser and version (if running browser tests): N/A
- Any third-party Mocha-related modules (and their versions):
- Any code transpiler (e.g., TypeScript, CoffeeScript, Babel) being used (and its version): esbuild
Additional Information
N/A
Issue Analytics
- State:
- Created 2 years ago
- Comments:9 (5 by maintainers)
@JakobJingleheimer unfortunately, I can’t. The
ERR_MODULE_NOT_FOUND
condition is there because you can runmocha ./foo
and assume that Mocha will load./foo.js
.But I fixed the problem and a PR will be coming in a few minutes! (it’s a hack, but the whole way of determining whether a file is ESM or CJS is ultimately a hack)
@JakobJingleheimer reproduced! The fix is really ugly, as this whole section of code is heuristics in figuring out whether the
require
threw for “real” reasons or just because it wasn’t supposed to berequire
-ed.But it’s mostly passing the test of time, and I can’t think of another way to fallback to
require
ifimport
fails (for example, if there arerequire
hooks that are needed).Hmm… maybe we don’t really need the
require
? is it time we got rid of it? AFAIR, require hooks are still called whenimporti
-ng a CJS file.(just thoughts. Will be fixed one way or another this weekend)