Jest ES6模块:意外的模块导入

24

我正在尝试测试一个需要导入ES6模块的文件,像这样:

https://repl.it/HG9t/0

看起来我缺少一些配置使其正常工作。

如果您能够轻松使用另一个单元测试框架实现此目的,我也很感兴趣。

谢谢您提前的帮助。


据我所知,Node不支持ES2015的import语法,而是使用require - evolutionxbox
现在可以通过 NODE_OPTIONS='--experimental-vm-modules' jest 来支持。请参见 https://dev59.com/vlsV5IYBdhLWcg3w0hlU#61652773。 - Raine Revere
3个回答

11
  1. 安装所需依赖:

yarn add --dev babel-jest @babel/core @babel/preset-env

或者

npm install --save-dev babel-jest @babel/core @babel/preset-env

  1. 在您的主文件夹中创建 babel.config.js 文件并将其粘贴到该文件中:
// babel.config.js
module.exports = {
  presets: [
    [
      '@babel/preset-env',
      {
        targets: {
          node: 'current',
        },
      },
    ],
  ],
};
  1. 确保你的package.jsonjest.config.js中所有的jest设置都是默认值。

1
我得到了“加载配置时出错 - 您似乎正在使用本地的 ECMAScript 模块配置文件,这仅在异步运行 Babel 时受支持。” - Raine Revere

10

由于Node不支持模块化,你需要使用Babel来编译你的文件。请查看文档以了解如何配置Jest和Babel。


11
自从v8.5版本以来,Node通过--experimental-modules选项支持模块化。 - Dan Dascalescu
1
即使没有 .mjs 扩展名呢? - Biel Simon
5
是的,去掉mjs扩展名。您需要在package.json中添加" type": "module "并使用Dan提到的标志。 - Chris Magnuson
2
"type": "module" will only work from node v12 onwards https://nodejs.org/docs/latest-v12.x/api/esm.html but you can use node -r esm - velop
你根本不需要"type":"module"(除非你按照官方 Node 的方式进行操作)。如果你只是使用-r esm...与支持它的普通库(例如Node本身或Mocha)一起使用,ES6模块就可以“正常工作”。 - machineghost
当我在package.json文件中加入"type": "module"时,会出现'ReferenceError: module is not defined'的错误。 - roadev

0

我曾经遇到过与npm包“rgb-hex”和“hex-rgb”类似的问题,因为它们的主要导出是以ES6格式完成的。我正在使用一个带有Jest的TypeScript项目。我认为错误来自于Jest而不是TypeScript,因为Jest可以在正确转换的JavaScript上工作(根据其自己的配置)。潜在的问题是这些ES6风格的主要导出将会导致Jest出现问题(而不是tsc或TypeScript链),因为你需要告诉Jest进行转换。

我使用了“ts-jest”包找到了一个可用的配置,基于简单的预设(唯一需要注意的是忽略模式):

tsconfig.json:

{
    "compilerOptions": {
      "esModuleInterop": true,
      "module": "es2020",
      "moduleResolution": "nodenext",
      "forceConsistentCasingInFileNames": true,
      "strict": true,
      "skipLibCheck": true,
      "rootDir": "./",
      "allowJs": true
    },
    "ts-node": {
        "esm": true
    },
    "include": ["./ts-src/**/*"]
  }

jest.config.cjs

module.exports = {
  verbose: true,
  preset: 'ts-jest/presets/js-with-babel-esm',
  testEnvironment: 'node',
  transformIgnorePatterns: ['/node_modules/(?!(hex\-rgb|rgb\-hex)/)']
};

注意:上面的预设设置很重要,如果你想要使用带有esm的babel,请参考'ts-jest'的文档。
babel.config.cjs(完全原始但已包含且我认为是必需的)
module.exports = {
    presets: [['@babel/preset-env', {targets: {node: 'current'}}]],
  };

请注意忽略来自node_modules的内容模式。您正在使用正则表达式中的否定和分组告诉它“是的,除了这些特定的包模式之外,忽略node_modules进行转码”。这些东西出现在Jest中的原因是,node_modules中的软件包通常不使用其主文件index.js文件(或类似文件)中的ES6导出。而Jest通常不会对它们进行转换,因为那样它就必须扫描所有的node_modules。因此,您可以使用这些忽略模式(带有有些反直觉的正则表达式)来转换node_modules中的特定内容。
编辑:.cjs扩展名是因为我的整个项目在package.json中使用了"type":"module"。如果将这些文件保留为.js,则会收到非常详细的错误。.cjs扩展名告诉Node放松一下,只需使用它们的框架当前规范格式中的配置即可(这不是ES6...哈哈JS永远不会改变)。

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