Reputation: 13923
I'm trying to map paths in tsconfig.json to get rid of relative paths hell. My React App is based on Create-React-App. I tried this SO thread and added paths in my tsconfig.json. My tsconfig.json is as
{
"compilerOptions": {
"baseUrl": "src",
"target": "es5",
"lib": [
"dom",
"dom.iterable",
"esnext"
],
"allowJs": true,
"skipLibCheck": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"module": "esnext",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "react",
"strictNullChecks": false
},
"include": [
"src"
]
}
when I compile my project in VS Code, it removes the paths entry from tsconfig.json with the following message. Why alias imports are not supported in my react-scripts based React Project?
Upvotes: 23
Views: 36758
Reputation: 7661
In the end, i figured out this is not the issue of tsconfig
. Instead different build system reads this file and operate a bit differently. For instance, a NextJS build does most of the stuff according to the doc, but a Create React App build actually does not follow this exactly. For instance, I can only make the following work.
import Avatar from 'src/components/Avatar'
{
"compilerOptions": {
"baseUrl": ".",
But nothing else with react-scripts
. I hope this helps a bit in this crazy world.
Upvotes: 4
Reputation: 848
You don't need craco
for fixing the problem like that anymore. I've solved this issue by moving the baseUrl
to the main tsconfig.json
file like below:
tsconfig:
{
"extends": "./tsconfig.paths.json",
"compilerOptions": {
"baseUrl": "./src",
"target": "es5",
"lib": ["dom", "dom.iterable", "esnext"],
"allowJs": true,
"experimentalDecorators": true,
"skipLibCheck": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"strict": false,
"noImplicitAny": false,
"forceConsistentCasingInFileNames": true,
"module": "esnext",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "react"
},
"include": ["src"]
}
tsconfig.path.json:
{
"compilerOptions": {
"paths": {
"api/*": ["api/*"],
"assets/*": ["assets/*"],
"config/*": ["config/*"],
"components/*": ["components/*"],
"hooks/*": ["hooks/*"],
"pages/*": ["pages/*"],
"store/*": ["store/*"],
"constant/*": ["constant/*"],
"types/*": ["types/*"],
"utils/*": ["utils/*"]
}
}
}
Upvotes: 3
Reputation: 1825
I made to Angelo P's answer work by changing the config-overrides.js
to
const path = require('path');
module.exports = function override(config, env) {
config.resolve = {
...config.resolve,
alias: {
...config.resolve.alias,
"@src": path.resolve(__dirname, 'src/'),
"@api": path.resolve(__dirname, "src/API/"),
"@assets": path.resolve(__dirname, "src/assets/"),
"@components": path.resolve(__dirname, "src/components/"),
"@containers": path.resolve(__dirname, "src/containers/"),
"@css": path.resolve(__dirname, "src/css/"),
"@customHooks": path.resolve(__dirname, "src/CustomHooks/"),
"@helperFuncs": path.resolve(__dirname, "src/HelperFuncs/"),
"@hoc": path.resolve(__dirname, "src/hoc/"),
"@middlewares": path.resolve(__dirname, "src/middlewares/"),
"@models": path.resolve(__dirname, "src/models/"),
"@store": path.resolve(__dirname, "src/store/"),
"@actions": path.resolve(__dirname, "src/store/actions"),
"@reducers": path.resolve(__dirname, "src/store/reducers/"),
"@sagas": path.resolve(__dirname, "src/store/sagas/"),
"@typings": path.resolve(__dirname, "src/Typings/"),
"@utils": path.resolve(__dirname, "src/utils/")
},
extensions: ['.ts', '.tsx', '.js', '.jsx', '.json', '.d.ts']
};
return config;
};
Works like a charm, but the only thing missing is VSCode autocompletion. React starts up with this warning:
The following changes are being made to your tsconfig.json file:
- compilerOptions.paths must not be set (aliased imports are not supported)
So I'm assuming it removes the path
field from the tsconfig.json and VSCode cannot pick up the aliases, so ESLint
and TS
give the following errors in VSCode, but everything works fine.
Unable to resolve path to module '@typings/...'.eslintimport/no-unresolved
Cannot find module '@typings/...' or its corresponding type declarations.ts(2307)
Anyone has a solution for this?
UPDATE
Managed to get it all working by making these changes:
tsconfig.paths.json
{
"compilerOptions": {
"paths": {
"@src/*": ["./src/*"],
"@api/*": ["./src/API/*"],
"@assets/*": ["./src/assets/*"],
"@components/*": ["./src/components/*"],
"@containers/*": ["./src/containers/*"],
"@css/*": ["./src/css/*"],
"@customHooks/*": ["./src/CustomHooks/*"],
"@helperFuncs/*": ["./src/HelperFuncs/*"],
"@hoc/*": ["./src/hoc/*"],
"@middlewares/*": ["./src/middlewares/*"],
"@models/*": ["./src/models/*"],
"@store/*": ["./src/store/*"],
"@actions/*": ["./src/store/actions*"],
"@reducers/*": ["./src/store/reducers/*"],
"@sagas/*": ["./src/store/sagas/*"],
"@typings/*": ["./src/Typings/*"],
"@utils/*": ["./src/utils/*"]
}
}
}
Note the *
at the end of @.../*
tsconfig.json
{
"extends": "./tsconfig.paths.json",
"compilerOptions": {
"target": "es6",
"lib": [
"dom",
"dom.iterable",
"esnext",
"es2015.promise"
],
"allowJs": true,
"skipLibCheck": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"noFallthroughCasesInSwitch": true,
"module": "esnext",
"moduleResolution": "node",
"isolatedModules": true,
"noEmit": true,
"jsx": "react-jsx",
"plugins": [
{
"name": "typescript-plugin-css-modules"
}
],
"resolveJsonModule": true,
"baseUrl": ".",
},
"include": [
"src",
"src/**/*.ts"
]
}
npm i -D eslint-plugin-import @typescript-eslint/parser eslint-import-resolver-typescript
.eslintrc.json
{
...,
"settings": {
"import/resolver": {
"node": {
"extensions": [".js", ".jsx", ".ts", ".tsx", ".d.ts"]
},
"typescript": {}
}
}
}
Upvotes: 6
Reputation: 15630
Path aliases are no longer supported
you can do this now, to directly import files relative to the src
directory
go to your jsconfig.json
file add base URL to be "."
"compilerOptions": {
"baseUrl":".",
...
then you can directly import stuff from the src
directory
import Myfile from "src/myfile.js"
Upvotes: 12
Reputation: 49
you've probably already figured this one out but here's a solution while we wait for a pull request that adds this to tsconfig Currently having the same issue with create-react-app react v 17.0.2,
I've had a similar issue with gatsby applications where you're not able to just set up alias imports without changing the web pack config
this thread has a good explanation on alias imports within cra without typescript, but it should lead to the same configuration at the end of the day.
you'd have to either eject(don't do this unless you have other issues you need to solve inside of your webpack config.) or use another package like CRACO or React-App-Rewired to configure your aliases through webpack.
This Stackoverflow answer is most likely what you're looking for.
install react-app-rewired then create config-overrides.js and place this code in there ->
//config-overrides.js
const { alias, configPaths } = require('react-app-rewire-alias');
module.exports = function override(config) {
return alias(configPaths('./tsconfig.paths.json'))(config);
};
create your paths object inside of tsconfig.paths.json
//tsconfig.paths.json
{
"compilerOptions": {
"baseUrl": "./src",
"paths": {
"@components": ["components"],
"@styles": ["styles"],
"@config": ["config"]
}
}
}
then extend these options inside of tsconfig (not inside compilerOptions)
//tsconfig.js
"extends": "./tsconfig.paths.json"
finally, replace each react-scripts script in your package.json with react-app-rewired
//package.json
"scripts": {
"start": "react-app-rewired start",
"build": "react-app-rewired build",
"test": "react-app-rewired test",
"eject": "react-app-rewired eject"
},
You should be all set to go after this. Hoping this helps anyone else who runs into this problem with create-react-app.
Upvotes: 4
Reputation: 125
You have to add "baseUrl": ".",
to you compiler options and than you can use the import src/your/path
directly.
Upvotes: 3