开玩笑:node_module 依赖项使用 import 语句并使测试崩溃

Jest: node_module dependency uses import statement and crashes the test

TL;DR

我的 Jest 测试崩溃

    SyntaxError: Cannot use import statement outside a module

因为 node_module 使用 import 语句。我该如何解决这个错误?

上下文

我正在编写一个 Next.js 应用程序,使用 Jest 作为我的测试 运行ner 并使用 Magic 进行身份验证。我已经 ts-node 安装到 运行 我在 TypeScript 中的 Jest 测试。

我想测试一个使用 @magic-sdk/admin 包的无服务器函数,该包又使用 ethereum-cryptography 作为其 keccak 哈希算法。

当我 运行 测试时它崩溃了,因为 ethereum-cryptography 包使用了 import 语句。

 FAIL  src/features/user-authentication/login-handler.test.ts
  ● Test suite failed to run

    Jest encountered an unexpected token

    This usually means that you are trying to import a file which Jest cannot parse, e.g. it's not plain JavaScript.

    By default, if Jest sees a Babel config, it will use that to transform your files, ignoring "node_modules".

    Here's what you can do:
     • If you are trying to use ECMAScript Modules, see https://jestjs.io/docs/en/ecmascript-modules for how to enable it.
     • To have some of your "node_modules" files transformed, you can specify a custom "transformIgnorePatterns" in your config.
     • If you need a custom transformation specify a "transform" option in your config.
     • If you simply want to mock your non-JS modules (e.g. binary assets) you can stub them out with the "moduleNameMapper" config option.

    You'll find more details and examples of these config options in the docs:
    https://jestjs.io/docs/en/configuration.html

    Details:

    /Users/my-computer/dev/my-app/node_modules/ethereum-cryptography/src/keccak.ts:1
    ({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,global,jest){import { createHashFunction } from "./hash-utils";
                                                                                             ^^^^^^

    SyntaxError: Cannot use import statement outside a module

      at Runtime.createScriptFromCode (node_modules/jest-runtime/build/index.js:1350:14)
      at Object.<anonymous> (node_modules/ethereum-cryptography/src/keccak.ts:3:26)

Test Suites: 1 failed, 1 total
Tests:       0 total
Snapshots:   0 total
Time:        2.292 s
Ran all test suites related to changed files.

我的tsconfig.json

{
  "compilerOptions": {
    "allowJs": true,
    "baseUrl": "./src",
    "esModuleInterop": true,
    "forceConsistentCasingInFileNames": true,
    "isolatedModules": true,
    "jsx": "preserve",
    "lib": ["dom", "dom.iterable", "esnext"],
    "module": "esnext",
    "moduleResolution": "node",
    "noEmit": true,
    "resolveJsonModule": true,
    "skipLibCheck": true,
    "strict": true,
    "target": "es5"
  },
  "exclude": ["node_modules"],
  "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"]
}

我的 jest.config.ts 看起来像这样。

export default {
  moduleDirectories: ['node_modules', 'src'],
  moduleNameMapper: {
    '\.(css|less)$': '<rootDir>/src/tests/mocks/style-mock.js',
  },
  setupFilesAfterEnv: ['./jest.setup.ts'],
  setupFiles: ['<rootDir>/src/tests/setup-environment-variables.js'],
};

我试过的

看起来这是大量 Google 结果的常见错误,但其中 none 有效。这是我尝试过的。

我尝试将文件夹包含在 transformIgnorePatterns 中。

const esModules = ['ethereum-cryptography', '@magic-sdk/admin'].join('|');

export default {
  moduleDirectories: ['node_modules', 'src'],
  moduleNameMapper: {
    '\.(css|less)$': '<rootDir>/src/tests/mocks/style-mock.js',
  },
  setupFilesAfterEnv: ['./jest.setup.ts'],
  setupFiles: ['<rootDir>/src/tests/setup-environment-variables.js'],
  transformIgnorePatterns: [`/node_modules/(?!${esModules})`],
};

没用。

我尝试使用 transformts-jest 明确地转换它。

transform: { '^.+\.(ts|tsx|js|jsx)?$': 'ts-jest' },

我也试过在tsconfig.json中把模块改成commonjs,也没用。

我该如何解决这个问题并让测试达到 运行?

我发现了我的错误。我的 jest.config.tsmoduleDirectories 中有 src 因为我配置 Next.js 支持绝对导入。

  moduleDirectories: ['node_modules', 'src'], //  fails

当我将其更改为从 rootDir 中显式更改时,它起作用了

export default {
  moduleDirectories: ['node_modules', '<rootDir>/src'],
  moduleNameMapper: {
    '\.(css|less)$': '<rootDir>/src/tests/mocks/style-mock.js',
  },
  setupFilesAfterEnv: ['./jest.setup.ts'],
  setupFiles: ['<rootDir>/src/tests/setup-environment-variables.js'],
};