16

There is great post "Testing native ES modules using Mocha and esm" of Alex Gibson. Thanks him.

I've tried to use mocha with native ES modules support in my project and I had 2 different errors:

$ ./node_modules/mocha/bin/mocha --require esm './test/Util.test.js'

TypeError [ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING]: A dynamic import callback was not specified.
    at exports.importModuleDynamicallyCallback (internal/process/esm_loader.js:41:9)
    at formattedImport (/.../node_modules/mocha/lib/esm-utils.js:6:23)
    at Object.exports.requireOrImport (/.../node_modules/mocha/lib/esm-utils.js:23:14)
    at Object.exports.loadFilesAsync (/.../node_modules/mocha/lib/esm-utils.js:33:34)
    at Mocha.loadFilesAsync (/.../node_modules/mocha/lib/mocha.js:427:19)
    ...
$ /usr/bin/node /.../node_modules/mocha/bin/mocha -r esm --ui bdd --reporter \ 
  /.../PhpStorm/plugins/NodeJS/js/mocha-intellij/lib/mochaIntellijReporter.js \ 
  /.../test/Util.test.js

TypeError: Invalid host defined options
    at formattedImport (/.../node_modules/mocha/lib/esm-utils.js:6:23)
    at Object.exports.requireOrImport (/.../node_modules/mocha/lib/esm-utils.js:23:14)
    at Object.exports.loadFilesAsync (/.../node_modules/mocha/lib/esm-utils.js:33:34)
    at Mocha.loadFilesAsync (/.../node_modules/mocha/lib/mocha.js:427:19)
    ...
Alex Gusev
  • 1,526
  • 3
  • 16
  • 35

5 Answers5

12

From what I learned in the past 2 hours:

package.json

{
    "type": "module"
}

tsconfig.json

{
    "compilerOptions": {
        "module": "esnext",
        "moduleResolution": "node",
    }
}

.mocharc.json

{
    "node-option": [
        "experimental-specifier-resolution=node",
        "loader=ts-node/esm"
    ]
}
Henry Ruhs
  • 1,533
  • 1
  • 20
  • 32
4

UPDATE: I think the reason for the error is a conflict between --require esm option in mocha arguments and other methods of indicating that sources are ES6 modules (*.mjs or type option in package.json). My current tests have .mjs extensions and the same error is occured without "type": "module" in package.json

old staff

I've looked up for the reason and this is the reason - my own package.json:

"type": "module"

Note from nodejs.org:

Node.js treats JavaScript code as CommonJS modules by default. Authors can tell Node.js to treat JavaScript code as ECMAScript modules via the .mjs file extension, the package.json "type" field, or the --input-type flag.

Just remove "type": "module" from your package.json and mocha will run tests with esm support as described in Alex Gibson's post.

This is my test repo with code to try: flancer64/so_mocha_esm

Alex Gusev
  • 1,526
  • 3
  • 16
  • 35
  • 8
    I can't remove `"type": "module"`, because I actually want to generate ESM modules as an end product. I'm also working in TypeScript, and having no luck so far trying to get mocha, ts-node, esm, and/or the `--experimental-specifier-resolution` flag working together happily. – kshetline Dec 21 '20 at 04:08
  • @kshetline, just try to leave one only flag of ES6 sources: `"type": "module"` in `package.json` or `--require esm` option in `mocha` arguments. `mocha` is failed when both variants present. – Alex Gusev Dec 21 '20 at 11:17
  • 1
    I've tried all permutations and combinations... still no luck! For the moment I'm settling for a very sad hack that modifies my package.json via sed-like search & replace to change `"type"` to `"commonjs"`, run my tests, then fix package.json back to `"module"`. Ugh. – kshetline Dec 21 '20 at 12:12
  • I fixed the "invalid host defined options" error by leaving type:module in package.json and instead renaming the problematic file .js instead of .esm.js. – Seth Jan 18 '21 at 18:18
  • 4
    I just had the same problem, even without `"type": "module"`. Downgrading Mocha from version 9.x.x to 8.3.0 solved the problem. – GroovyPanda Jun 15 '21 at 11:00
  • I can confirm that downgrading `mocha` from `v9.0.x` to `v8.4.x` solve the issue. Thank you @RemiX, – Fery W Jul 21 '21 at 12:40
3

I have found the solution after a countless number of experiments and DuckDuckGo searches :)

mocha --loader=ts-node/esm 'test/**/*.{ts,js}'

P.S. https://github.com/TypeStrong/ts-node/issues/1007

Ali Ch
  • 31
  • 1
2

this on works for me

"test": "mocha --require ts-node/register './src/test/**/*.ts'"
cool_code
  • 178
  • 2
  • 8
1

Came across same issue and figured out that I only have these options to make it work.

  1. Downgrade mocha version from 9.x.x to 8.3.0, as suggested by @RemiX here, or
  2. Add experimental-specifier-resolution=node with loader=ts-node/esm in your mocharc.node-option as suggesteed in this gist

Hope that helps

Fery W
  • 1,402
  • 1
  • 15
  • 28