问题
I am setting a configuration to run my tests in a create-react-app + typescript app (from which I have ejected). I am using jest + enzyme. In my tsconfig.json I have set baseUrl='./src'
so I can use absolute paths when I import modules. For example this is a typical import statement in one of my files:
import LayoutFlexBoxItem from 'framework/components/ui/LayoutFlexBoxItem';
You can see that the path is absolute (from /src folder) and not relative.
This works fine when I run in debug mode ( yarn start
)
But when I run my test ( yarn test
), I get this error:
Cannot find module 'framework/components/Navigation' from 'index.tsx'
So it looks like jest is not able to resolve this absolute path although I have set it up in my tsconfig.json. This is my tsconfig.json:
{
"compilerOptions": {
"outDir": "dist",
"module": "esnext",
"target": "es5",
"lib": ["es6", "dom"],
"sourceMap": true,
"allowJs": true,
"jsx": "react",
"moduleResolution": "node",
"rootDir": "src",
"forceConsistentCasingInFileNames": true,
"noImplicitReturns": true,
"noImplicitThis": true,
"noImplicitAny": true,
"strictNullChecks": true,
"suppressImplicitAnyIndexErrors": true,
"noUnusedLocals": true,
"baseUrl": "./src"
},
"exclude": [
"node_modules",
"build",
"dist",
"config",
"scripts",
"acceptance-tests",
"webpack",
"jest",
"src/setupTests.ts"
]
}
Now I can see that there is a generated tsconfig.test.json
at the root of my project. This is the ts configuration used for test. And here is its content:
{
"extends": "./tsconfig.json",
"compilerOptions": {
"module": "commonjs"
}
}
As you can see the "module" is commonjs
here whereas in the default configuration it is esnext
. Could this be one reason?
Has any one been able to unit test his typescript project with Jest and absolute path? or is this a known bug? Since I have ejected from default configuration, are there some settings to put in my webpack configuration?
Thanks for your input and suggestion.
回答1:
I was struggling with the same problem and actually it turns out that a simple change seems to do the trick.
I just updated the moduleDirectories
field in jest.config.js
Before
moduleDirectories: ['node_modules']
After
moduleDirectories: ['node_modules', 'src']
Hope it helps,
Antoine
回答2:
Here is how I got moduleNameMapper working.
With the below config in my tsconfig:
"paths": {
"@App/*": [
"src/*"
],
"@Shared/*": [
"src/Shared/*"
]
},
Here's the moduleNameMapper:
"moduleNameMapper": {
"@App/(.*)": "<rootDir>/src/$1",
"@Shared/(.*)": "<rootDir>/src/Shared/$1"
}
回答3:
my solution was,
"jest": {
"moduleDirectories": [
"node_modules",
"src"
],
"moduleFileExtensions": [
"js",
"json",
"ts"
],
"roots": [
"src"
],
"testRegex": ".spec.ts$",
"transform": {
"^.+\\.(t|j)s$": "ts-jest"
},
"coverageDirectory": "../coverage",
"testEnvironment": "node",
"moduleNameMapper": {
"src/(.*)": "<rootDir>/src/$1"
}
}
回答4:
I've using React with Typescript, I removed react-scripts-ts test --env=jsdom
from npm test
and added jest --watch
as my default test, after I added jest.config.js
to my project following these instructions https://basarat.gitbooks.io/typescript/docs/testing/jest.html
and I used the the configuration mentioned by @Antonie Laffargue (add/edit property moduleDirectories: ['node_modules', 'src']
), it works perfectly.
回答5:
As many here pointed out moduleNameMapper
in jest.config.js
needs to define paths specified in tsconfig.json
. For example, if you have paths in tsconfig.json
defined as follows
// tsconfig.json
{
...
"baseUrl": "src",
"paths": {
"@alias/*": [ 'path/to/alias/*' ]
}
...
}
then your jest.config.js
needs to provide those paths in moduleNameMapper
in the following format:
// jest.config.js
module.exports = {
'roots': [
'<rootDir>/src'
],
'transform': {
'^.+\\.tsx?$': 'ts-jest'
},
'moduleNameMapper': {
'@alias/(.*)': '<rootDir>/src/path/to/alias/$1'
}
};
Having that we can improve our jest.config.js
to convert paths defined in tsconfig.json
automatically. Here is a Gist code snippet for that:
// jest.config.js
function makeModuleNameMapper(srcPath, tsconfigPath) {
// Get paths from tsconfig
const {paths} = require(tsconfigPath).compilerOptions;
const aliases = {};
// Iterate over paths and convert them into moduleNameMapper format
Object.keys(paths).forEach((item) => {
const key = item.replace('/*', '/(.*)');
const path = paths[item][0].replace('/*', '/$1');
aliases[key] = srcPath + '/' + path;
});
return aliases;
}
const TS_CONFIG_PATH = './tsconfig.json';
const SRC_PATH = '<rootDir>/src';
module.exports = {
'roots': [
SRC_PATH
],
'transform': {
'^.+\\.tsx?$': 'ts-jest'
},
'moduleNameMapper': makeModuleNameMapper(SRC_PATH, TS_CONFIG_PATH)
};
回答6:
I had a similar problem. I hope this could help to spare time for some of you.
My problem:
- using create-react-app with typescript
- using absolute paths (src/MyComp) to import components inside other components (e.g. App.tsx)
- it was working on compile/run/build
- it was not working on test
I found that the error was due to a different value of the NODE_PATH. So I set it on tests run.
I recreated the issue and the fix in here: https://github.com/alessandrodeste/...
I'm not sure if this could bring side effects on tests. Let me know if you have feedback ;)
回答7:
You probably want moduleNameMapper
feature of jest config.
It will map your custom import namespaces to real module locations.
see official documentation here:
https://facebook.github.io/jest/docs/en/configuration.html#modulenamemapper-object-string-string
回答8:
ts-jest can resolve this problem perfectly!
https://kulshekhar.github.io/ts-jest/user/config/#paths-mapping
just modify jest.config.js like this:
const { pathsToModuleNameMapper } = require('ts-jest/utils');
const { compilerOptions } = require('./tsconfig.json');
module.exports = {
preset: 'ts-jest',
moduleNameMapper: pathsToModuleNameMapper(compilerOptions.paths)
}
来源:https://stackoverflow.com/questions/50171412/jest-typescript-absolute-paths-baseurl-gives-error-cannot-find-module