13

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?
skyboyer
  • 22,209
  • 7
  • 57
  • 64
TmTron
  • 17,012
  • 10
  • 94
  • 142
  • Having the same issue... if you found a resolution, I would love to hear it. – Donovan Dec 05 '19 at 12:05
  • 1
    @Donovan 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) – TmTron Dec 05 '19 at 12:13

4 Answers4

12

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!

Dahan Schuster
  • 306
  • 4
  • 7
  • 2
    It can be simplified by pathsToModuleNameMapper() method in ts-jest/utils. https://kulshekhar.github.io/ts-jest/docs/getting-started/paths-mapping/ In this case, the prefix should be set to /src – dolgom Oct 12 '21 at 01:55
1

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"]
}
Ubaid
  • 737
  • 8
  • 18
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)

TmTron
  • 17,012
  • 10
  • 94
  • 142
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.

sputnik
  • 45
  • 4
  • 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](/help/how-to-answer). – Community Jan 05 '23 at 11:42