Open the-mike opened 6 years ago
I fixed this problem and made pull request: https://github.com/wmonk/create-react-app-typescript/pull/223 As a temporary fix you can use diabelb-react-scripts-ts instead of react-scripts-ts.
Just run:
npm --save remove react-scripts-ts
npm --save install diabelb-react-scripts-ts
Are you using jest with this aliases?
I've tried to use it but my tests can't find modules imported using custom paths. My app is building and running - only jest have a problem.
my tsconfig.json
{
"compilerOptions": {
...
"baseUrl": ".",
"paths": {
"@app/*": ["./src/*"]
}
},
...
}
my tsconfig.test.json
{
"extends": "./tsconfig.json",
"compilerOptions": {
"module": "commonjs"
}
}
After using import like this in one component
import { connect, Dispatch } from 'react-redux';
import StoreState from '@app/types/StoreState';
import Counter from '@app/components/counter/Counter';
import * as actions from '@app/actions/';
I've got jest errors like this
FAIL src/components/home/Home.test.tsx
● Test suite failed to run
Cannot find module '@app/components/counter/Counter' from 'Counter.tsx'
at Resolver.resolveModule (node_modules/jest-resolve/build/index.js:179:17)
at Object.<anonymous> (src/containers/counter/Counter.tsx:4:17)
Hello,
Suddenly, ts-jest does not support absolute paths right know. But there is a way out. First you can check my fork with solution: https://github.com/diabelb/create-react-app-typescript-redux
If not, you need to fork create-react-app-typescript yourself or eject application. After that you have to add path info to package.json:
"jest": { "moduleNameMapper": { "^react-native$": "react-native-web", "@App/(.)": "
/src/$1", "@Reducers/(. )": "/src/store/reducers/$1", "@Store/(.)": " /src/store/$1", "@Components/(. )": "/src/components/$1" } },
and edit createJestConfig.js - find out supportedKeys array and add moduleNameMapper:
const supportedKeys = [ 'moduleNameMapper', 'collectCoverageFrom', 'coverageReporters', 'coverageThreshold', 'snapshotSerializers', ];
Suddenly, ts-jest does not support absolute paths right know.
Strictly speaking, this is not correct. The issue described above refers to module resolution, which is performed by jest
when executing the tests - ts-jest
does not have any influence on this. That's why the moduleNameMapper
entry is required for path mapping in jest
.
Unluckily, the syntax used for this mapping (regex based) differs from the one that is used in the tsconfig
(glob based). A suitable transformation would help, but is not that easy to achieve for general purpose. Otherwise, we would already have added it to the jest config creation process.
@DorianGrey is there any workaround currently for fixing the jest problems with path mappings?
Also, would it be possible to just convert all the path mappings in tsconfig.test.json
from glob to regex (using a lib such as glob-to-regexp for instance) with no extra config from the user side?
But it might be a good idea to allow the user to set moduleNameMapper
config meanwhile.
Also, would it be possible to just convert all the path mappings in tsconfig.test.json from glob to regex (using a lib such as glob-to-regexp for instance) with no extra config from the user side?
Not in a simple way.
The path mappings in the tsconfig.json
are relative to the baseUrl
, while the ones in the jest
configuration have to complete (and refer to a <rootDir
), so it would be required to rewrite them. An addtional problem is raised by the matchers in the mappings - regexp vs. glob would need a manual rewrite, either before or after the conversion. While taking care that all of these steps leave a usable expression behind. However, the worst thing to somehow deal with is that the mappings in the tsconfig
are 1:n, while the ones from jest
are 1:1 - so, at least for supporting all potential setups, it would be required to somehow "join" the potentially multiple globs, or enforce that there is exactly one.
A lot of work...
@DorianGrey I understand. Perhaps the trivial thing to do is to allow the user to specify the moduleNameMapper
config. It's not ideal, but jest and ts-jest works the same way.
It might actually be a good idea to have path mappings support without additional config in ts-jest instead.
"moduleNameMapper": {
"^@app/(.*)$": "<rootDir>/src/$1"
}
is working well, according to moduleNameMapper
in tsconfig.json i add baseUrl and path
"compilerOptions": {
"baseUrl": "./",
"paths": {
"@app/*": [
"src/*"
]
}
}
@DorianGrey @rolandjitsu thank for explanations.
Oddly, for me the same configuration as @kuzvac leads to Jest getting stuck at Determining test suites to run...
.
EDIT: Using react-scripts-ts
v2.15.1
@hassankhan I think we need to wait for https://github.com/wmonk/create-react-app-typescript/pull/303 to be merged before we can use that config? 😕
I patched the changes into my local node_modules/
to test, I'll check against the PR
@hassankhan if you have any problems with the changes in the PR let my know, so I can update it! 🙂
any updates?
https://github.com/wmonk/create-react-app-typescript/pull/303 was merged and will be included in the next CRA-ts release.
I agree with @rolandjitsu that there should be some kind of default for mapping tsconfig paths for Jest paths. I think that this would reduce the number of configuration and the confusion between jest and tsconfig path mappings.
Since module resolution is basically determined at compile time, there is little sense to support n-number of paths under tsconfig's path. The only use case I see in tsconfig's path option is to resolve modules in different locations (during development, explicitly stating how module resolution would work), but I am not sure if this is carried over to a webpack build.
Of course, being able to manually override moduleNameMapper
should still be supported, but a default 'mapper' makes a lot of sense.
I've dealt with this in my own private project with the following very crude code:
const tsconfig = require('./tsconfig.json')
const path = require('path')
/**
* Transforms tsconfig paths to Jest compatible moduleNameMapper syntax
* Only takes the first path for each key in tsconfig.compilerOptions.paths
* Takes 'baseUrl' into consideration
* @param {Object} tsconfig
*/
const transformTsPathsToJestPaths = tsconfig => {
const { paths = {}, baseUrl = '' } = tsconfig.compilerOptions
const resolvedBase = path.join('<rootDir>', baseUrl)
return Object.keys(paths).reduce(
(acc, key) =>
key === '*'
? acc
: {
...acc,
['^' + key.replace('*', '(.*)') + '$']: path.join(
resolvedBase,
paths[key][0].replace('*', '$1')
)
},
{}
)
}
With the following tsconfig.json
{
"compilerOptions": {
"baseUrl": "./src",
"paths": {
"@ModuleA/*": ["ModuleA/*"]
}
}
}
The function outputs:
{ '^@ModuleA/(.*)$': '<rootDir>/src/ModuleA/$1' }
I'm trying to implement alias for importing modules from root of my project. According to typescripts docs it can be done by adding following configuration to 'tsconfig.json' file
I get no Typescript compile error, but error from webpack i.e. Failed to compile.
./src/App.tsx Module not found: Can't resolve '~/components/forms' in '/Users/mike/dev/js/react-ts/src'
My env: macOS 12.12.3 node v. 6.10 create-react-app 1.4.3 react-scripts-ts 2.8.0
It seems to be known issue and was resolved in awesome-typescript-loader using plugin https://github.com/dividab/tsconfig-paths-webpack-plugin. For now I change my typescript config to
and added .env file with NODE_PATH=. Seems that it fixed global imports inside my project but it not very flexible.