Reputation: 6603
I created a new React-typescript app via this command with [email protected]
and [email protected]
:
npx create-react-app my-app --template typescript
Then I decided to define the alias path as I did many times before. I created the tsconfig.paths.json
in the root of my app.
{
"compilerOptions": {
"baseUrl": "./src",
"paths": {
"components/*": ["/components/*"],
"routes/*": ["/routes/*"],
"constants/*": ["/constants/*"]
}
}
}
Then I added the extend
property to the tsconfig.json
file:
{
"extends": "./tsconfig.paths.json",
"compilerOptions": {
"target": "es5",
"lib": [
"dom",
"dom.iterable",
"esnext"
],
"allowJs": true,
"skipLibCheck": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"noFallthroughCasesInSwitch": true,
"module": "esnext",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "react-jsx"
},
"include": [
"src"
]
}
Also, I installed [email protected]
and created the config-override.js
:
const path = require('path');
module.exports = function override(config) {
config.resolve = {
...config.resolve,
alias: {
...config.alias,
'components': path.resolve(__dirname, 'src/components/*'),
'routes': path.resolve(__dirname, 'src/routes/*'),
'constants': path.resolve(__dirname, 'src/constants/*'),
}
}
return config;
}
So I reopened my IDE (VSCode) and ran npm start
. I must mention I changed scripts in the package.json
before running the start command.
{
.
.
.
"scripts": {
"start": "react-app-rewired start",
"build": "react-app-rewired build",
"test": "react-app-rewired test",
"eject": "react-app-rewired eject"
}
.
.
.
}
After running the start command, this message was displayed in a terminal, and compiling failed:
The following changes are being made to your tsconfig.json file: -compilerOptions.paths must not be set (aliased imports are not supported)
*Failed to compile.
./src/App.tsx Module not found: Can't resolve 'components' in .......*
So I started to search about this issue to resolve it. I found many approaches, that I will mention some of them below:
1. Go to your jsconfig.json
file and add the base URL to be "."
"compilerOptions": {
"baseUrl": ".",
...
Then you can directly import stuff from the src directory
import Myfile from "src/myfile.js"
Result ==> DID NOT WORK!
2. This problem is solved by an alias for rewiring. Install react-app-rewire-alias
then create config-override.js
file:
const {alias, configPaths} = require('react-app-rewire-alias')
module.exports = function override(config) {
alias(configPaths())(config)
return config
}
Result ==> DID NOT WORK!
3. Using [email protected]
package
Install craco and craco-alias npm install @craco/craco --save
and npm i -D craco-alias
Create tsconfig.paths.json
in the root directory
{
"compilerOptions": {
"baseUrl": "./src",
"paths": {
"@components/*" : ["./components/*"]
}
}
}
Extend tsconfig.paths.json
in tsconfig.json
{ "extends": "./tsconfig.paths.json", //default configs... }
Create craco.config.js
in the root directory
const CracoAlias = require("craco-alias");
module.exports = {
plugins: [
{
plugin: CracoAlias,
options: {
source: "tsconfig",
// baseUrl SHOULD be specified
// plugin does not take it from tsconfig
baseUrl: "./src",
/* tsConfigPath should point to the file where "baseUrl" and "paths"
are specified*/
tsConfigPath: "./tsconfig.paths.json"
}
}
]
};
in package.json
swap "start": "react-scripts start"
with "start": "craco start"
Result ==> DID NOT WORK!
I'm confused because I had used the alias path many times before, but it does not work now. I don't want to eject
my app but using the alias path is helpful.
Upvotes: 8
Views: 11027
Reputation: 395
Assuming your React app was created using create-react-app
and TypeScript template, I confirm the following steps working as expected with minimum configuration.
Install dependencies for configuration override
Using npm
npm install -D @craco/craco craco-alias
Using yarn
yarn add -D @craco/craco craco-alias
package.json
It should look similar to this
{
// ...
"devDependencies": {
"@craco/craco": "7.1.0",
"craco-alias": "3.0.1"
}
}
Create craco.config.js
at the root level of the project, the same level as tsconfig.json
const cracoAlias = require("craco-alias");
module.exports = {
plugins: [
{
plugin: cracoAlias,
options: {
baseUrl: ".",
source: "tsconfig",
tsConfigPath: "./tsconfig.json",
},
},
],
};
Note
The baseUrl
in the craco.config.js
should match with the baseUrl
in the tsconfig.json
Create path alias in tsconfig.json
Below is the typical tsconfig.json
auto-generated by CRA. Then, add paths
property inside compilerOptions
.
{
"compilerOptions": {
"target": "es5",
"lib": ["dom", "dom.iterable", "esnext"],
"allowJs": true,
"skipLibCheck": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"noFallthroughCasesInSwitch": true,
"module": "esnext",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "react-jsx",
"baseUrl": ".",
"paths": {
"@/*": ["src/*"]
}
},
"include": ["src"]
}
@/*: ["src/*"]
means it will replace path prefix @/
with src/
.
Assuming you have a component named MyComponent
that is exported using named export from ./src/components/my-component.tsx
, you can import the component using import alias as
import { MyComponent } from "@/components/my-component";
which will be converted into
import { MyComponent } from "./src/components/my-component";
behind the scene. You can also create new aliases by adding extra properties in the paths
object of tsconfig.json
Next, replace react-scripts
with craco
in the scripts
of package.json
{
"name": "my-app",
// ...
"scripts": {
"start": "craco start",
"build": "craco build",
"test": "craco test"
}
// ...
}
Finally, test the import alias
Using npm
npm run start
Using yarn
yarn start
Upvotes: 1
Reputation: 15630
Path alias are no longer supported.
But to avoid annoying import paths like ../../../
you can directly import files relative to the src
directory
You can do the following
go to your tsconfig.json
file add base URL to be "."
"compilerOptions": {
"baseUrl":".",
...
Then you can directly import stuff relative to the src
directory
import utility from "src/Myfile.js"
Upvotes: 4
Reputation: 104
I was able to make it work all together (typescript + eslint) in Typescript CRA created just few days ago. This is how I did it:
Selected deps from package.json
:
# react: 17.0.2
# eslint: 8.6.0
# react-scripts: 5.0.0
# eslint-import-resolver-babel-module 5.3.1
yarn add eslint-import-resolver-babel-module --dev
I don't have any
tsconfig.paths.json
// tsconfig.json
{
"compilerOptions": {
//...youCompilerOptions
"baseUrl": "src"
},
"include": ["src"]
}
Create new file or add to existing webpack.config.js
// webpack.config.js
module.exports = {
resolve: {
extensions: ["ts", "tsx", "js", "jsx"],
alias: {
components: path.resolve(__dirname, "src/components"),
},
},
};
Finally .eslintrc.json
// .eslintrc.json
{
// ...yourConfig
"settings": {
"import/resolver": {
"node": {
"paths": ["src"],
"moduleDirectory": ["node_modules", "src"],
"alias": {
"components": "./src/components"
}
}
}
},
}
Upvotes: 4