Jest在使用绝对路径导入组件时会出现“找不到模块”的错误

182

运行Jest时收到以下错误

Cannot find module 'src/views/app' from 'index.jsx'

  at Resolver.resolveModule (node_modules/jest-resolve/build/index.js:179:17)
  at Object.<anonymous> (src/index.jsx:4:12)

index.jsx

import AppContainer from 'src/views/app';

package.json

  "jest": {
    "collectCoverageFrom": [
      "src/**/*.{js,jsx,mjs}"
    ],
    "setupFiles": [
      "<rootDir>/config/polyfills.js"
    ],
    "testMatch": [
      "<rootDir>/src/**/__tests__/**/*.{js,jsx,mjs}",
      "<rootDir>/src/**/?(*.)(spec|test).{js,jsx,mjs}"
    ],
    "testEnvironment": "node",
    "testURL": "http://localhost",
    "transform": {
      "^.+\\.(js|jsx|mjs)$": "<rootDir>/node_modules/babel-jest",
      "^.+\\.css$": "<rootDir>/config/jest/cssTransform.js",
      "^(?!.*\\.(js|jsx|mjs|css|json)$)": "<rootDir>/config/jest/fileTransform.js"
    },
    "transformIgnorePatterns": [
      "[/\\\\]node_modules[/\\\\].+\\.(js|jsx|mjs)$"
    ],
    "moduleDirectories": [
        "node_modules",
        "src"
    ],
    "moduleNameMapper": {
      "^react-native$": "react-native-web"
    },
    "moduleFileExtensions": [
      "web.js",
      "js",
      "json",
      "web.jsx",
      "jsx",
      "node",
      "mjs"
    ]
  },

我的测试运行的是只包含相对路径的文件,在目录树中正确运行。

澄清一下,我正在寻找如何配置Jest不在绝对路径上失败。


尝试使用 import AppContainer from './src/views/app'; 导入应用程序容器。 - Metalik
12
我需要知道如何运行绝对路径,这样我就不必在导入时反复返回多个目录或者在移动文件时更新多个文件。 - Seth McClaine
重要的是要提到这里的jest配置在package.json中。但它也可以在jest.config.json或其他文件中。 - oskrgg
重要的是要提到这里的jest配置在package.json中。但它也可以在jest.config.json或其他文件中。 - undefined
15个回答

111

我认为你正在寻找:rootsmodulePaths以及moduleDirectories

你可以添加相对路径和绝对路径。

我建议在roots数组中包含<rootDir>,在modulePaths数组中包含<rootDir>,在moduleDirectories数组中包含node_modules,除非你有充分的理由将它们排除在外。

"jest": {
  "roots": [
    "<rootDir>",
    "/home/some/path/"
  ],
  "modulePaths": [
    "<rootDir>",
    "/home/some/other/path"
  ],
  "moduleDirectories": [
    "node_modules"
  ],
}

1
这帮助我解决了我的Angular问题。我的错误是Cannot find module 'src/app/core/services/seo.service' from 'src/app/blog/blog-list/blog-list.component.ts',并且在我的spec文件中导入routerTestingModule后发生了这个错误,这是为了解决一个错误NG0304:'router-outlet'不是已知元素:在我的jest.config.js中 module.exports = { preset: "jest-preset-angular", setupFilesAfterEnv: ["<rootDir>/setup-jest.ts"], globalSetup: "jest-preset-angular/global-setup", modulePaths: ["<rootDir>"], // <-- adding this solved it }; - BrunoElo
11
"modulePaths": ["<rootDir>/src/"] 就是我所需要的东西。 - totymedli
1
"modulePaths": [ "<rootDir>/../" ] 这是我的情况下 :=) - c_froehlich
这在Create React App中不起作用。我们必须先弹出才能运行:/ - George Mylonas
moduleDirectories可以省略,因为它的默认值已经是["node_modules"]了。 - undefined

72

由于在package.json文件中你有以下内容:

"moduleDirectories": [
    "node_modules",
    "src"
]

这段话的意思是:每个你要导入的模块都会先在node_modules里查找,如果没找到,就会去src目录查找。

既然它会去src目录查找,那么你应该使用:

