使用 Mocha 测试 Node.js 应用程序,包括依赖项中的 ES6 模块

问题描述

我想使用 Mocha (v8.2.1) 测试我的简单 Node.js (v14.15.4) 应用程序。 我还包括 Babel 以在我的代码中编译 ES6 模块。

特别是,我使用 "@babel/core" (v7.12.10)"babel/register" (v7.12.10) 将编译器与 mocha 结合使用,而 "@babel/preset-env" (v7.12.11) 用于 ES6 模块支持

一切正常,直到我在代码中包含外部依赖项。就我而言,我想使用 bpmn-js (v8.2.0),它本身已准备好与 ES6 模块 (https://bpmn.io/blog/posts/2018-migrating-to-es-modules.html) 一起使用。

我的项目结构如下:

- bpmn
    - index.js
- node_modules
    - ...
- babel.config.json
- index.js
- index.test.js
- package.json

文件描述如下:

package.json

{
  "name": "test","version": "1.0.0","description": "","main": "index.js","scripts": {
    "test": "mocha --require @babel/register index.test.js"
  },"devDependencies": {
    "mocha": "8.2.1","@babel/core": "7.12.10","@babel/register": "7.12.10","@babel/preset-env": "7.12.11"
  },"dependencies": {
    "bpmn-js": "8.2.0"
  },"author": "","license": "ISC"
}

babel.config.json

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

index.js

export {
    default
  } from './bpmn';

bpmn/index.js

//import { Viewer } from 'bpmn-js';

export default (str) => {
    return str.toupperCase();
};

index.test.js

import toupperCase from './index';

const assert = require('assert');

describe('The module toupperCase',() => {
  it('should transform my test string',() => {
    assert.strictEqual(toupperCase('test'),'TEST');
  });
});

如前所述,运行 npm run test 时一切正常。 但是,如果我在 bpmn/index.js 文件的第 1 行中包含注释, 出现以下错误。似乎 babel 编译了我的本地项目文件,但忽略了外部依赖项,即 bpmn-js 在这种情况下

\node_modules\bpmn-js\index.js:1
export {
^^^^^^

SyntaxError: Unexpected token 'export'
    at wrapSafe (internal/modules/cjs/loader.js:979:16)
    at Module._compile (internal/modules/cjs/loader.js:1027:27)
    at Module._compile (D:\Code\Neuer Ordner\node_modules\pirates\lib\index.js:99:24)
    at Module._extensions..js (internal/modules/cjs/loader.js:1092:10)
    at Object.newLoader [as .js] (D:\Code\Neuer Ordner\node_modules\pirates\lib\index.js:104:7)
    at Module.load (internal/modules/cjs/loader.js:928:32)
    at Function.Module._load (internal/modules/cjs/loader.js:769:14)
    at Module.require (internal/modules/cjs/loader.js:952:19)
    at require (internal/modules/cjs/helpers.js:88:18)
    at Object.<anonymous> (D:\Code\Neuer Ordner\bpmn\/index.js:1:1)
    at Module._compile (internal/modules/cjs/loader.js:1063:30)
    at Module._compile (D:\Code\Neuer Ordner\node_modules\pirates\lib\index.js:99:24)
    at Module._extensions..js (internal/modules/cjs/loader.js:1092:10)
    at Object.newLoader [as .js] (D:\Code\Neuer Ordner\node_modules\pirates\lib\index.js:104:7)
    at Module.load (internal/modules/cjs/loader.js:928:32)
    at Function.Module._load (internal/modules/cjs/loader.js:769:14)
    at Module.require (internal/modules/cjs/loader.js:952:19)
    at require (internal/modules/cjs/helpers.js:88:18)
    at Object.<anonymous> (D:\Code\Neuer Ordner\/index.js:1:1)
    at Module._compile (internal/modules/cjs/loader.js:1063:30)
    at Module._compile (D:\Code\Neuer Ordner\node_modules\pirates\lib\index.js:99:24)
    at Module._extensions..js (internal/modules/cjs/loader.js:1092:10)
    at Object.newLoader [as .js] (D:\Code\Neuer Ordner\node_modules\pirates\lib\index.js:104:7)
    at Module.load (internal/modules/cjs/loader.js:928:32)
    at Function.Module._load (internal/modules/cjs/loader.js:769:14)
    at Module.require (internal/modules/cjs/loader.js:952:19)
    at require (internal/modules/cjs/helpers.js:88:18)
    at Object.<anonymous> (D:\Code\Neuer Ordner\/index.test.js:1:1)
    at Module._compile (internal/modules/cjs/loader.js:1063:30)
    at Module._compile (D:\Code\Neuer Ordner\node_modules\pirates\lib\index.js:99:24)
    at Module._extensions..js (internal/modules/cjs/loader.js:1092:10)
    at Object.newLoader [as .js] (D:\Code\Neuer Ordner\node_modules\pirates\lib\index.js:104:7)
    at Module.load (internal/modules/cjs/loader.js:928:32)
    at Function.Module._load (internal/modules/cjs/loader.js:769:14)
    at Module.require (internal/modules/cjs/loader.js:952:19)
    at require (internal/modules/cjs/helpers.js:88:18)
    at Object.exports.requireOrImport (D:\Code\Neuer Ordner\node_modules\mocha\lib\esm-utils.js:20:12)
    at Object.exports.loadFilesAsync (D:\Code\Neuer Ordner\node_modules\mocha\lib\esm-utils.js:33:34)
    at Mocha.loadFilesAsync (D:\Code\Neuer Ordner\node_modules\mocha\lib\mocha.js:431:19)
    at singleRun (D:\Code\Neuer Ordner\node_modules\mocha\lib\cli\run-helpers.js:125:15)
    at exports.runMocha (D:\Code\Neuer Ordner\node_modules\mocha\lib\cli\run-helpers.js:190:10)
    at Object.exports.handler (D:\Code\Neuer Ordner\node_modules\mocha\lib\cli\run.js:362:11)
    at D:\Code\Neuer Ordner\node_modules\yargs\lib\command.js:241:49

解决方法

您的方法有两个问题。第一个,非常基础,是您尝试在 Node.js 进程中导入 bpmn-js。此包只能在浏览器中运行,因为它取决于可用的 DOM 文档。你永远无法做到这一点。另一个问题是,正如您正确理解的那样,bpmn-js 使用 ES6 模块语法。默认情况下,@babel/register 会忽略node_modules 目录中的包。换句话说,它们没有被转译。您可以配置@babel/register 为 bpmn-js 提供豁免并对其进行转译,但您的导入仍然会失败,并显示以下内容:

ReferenceError: document is not defined

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...