【问题标题】:Is it possible to use ES6 modules in Mocha tests?是否可以在 Mocha 测试中使用 ES6 模块?
【发布时间】:2018-03-11 06:27:54
【问题描述】:

ES6、Windows 10 x64、Node.js 8.6.0、Mocha 3.5.3

是否可以在 Mocha 测试中使用 ES6 模块?我遇到了exportimport 关键字的问题。

/* eventEmitter.js
 */

/* Event emitter. */
export default class EventEmitter{

    constructor(){

        const subscriptions = new Map();

        Object.defineProperty(this, 'subscriptions', {
            enumerable: false,
            configurable: false,
            get: function(){
                return subscriptions;
            }
        });
    }

    /* Add the event listener.
     * @eventName - the event name. 
     * @listener - the listener.
     */
    addListener(eventName, listener){
        if(!eventName || !listener) return false;
        else{
            if(this.subscriptions.has(eventName)){
                const arr = this.subscriptions.get(eventName);
                arr.push(listener);
            }
            else{
                const arr = [listener];
                this.subscriptions.set(eventName, arr);
            }
            return true;
        }
    }

    /* Delete the event listener.
     * @eventName - the event name. 
     * @listener - the listener.
     */
    deleteListener(eventName, listener){
        if(!eventName || !listener) return false;
        else{
            if(this.subscriptions.has(eventName)){
                const arr = this.subscriptions.get(eventName);
                let index = arr.indexOf(listener);

                if(index >= 0){
                    arr.splice(index, 1);
                    return true;
                }
                else{
                    return false;
                }
            }
            else{
                return false;
            }
        }
    }

    /* Emit the event.
     * @eventName - the event name. 
     * @info - the event argument.
     */
    emit(eventName, info){
        if(!eventName || !this.subscriptions.has(eventName)) {
            return false;
        }
        else{
            for(let fn of this.subscriptions.get(eventName)){
                if(fn) fn(info);
            }
            return true;
        }
    }
}

摩卡测试:

/* test.js 
 * Mocha tests.
 */
import EventEmitter from '../../src/js/eventEmitter.js';

const assert = require('assert');

describe('EventEmitter', function() {
  describe('#constructor()', function() {
    it('should work.', function() {
        const em = new EventEmitter();
        assert.equal(true, Boolean(em));
    });
  });
});

我直接通过 PowerShell 控制台启动 mocha。结果:

【问题讨论】:

  • 我认为关键是 Node 8.6 支持导入/导出而无需转译。但是,我不确定 mocha 是否允许使用它所需的 --experimental-modules,因此可能仍然需要转译,直到它这样做(或直到支持使其稳定)
  • 我认为这不是重复的问题。顶级浏览器原生支持 ES 模块,可以run Mocha tests without using Babel
  • 时间已经过去,现在可以在 mocha 中使用 import 语法,这要感谢 esm 模块。将其添加到您的依赖项中,然后使用 mocha -r esm。你甚至不需要切换到.mjs 扩展。
  • 这个问题实际上不是 stackoverflow.com/questions/46255387/… 的重复,因为后者是关于 Babel,而这个问题不是。

标签: javascript node.js ecmascript-6 mocha.js


【解决方案1】:

Mocha 从 7.1.0 版开始具有 support for ESM(发布时间:2020 年 2 月 26 日)。

这需要 Node 12.11.0 或更高版本,并受当前在 Node 中使用模块的限制/限制:

  • 您必须对使用 ES 模块的源文件使用 .mjs 文件扩展名,或者您的 package.json 中必须包含 "type": "module"
  • import来自 CommonJS 模块时,您不能使用命名导入
  • 本地 import 语句必须明确包含 .js 文件扩展名

等等。

更新答案

我之前曾推荐使用 esm 作为 Mocha 内置模块支持的替代方案,但该软件包不再被维护,无法处理像 ?. 这样的新语法结构,并且似乎可能无法在都带有较新版本的 Mocha。

但是,@babel/register 似乎对此很有效:

mocha -r @babel/register -r regenerator-runtime/runtime

我正在使用这个预设(在 .babelrc 中):

{
    "presets": [
        "@babel/preset-env"
    ]
}

并且此设置需要以下软件包:

  • @babel/core
  • @babel/注册
  • @babel/preset-env
  • 再生器运行时

到目前为止,我个人的经验是,尝试利用 Mocha 新的、固有的 ESM 支持仍然是一个相当大的负担,但使用这种方法非常无缝。

上一个答案

另一种选择是使用esm 包,它不受上述限制:

mocha -r esm

到目前为止,我个人的经验是,尝试利用 Mocha 新的、固有的 ESM 支持仍然是一个相当大的负担,但使用 esm 包是非常无缝的。

【讨论】:

  • 如果你想使用mocha --watch,那么你还必须像mocha --watch --parallel这样并行运行测试,这样手表就不会调用loadFiles
  • 这似乎不再起作用了。 Here's a simple repo。如果您在终端中单击+,然后键入npm test,即使测试命令是mocha --require esm test,它也会失败并显示“SyntaxError:无法在模块外使用导入语句”
  • @gman 这有点奇怪,但我看到和你一样的问题。也许在较新版本的 Mocha 中有一些东西打破了这一点。请参阅我上面的更新答案。我现在推荐使用 Babel 而不是 esmthat seems to still work。仅供参考,您的 import 声明中似乎有一个错字,但这似乎不是您看到的错误的原因。
  • "Cannot use import statement outside a module" 在使用 babel 时似乎又回来了,请检查您的代码框
【解决方案2】:

在我的情况下运行:

基本命令:

npx mocha --require esm test_path/

package.json

"scripts": {
    // ...
    "test": "npx mocha --require esm --reporter spec test_path/"
}

跑步

npm test

【讨论】:

  • 我得到了Cannot find module 'esm'
  • 大概是指this。对于不知道--require 工作原理的人来说,并不太清楚。
【解决方案3】:

使用 Babel 和 Browserfy 是可能的 https://drublic.de/blog/es6-modules-using-browserify-mocha/

【讨论】:

  • npm i -D esm 然后使用 mocha --require esm 运行测试
  • 鉴于 node 开箱即用地支持此功能,这似乎是一个非答案,所以问题是如何让 mocha 在 node 中启用此功能。
  • @user239558 没那么容易。在 Mocha 决定之前,无法使用内置支持。您可以像这样传递标志以在 Node 中启用模块支持:node --experimental-modules $(npm bin)/_mocha,但它仍然会在使用 import * from './my-module' 运行代码时崩溃。原因是 Mocha 使用普通的 CommonJS 要求导入测试文件,而 Node 要求它使用 import 来启用文件作为 ES 模块运行的模式。这意味着摩卡必须改变它才能工作。在此之前,ESM 或转译是您的答案。
猜你喜欢
  • 1970-01-01
  • 2016-11-08
  • 2021-01-23
  • 1970-01-01
  • 2018-12-28
  • 2016-08-26
  • 2019-09-01
  • 2020-08-05
  • 2019-10-23
相关资源
最近更新 更多