import AppContainer from 'views/app';
请注意,该路径是相对于 src 目录的绝对路径,您无需导航即可找到它。

或者您可以在 package.json 中的 moduleDirectories 中配置您的根目录,以便您按照所需导入所有组件。


2
在我的情况下,moduleNameMapper 是最好的选择,因为我们有 @ 指向一些特定的根目录。 - giovannipds

22

添加

"moduleDirectories": [
    "node_modules",
    "src"
]

如果您的package.json文件中有Jest的配置,那么应该可以正常工作。

如果您有一个jest.config.js文件,您应该将其添加到该文件中,否则jest.config.js文件会覆盖并忽略package.json文件。因此,在您的jest.config.js文件中:

module.exports = {
// ... lots of props
  moduleDirectories: ["node_modules", "src"],
// ...
}

8

那是因为 Jest 不识别如 src/views/app 这样的相对导入。

package.json 中添加一个 rootDir 和一个 modulePaths

"name": "my-app",
...
"jest": {
    ...
    "rootDir": "./",
    "modulePaths": [
      "<rootDir>"
    ],
    ...
  }
}

我面临的问题是在另一个导入的文件中的导入。在nestJs中使用它。实际的测试文件在一个名为tests的文件夹中,而实际的代码在src中。稍作修改后,上述方法似乎对我有效:"modulePaths": [ "<rootDir>/../" ] - undefined

6
在我的情况下,我正在运行集成测试,并且所有的测试都在同一个文件中,路径为src/int-test.spec.ts。为了读取路径,我不得不编写以下代码: 解决方案1
"jest": {
    ...,
    "moduleNameMapper": {
      "src/(.*)": "<rootDir>/$1"
    }
  }

另一种方法是创建jest.config.js文件,如果命名为jest.config.js|ts|mjs|cjs|json,则该文件将被自动发现。

解决方案2

const path = require('path');

module.exports = {
  moduleFileExtensions: ['js', 'json', 'ts'],
  roots: ['src'],
  testRegex: '.*\\.spec\\.ts$',
  transform: {
    '^.+\\.(t|j)s$': 'ts-jest',
  },
  collectCoverageFrom: ['**/*.(t|j)s'],
  coverageDirectory: '../coverage',
  testEnvironment: 'node',
  moduleDirectories: ['node_modules', 'src', __dirname],
};


此外,如果您在使用带前缀的导入时遇到此问题(例如parcel喜欢使用的方式),您可以将映射器更改为:"prefix:(.*)": "$1",然后根据需要模拟不带前缀的路径。 - Lerk

5

在更新了package.json后,请确保您已经运行了npm inpm install。我的问题是 :0


2
对于那些使用Webpack和Babbel从零开始构建项目的人,请尝试以下步骤:
  1. 删除node_modules文件夹并重新安装(这是解决我的问题的方法)。

  2. 这是一个设置Webpack所需文档的链接,但在某些情况下可能不需要。 Jest文档Webpack

  3. 这是一个解释如何在React中设置Jest(不使用Create-React-App)的文档链接。 Jest React文档

4. 这是一个使用Jest进行简单设置的示例。您可以在package.json或Jest配置文件中进行设置。

免责声明:这并没有回答OP的问题。但大多数人会因为这个问题使用关键字而到达此处。

  "jest": {
"moduleFileExtensions": ["js", "jsx"],
"moduleDirectories": ["node_modules"],
"moduleNameMapper": {
  "\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/__mocks__/fileMock.js",
  "\\.(css|less)$": "<rootDir>/__mocks__/styleMock.js"
}

}


1

2
你的回答可以通过提供更多支持信息来改进。请编辑以添加进一步的细节,例如引用或文档,以便他人可以确认你的答案是正确的。您可以在帮助中心中找到有关如何编写良好答案的更多信息。 - Community

1
只需将“modulePaths”添加到您的package.json文件中。
"jest": {
    ...
    "modulePaths": [
      "<rootDir>"
    ],
    ...
  }
}

1

在我的情况下,添加 __esModule:true 解决了这个问题。

jest.mock('module',()=>({
  __esModule: true,                    // this makes it work
  default: jest.fn()
}));

希望这能对某些人有所帮助。虽然这与问题不太相关。

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