ts-jest: moduleNameMapper doesn't work for me

I change the path configuration in my tsconfig, for better paths. But now i cannot execute my testcases. So i checked the following documentaries:

Is that an error or a misconfiguration? By Error i will do a small repo.

Snippet tsconfig.json

...
        "rootDirs": [
          "src/",
          "test/"
        ],
        "baseUrl": ".",
        "paths": {
          "log": ["src/util/log"],
          "server": ["src/server"],
          "util/*": ["src/util/*"],
          "api/*": ["src/api/*"],
          "middleware/*": ["src/middleware/*"],
          "service/*": ["src/service/*"],
          "types/*": ["src/types/*"],
          "test/*": ["test/*"],
          "mocks/*": ["test/mocks/*"],
          "src/*": ["src/*"]
        },

Snippet package.json

...
    "globals": {
      "ts-jest": {
        "tsConfigFile": "tsconfig.json"
      }
...
    "moduleDirectories": [
      ".",
      "node_modules"
    ],
    "moduleNameMapper": {
      "log": "<rootDir>/src/util/log",
      "server": "<rootDir>/src/server",
      "util/(.*)": "<rootDir>/src/util/$1",
      "api/(.*)": "<rootDir>/src/api/$1",
      "middleware/(.*)": "<rootDir>/src/middleware/$1",
      "service/(.*)": "<rootDir>/src/service/$1",
      "types/(.*)": "<rootDir>/src/types/$1",
      "test/(.*)": "<rootDir>/test/$1",
      "mocks/(.*)": "<rootDir>/test/mocks/$1",
      "src/(.*)": "<rootDir>/src/$1"
    }
...

ERROR

● Test suite failed to run

   Configuration error:

   Could not locate module ../util/params (mapped as C:\Users\XXX\backend\src\util\params)

   Please check:

   "moduleNameMapper": {
     "/util\/(.*)/": "C:\Users\XXX\backend\src\util\$1"
   },
   "resolver": undefined

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Comments: 30 (2 by maintainers)

Commits related to this issue

Most upvoted comments

I almost gave up on this but finally fixed it.

// tsconfig.json
{
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "@environment": ["src/environment"],
      "@test-utils/*": ["src/test-utils/*"]
    },
}

The key below was that moduleDirectories was not required to get it to work but modulePaths is. Also a piece of advice is to use <rootDir> instead of ./.

// jest.config.js
const { pathsToModuleNameMapper } = require('ts-jest/utils')
const { compilerOptions } = require('./tsconfig')

module.exports = {
  roots: ['<rootDir>'],
  modulePaths: ['<rootDir>'],
  moduleNameMapper: pathsToModuleNameMapper(compilerOptions.paths),
}

Changing the moduleDirectories key in the jest configuration got this working (I tested with jest --no-cache from the root directory)

    "moduleDirectories": [
      ".",
      "src",
      "src/util",
      "node_modules"
    ]

Hope this helps

This should not have been closed. There is an opportunity to automate this so that developer does not have to touch jest.config.

If you’re using a different baseUrl in your tsconfig.json, you should set modulePaths to that baseUrl.

// tsconfig.json
{
  "compilerOptions": {
      "baseUrl": "./src",
      "paths": {
        ...
      }
  }
}
// jest.config.js
const { pathsToModuleNameMapper } = require('ts-jest/utils')
const { compilerOptions } = require('./tsconfig')

module.exports = {
  roots: ['<rootDir>'],
  modulePaths: [compilerOptions.baseUrl], // <-- This will be set to './src'
  moduleNameMapper: pathsToModuleNameMapper(compilerOptions.paths),
}

I have this problem that should be related to this issue. When I call a module “util” that links to src/util folder, it doesn’t work.

  moduleNameMapper: {
    '^util(.*)$': '<rootDir>/src/util$1'
  }

And throws:

    Configuration error:

    Could not locate module util mapped as:
    C:\Users\itsme\Desktop\projecX\src\util.

    Please check your configuration for these entries:
    {
      "moduleNameMapper": {
        "/^util(.*)$/": "C:\Users\itsme\Desktop\projecX\src\util$1"
      },
      "resolver": null
    }

      at createNoMappedModuleFoundError (node_modules/jest-resolve/build/index.js:472:17)
      at Object.<anonymous> (node_modules/micromatch/index.js:7:12)

