使用 Jest 运行测试时无法使用 uuid 模块

x80*_*486 3 node.js jestjs node-uuid

我有一个12.16.3使用 Express的非常简单的 Node.js( ) 应用程序4.17.1。我正在尝试使用 Jest26.0.1来运行测试套件,但由于整个项目中使用的uuid模块(版本8.1.0)存在一些问题,同样失败了:

[x80486@uplink:~/Workshop/node-guacamole]$ npm run test 

> node-guacamole@0.3.0 test /home/x80486/Workshop/node-guacamole
> node --experimental-modules --experimental-vm-modules ./node_modules/.bin/jest --coverage --detectOpenHandles --forceExit --verbose

(node:71155) ExperimentalWarning: The ESM module loader is experimental.
 FAIL  src/domain/customer.test.js
  ? Test suite failed to run

    SyntaxError: The requested module 'uuid' does not provide an export named 'v4'

      at jasmine2 (node_modules/jest-jasmine2/build/index.js:228:5)

 FAIL  src/service/customer.service.test.js
  ? Test suite failed to run

    SyntaxError: The requested module 'uuid' does not provide an export named 'v4'

          at async Promise.all (index 4)
      at jasmine2 (node_modules/jest-jasmine2/build/index.js:228:5)

 FAIL  src/handler/customer.handler.test.js
  ? Test suite failed to run

    SyntaxError: The requested module 'uuid' does not provide an export named 'v4'

          at async Promise.all (index 2)
          at async Promise.all (index 7)

----------|---------|----------|---------|---------|-------------------
File      | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
----------|---------|----------|---------|---------|-------------------
All files |       0 |        0 |       0 |       0 |                   
----------|---------|----------|---------|---------|-------------------
Test Suites: 3 failed, 3 total
Tests:       0 total
Snapshots:   0 total
Time:        0.63 s
Ran all test suites.
Run Code Online (Sandbox Code Playgroud)

我导入模块,如:import { v4 } from "uuid"; 另一方面,应用程序运行成功:

[x80486@uplink:~/Workshop/node-guacamole]$ npm run start:dev 

> node-guacamole@0.3.0 start:dev /home/x80486/Workshop/node-guacamole
> nodemon --experimental-modules --experimental-vm-modules ./src/main.js

[nodemon] 2.0.4
[nodemon] to restart at any time, enter `rs`
[nodemon] watching path(s): *.*
[nodemon] watching extensions: js,mjs,json
[nodemon] starting `node --experimental-modules --experimental-vm-modules ./src/main.js`
(node:74672) ExperimentalWarning: The ESM module loader is experimental.
2020-06-03T03:28:48.889Z [debug] - Server running at http://localhost:8080
2020-06-03T03:28:48.889Z [info] - Press CTRL-C to stop
Run Code Online (Sandbox Code Playgroud)

...一切正常。我很困惑......我不明白为什么这只会用 Jest 失败。我还需要做些什么才能让它发挥作用?

Fra*_*cia 5

TL; DR:不是玩笑还支持领域"exports"package.json

问题是 Node.js 使用 ESM 版本,因为它理解 package.json 中的“exports”字段,但由于 Jest 尚不支持它,Jest 使用 package.json 中的“main”字段导出 CommonJS 版本. 请参阅相关的 package.json 部分

...
"main": "./dist/index.js",
"exports": {
  "./package.json": "./package.json",
  ".": {
    "require": "./dist/index.js",
    "import": "./wrapper.mjs"
  }
},
...
Run Code Online (Sandbox Code Playgroud)

这是做什么的:

  1. main与往常一样,默认导出为。
  2. 如果exports理解,则覆盖"main"导出
  3. 默认导出"."定义了 require 和 import,因此 Node.js 使用“导入”
  4. 但问题是Jest 问题表明它尚未理解“Package Exports”,因此 Jest 尝试加载 CommonJS 文件(从“main”),而 Node.js 加载 ESM 文件。

发现了完全相同的问题并在此处记录了下来。作为实验,这应该适用于 Jest:

import uuid from 'uuid';
const { v4 } = uuid;
Run Code Online (Sandbox Code Playgroud)

但这不适用于 Node.js,因为 UUID 没有定义默认的 export

你有两个现实的选择:

  • 等到 Jest 支持包导出,他们在 ESM 支持方面做得很好,我认为不会需要很长时间。
  • 支持我uuid包中的提议,他们还导出默认值,例如export default uuidin wrapper.mjs,这将允许您使用我上面的代码段。

  • 我认为弗朗西斯科说得对。作为 `uuid` 的维护者,我想指出的是,这些都是实验性的 Node.js API(因此有 `--experimental-modules --experimental-vm-modules` 标志),因此会出现一些问题。我不想仅仅为了解决笑话中当前的缺陷而添加默认导出,该缺陷很快就会得到修复。这只会使用玩笑测试正确的“pkg.exports”支持变得更加困难。 (2认同)