Jest "Cannot find module" with typescript paths in CI
Asked Answered
M

4

14

On the Gitlab-CI environment 2 of our Jest tests fail with Cannot find module.
The strange thing is that it works on my local Win10 machine - even when I run the tests in a similar docker-container (node 12.12.0).

Here is the console output:

FAIL apps/server/src/domain/dashboard/permission-group.service.spec.ts
Test suite failed to run
  Cannot find module '@cm/utils-server' from 'license.service.ts'
     9 |   isLicenseFileContent,
    10 |   LicenseStatus,
  > 11 |   parseLicenseInfo
       |                   ^
    12 | } from '@cm/license-shared';
    13 | import { ExitCode } from '../../util/exit-codes';
    14 | import { readFile } from '@cm/utils-server';
    at Resolver.resolveModule (../../node_modules/jest-resolve/build/index.js:259:17)
    at Object.<anonymous> (src/domain/license/license.service.ts:11:24)

I am not sure how to correctly interpret this output:

  1. permission-group.service.spec.ts: this is the test that fails
  2. Cannot find module '@cm/utils-server' from 'license.service.ts':
    Ok, the test or some of its dependencies, use license.service.ts and in the license.service.ts file the '@cm/utils-server' module cannot be found.
  3. What is the meaning of error-indicator (> at parseLicenseInfo)?
    • This is for the import @cm/license-shared - not for @cm/utils-server as indicated by the error message in 2
    • @cm/utils-server is also imported, but 2 lines below in line 14: So is this maybe just a bug in jest?
Monumental answered 30/11, 2019 at 13:22 Comment(2)
Having the same issue... if you found a resolution, I would love to hear it.Waki
@Waki currently only a workaround: we had paths defined in multiple tsconfig.json files of our mono-repo. We moved all paths up to the root-tsconfig and now the tests work again. But we don't really understand why this works. And this has the drawback that it is now easy to accicentially refer to a path that you shouldn't use in the lib (because the IDE now always uses all paths for code-assistance)Monumental
H
16

I just had this issue and searched for some solutions. Found this site which gave a clue about what could be done: to configure Jest's moduleNameMapper property.

So, reading the documentation I found this solution:

  1. Open the tsconfig.json and jest.config.js files (or equivalent)

  2. In tsconfig.json, find your absolute paths definition. My configuration looks like this:

"paths": {
    "@modules/*": ["modules/*"],
    "@config/*": ["config/*"],
    "@shared/*": ["shared/*"]
}
  1. In the jest.config.json, find and uncomment the moduleNameMapper property and start to translate your TS absolute paths into the Jest mapper syntax. Sounds complicated, but it isn't:
moduleNameMapper: {
    "@modules/(.*)": "<rootDir>/src/modules/$1",
    "@config/(.*)": "<rootDir>/src/config/$1",
    "@shared/(.*)": "<rootDir>/src/shared/$1",
}
  • The <rootDir> if defined automatically, and points to the package.json directory
  • "@modules/(.*)" is a Regex for "any string starting with '@module/' followed by anything after it
  • "<rootDir>/src/modules/$1" is the corresponding directory. $1 is a pointer to the Regex expression between the parenthesis ((.*)). Other expressions will be pointed by $2, $3 and so on

After doing this, I was able to execute my tests without any problem.

Console output before follow the above steps:

$ jest
 FAIL  src/modules/appointments/services/CreateAppointmentService.spec.ts
  ● Test suite failed to run

    Cannot find module '...'

Console output after:

$ jest
 PASS  src/modules/appointments/services/CreateAppointmentService.spec.ts

Hope this help someone, Thanks!

Haemolysis answered 9/8, 2020 at 17:51 Comment(1)
It can be simplified by pathsToModuleNameMapper() method in ts-jest/utils. kulshekhar.github.io/ts-jest/docs/getting-started/paths-mapping In this case, the prefix should be set to <rootDir>/srcTranspose
A
2

For those who are facing this issue in 2022. Please add this code in your jest-unit.json (or your jest config json file).

"moduleDirectories": ["<rootDir>/../", "node_modules"]

Result:

{
  "moduleFileExtensions": ["js", "json", "ts"],
  "rootDir": ".",
  "testEnvironment": "node",
  "testRegex": ".\\.spec.ts$",
  "transform": {
    "^.+\\.(t|j)s$": "ts-jest"
  },
  "moduleDirectories": ["<rootDir>/../", "node_modules"]
}
Adduct answered 29/9, 2022 at 13:58 Comment(0)
M
0

For now we use a workaround: we had paths defined in multiple tsconfig.json files of our mono-repo. We moved all paths up to the root-tsconfig and now the tests work again.
But we don't really understand why this works.

And a drawback is that it's now easy to accidentally refer to a path that you shouldn't use in the lib (because the IDE now always uses all paths for code-assistance)

Monumental answered 12/5, 2020 at 8:19 Comment(0)
T
0

I meet the same problem, I found the reason is the package(which cannot found) doesn't set the main field in package.json, add it then everythings ok.

Thigh answered 4/1, 2023 at 8:0 Comment(1)
As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.Nigelniger

© 2022 - 2024 — McMap. All rights reserved.