But when I rename the folder and the module to “utils”, in plural… It works.

  moduleNameMapper: {
    '^utils(.*)$': '<rootDir>/src/utils$1'
  }

🤷‍♂️🙄

yup @DmitryEfimenko that is what I meant by being an opt-in.

Example of where you would not want it:

// tsconfig.json:
"paths": {
  "app": ["./src/app"],
  "common/*": ["../src/common/*"],
  "quasar": ["./node_modules/quasar-framework/dist/quasar.mat.esm.js"]
}

// jest.config.js:
moduleNameMapper: {
  '^app$': '<rootDir>/src/app',
}

And that is not the only project I work on where both don’t match 😉

But yeah, having an option for it is a good idea. It could be a helper so that people can customize it:

// jest.config.js
const { pathsToModuleNameMapper } = require('ts-jest')
const { compilerOptions: { paths: tsconfigPaths } } = require('./tsconfig')

module.exports = {
  // ...
  moduleNameMapper: {
    ...pathsToModuleNameMapper(
      tsconfigPaths, // picking/omitting could happen here
      // options could be given here
    ),
    'someOtherMapping/(.*)': 'path/to/somewhere/else/$1',
  }
}

path mapping works depending on your rootDir, see https://github.com/kulshekhar/ts-jest/blob/master/TROUBLESHOOTING.md

I’m struggling with this as well. I’m using an nrwl/nx workspace, the paths in tsconfig.app allow the app to run fine, I put the module name mappings in jest.config, nothing. I’ve tried using the jest utils that do the path to module mappings from tsconfig.app prefixed with rootDir, explicitly putting the entries (so not pulling them in from tsconfig.app), and a hundred other things. Nothing works. You run the tests and any module mapped to a path is not found. The one and only solution I have that works is just to remove the paths and start typing ‘…/…/…/…’ everywhere (which would be dozens of imports).

I have a new problem

my tsconfig.json is configured with

    "baseUrl": "./",
    "paths": {
      "*": ["./src/*"]
    },

when I use in Jest.config.ts

import type { Config } from 'jest';
import { pathsToModuleNameMapper } from 'ts-jest';
import { compilerOptions } from './tsconfig.json';

const config: Config = {
  // Resto das configurações...

moduleNameMapper: pathsToModuleNameMapper(compilerOptions.paths, { prefix: '<rootDir>/' }),
};

export default config;

raises a exception:

Configuration error:
    
    Could not locate module  mapped as:
    /Users/jonathanccalixto/Workspace/github/jonathanccalixto/maallaqa-monorepo/backend/src/$1.
    
    Please check your configuration for these entries:
    {
      "moduleNameMapper": {
        "/^(.*)$/": "/Users/jonathanccalixto/Workspace/github/jonathanccalixto/maallaqa-monorepo/backend/src/$1"
      },
      "resolver": undefined
    }

how do I resolve this?

My dependencies:

"dependencies": {
    "fastify": "^4.13.0",
    "reflect-metadata": "^0.1.13",
    "semaphore-async-await": "^1.5.1",
    "tsyringe": "^4.7.0",
    "uuid": "^9.0.0"
  },
  "devDependencies": {
    "@types/jest": "^29.5.2",
    "@types/node": "^20.4.1",
    "@types/uuid": "^9.0.1",
    "@yanotec/eslint-config-node": "^1.0.7",
    "eslint": "^8.35.0",
    "eslint-plugin-prettier": "^5.0.0-alpha.1",
    "jest": "^29.6.1",
    "ts-jest": "^29.1.1",
    "ts-node": "^10.9.1",
    "tsx": "^3.12.3",
    "typescript": "^5.1.6"
  }

Wish this was automated 🙈 🤦 @DarkLite1 Your solution works like a charm, many thanks!

i hope u can understand the problem and reproduce the issue or the misconfig

repo

Thanks for ur help

Hi there!

I’m experiencing the warning Mapping only to first target of "*" because it has more than one (2) when I use pathsToModuleNameMapper

Having multiple path mapping for a pattern is supported by typescript (see https://www.typescriptlang.org/docs/handbook/module-resolution.html#path-mapping). Is there a reason we can’t do that here?

Anyone test this on windows? I can’t seem to get this to work for windows.

I’d think it’s a rare case when you would not want it. What if it was behind an option?

{
  "jest": {
    "globals": {
      "ts-jest": {
        "autoMapModuleNames": true
      }
    }
  }
}