Hi there, I'm getting an error when trying to load a module from a mapped path. The error is as follows:
Cannot find module '@app/constants/actionTypes' from 'index.ts'
at Resolver.resolveModule (node_modules/jest-resolve/build/index.js:151:17)
at Object.<anonymous> (src/actions/auth/index.ts:3:69)
at Object.<anonymous> (src/actions/auth/spec.ts:4:15)
And I'm trying to do the following:
import * as actionTypes from "@app/constants/actionTypes";
The file definitely exists and worked with relative paths.
Here's my tsconfig.json:
{
"compilerOptions": {
"outDir": "./dist/",
"sourceMap": true,
"noImplicitAny": true,
"module": "commonjs",
"target": "es5",
"jsx": "react",
"baseUrl": ".",
"paths": {
"@app/*": [ "./src/*" ]
}
},
"filesGlob": [
"src/**/*.ts",
"src/**/*.tsx",
"src/*.ts",
"src/*.tsx"
],
"exclude": [
"node_modules"
]
}
And here's the jest configuration of package.json;
"jest": {
"moduleFileExtensions": [
"ts",
"tsx",
"js"
],
"transform": {
".(ts|tsx)": "<rootDir>/node_modules/ts-jest/preprocessor.js"
},
"testResultsProcessor": "<rootDir>/node_modules/ts-jest/coverageprocessor.js",
"testRegex": "(/test/.*|(test|spec))\\.(ts|tsx)$",
"collectCoverage": true,
"collectCoverageFrom": [
"src/**/*.{ts,tsx}"
],
"moduleDirectories": [
"node_modules",
"src"
]
}
As you can see, I'm including the moduleDirectories, as suggested.
What's weirder still, is that I can still reference other modules through that path, and the following runs without error:
import { RequestLogin, ResponseError, ResponseAuth } from "@app/models/api";
Compiling directly with tsc and with the --traceResolution flag it seems to resolve without issue:
======== Resolving module '@app/constants/actionTypes' from '/var/www/front-end/src/actions/auth/index.ts'. ========
'baseUrl' option is set to '/var/www/front-end', using this value to resolve non-relative module name '@app/constants/actionTypes'
'paths' option is specified, looking for a pattern to match module name '@app/constants/actionTypes'.
Module name '@app/constants/actionTypes', matched pattern '@app/*'.
Trying substitution './src/*', candidate module location: './src/constants/actionTypes'.
Loading module as file / folder, candidate module location '/var/www/front-end/src/constants/actionTypes'.
File '/var/www/front-end/src/constants/actionTypes.ts' exist - use it as a name resolution result.
Resolving real path for '/var/www/front-end/src/constants/actionTypes.ts', result '/var/www/front-end/src/constants/actionTypes.ts'
======== Module name '@app/constants/actionTypes' was successfully resolved to '/var/www/front-end/src/constants/actionTypes.ts'. ========
It's baffling me as I can't work out why it would affect one module, but not the other.
Thanks for your help.
can you create a minimal repo that reproduces this issue?
Thanks for the speedy response @kulshekhar. Yes, I can recreate this with a minimal repo. You can find it here: https://github.com/archy-bold/ts-jest-test
There's a branch, passing, which uses relative paths and works.
this is a weird one. It's not throwing any error if I import import * as apis from "@app/constants/api";
Yeah, I considered it might be related to the type of import, but it didn't make a difference if I wrote the import as:
import { LOGIN_REQUEST } from "@app/constants/actionTypes";
I get the issue now. The other imports aren't a problem because they're just importing interfaces which are ignored at runtime. However, that's not the case for actionTypes
What's happening is that jest is unable to resolve mapped imports. This is why tsc seems to work fine but not the test.
I'm not sure where this issue belongs. Do you know what the expected behavior of the Typescript compiler is when it transpiles a mapped path? Does it leave the path as is or does it transform it to one that can be understood by node?
@archy-bold add the following to the jest section in your package.json
"moduleNameMapper": {
"@app/(.*)": "<rootDir>/src/$1"
}
This should solve the issue
Oh wow, great job!
I can't speak with any authority on the TypeScript compiler, unfortunately, so not sure how it deals with those paths. But this works perfectly now. Might be worth putting in the readme though.
that's actually a jest thing so I'm not sure this repo is the best place to highlight that (Mapped paths are often also used with webpack). Jest has some examples that use this - https://facebook.github.io/jest/docs/tutorial-webpack.html
Yeah, I spotted that, but they only talk about it to be used for mocked assets rather than mapping paths. Odd. https://facebook.github.io/jest/docs/configuration.html#modulenamemapper-object-string-string
Massive thanks for your help, though.
Hi, by setting the src folder in moduleDirectories just worked fine for me.

moduleNameMapper
won't work with paths: "*": ["*"]
it can only accept a string:
"@app/(.*)": "
this case needs
"(.*)": ["
Most helpful comment
@archy-bold add the following to the
jestsection in yourpackage.jsonThis should solve the issue