Alex Gusev
Alex Gusev

Reputation: 1854

Mocha tests with 'esm' support for native ES6 modules

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)
    ...

Upvotes: 17

Views: 21161

Answers (5)

Fery W
Fery W

Reputation: 1532

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

Upvotes: 2

Henry Ruhs
Henry Ruhs

Reputation: 1630

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"
    ]
}

Upvotes: 11

Ali Ch
Ali Ch

Reputation: 61

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

Upvotes: 6

cool_code
cool_code

Reputation: 208

this on works for me

"test": "mocha --require ts-node/register './src/test/**/*.ts'"

Upvotes: 2

Alex Gusev
Alex Gusev

Reputation: 1854

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

Upvotes: 3

Related Questions