使用'mocha'进行测试,支持原生ES6模块的'esm'

16
有一篇非常棒的文章 "Testing native ES modules using Mocha and esm" 是由Alex Gibson撰写的。非常感谢他。
我尝试在我的项目中使用具有原生ES模块支持的mocha,并遇到了两个不同的错误:
$ ./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)
    ...
5个回答

11

根据我过去两小时学到的知识:

package.json

{
    "type": "module"
}

tsconfig.json

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

.mocharc.json

{
    "node-option": [
        "experimental-specifier-resolution=node",
        "loader=ts-node/esm"
    ]
}

4

更新:我认为错误的原因是mocha参数中的--require esm选项与其他指示源为ES6模块的方法之间存在冲突(如*.mjspackage.json中的type选项)。我的当前测试文件使用.mjs扩展名,在package.json中没有"type": "module"时也出现了相同的错误。

旧内容

我已经查找了原因,这就是原因-我的package.json文件:

"type": "module"

来自 nodejs.org 的注意事项:

默认情况下,Node.js将JavaScript代码视为CommonJS模块。 作者可以通过.mjs文件扩展名、package.json中的"type"字段或--input-type标志告诉Node.js将JavaScript代码视为ECMAScript模块。

"type": "module"从您的package.json中删除即可,mocha将按照Alex Gibson帖子中描述的方式支持esm运行测试。
这是我的测试存储库,其中包括尝试的代码:flancer64/so_mocha_esm

9
我不能移除"type": "module",因为我希望生成ESM模块作为最终产品。我还在使用TypeScript,但是到目前为止,我尝试让mocha、ts-node、esm和/或--experimental-specifier-resolution选项一起正常工作时没有成功。 - kshetline
@kshetline,尝试只在package.json中留下一个ES6源的标志:"type": "module"或在mocha参数中使用--require esm选项。当两种变体同时存在时,mocha会失败。 - Alex Gusev
1
我已经尝试了所有的排列组合......还是没有成功!目前我只能采用一个非常可悲的hack,通过类似于sed的搜索和替换来修改我的package.json文件,将"type"更改为"commonjs",然后运行我的测试,最后再将package.json修复回"module"。唉。 - kshetline
我通过在package.json中保留type:module并将有问题的文件从.esm.js重命名为.js来解决了“定义的选项无效”的错误。 - Seth
4
我刚遇到了同样的问题,即使没有 "type": "module"。将 Mocha 从版本 9.x.x 降级到 8.3.0 可以解决这个问题。 - RemiX
我可以确认将 mochav9.0.x 降级到 v8.4.x 可以解决这个问题。谢谢 @RemiX。 - Fery W

3

2
这对我有效。
"test": "mocha --require ts-node/register './src/test/**/*.ts'"

1

我遇到了同样的问题,并发现只有以下两种方法可以解决它:

  1. mocha 版本从 9.x.x 降级为 8.3.0,如 @RemiX 在这里建议的那样,或者
  2. 按照此 gist中建议的,在你的 mocharc.node-option 中添加 experimental-specifier-resolution=nodeloader=ts-node/esm

希望这可以帮到你。


这里已经回答了所有问题,不需要再添加任何内容。 - vsync

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接