Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Aliased imports are not supported anymore when creating a new typescript react app #12047

Open
hessaam opened this issue Feb 11, 2022 · 36 comments

Comments

@hessaam
Copy link

hessaam commented Feb 11, 2022

I created a new React-typescript app via this command with react@17.0.2 and typescript@4.5.2:

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 react-app-rewired@2.1.8 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 is 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 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 rewire. 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 craco@6.4.1 package

  1. Install craco and craco-alias npm install @craco/craco --save and npm i -D craco-alias

  2. Create tsconfig.paths.json in root directory

    {
        "compilerOptions": {
            "baseUrl": "./src",
            "paths": {
               "@components/*" : ["./components/*"]
             }
        }
    }
    
  3. Extend tsconfig.paths.json in tsconfig.json

    {
    "extends": "./tsconfig.paths.json",
    //default configs...
    }

  4. 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"
            }
         }
      ]
    };
    
  5. in package.json swap "start": "react-scripts start" with "start": "craco start"

Result ==> DID NOT WORK!

I'm confused because I 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.

This is my question in the Stackoverflow community.

@alexNerazim
Copy link

alexNerazim commented Feb 22, 2022

I have the same issue, trying to resolve the path with alias and doing the webpack config have seen in multiply sites with tsconfig-paths-webpack-plugin and still not working..

@MrHOY
Copy link

MrHOY commented Apr 22, 2022

I have the same issue.
Any solution for this ?

@Aleksey-Danchin
Copy link

It's 2022 year. React 18 released, CRA v5 released, nodejs imports option exists, but alias from box not supported =)

@yatessss
Copy link

yatessss commented Jun 1, 2022

I created a new React-typescript app via this command with react@17.0.2 and typescript@4.5.2:

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 react-app-rewired@2.1.8 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 is 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 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 rewire. 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 craco@6.4.1 package

  1. Install craco and craco-alias npm install @craco/craco --save and npm i -D craco-alias
  2. Create tsconfig.paths.json in root directory
    {
        "compilerOptions": {
            "baseUrl": "./src",
            "paths": {
               "@components/*" : ["./components/*"]
             }
        }
    }
    
  3. Extend tsconfig.paths.json in tsconfig.json
    {
    "extends": "./tsconfig.paths.json",
    //default configs...
    }
  4. 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"
            }
         }
      ]
    };
    
  5. in package.json swap "start": "react-scripts start" with "start": "craco start"

Result ==> DID NOT WORK!

I'm confused because I 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.

This is my question in the Stackoverflow community.

remove all *

In my tests, simply remove the * from the alias, whether craco, react-app-rewired, To set up the alias configuration according to webpack document https://webpack.js.org/configuration/resolve/

in Craco:

webpack: {
    ...
    alias: {
      '@src': path.resolve(__dirname, 'src'),
    },
    ...
}

in react-app-rewired

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;
}

@jonathangraf
Copy link

Using Craco could be a short-term solution, but why do they not work out of the box anymore? Weird stuff

@charleston10
Copy link

I had to add react-app-rewired and react-app-rewired-alias
and followed the same tip that our friend commented @yatessss above and worked (thank u 😄)

My files

tsconfig.paths.json
tsconfig.json
config-overrides.js

tsconfig.paths.json

{
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "routers/*": ["./src/routers/*"]
    }
  }
}

tsocnfig.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",
    "experimentalDecorators": true
  },
  "include": [
    "src"
  ],
  "extends": "./tsconfig.paths.json" <<<<< import alias paths
}

config-overrides.js

const {alias, configPaths} = require('react-app-rewire-alias')

module.exports = function override(config) {
    alias(configPaths())(config)
    return config;
}

package.json

{
...
"scripts": {
    "start": "react-app-rewired start",
    "build": "react-app-rewired build",
    "test": "react-app-rewired test",
    "eject": "react-scripts eject"
  },
...
}

@skysantoroa
Copy link

skysantoroa commented Sep 13, 2022

@charleston10
Doesn't work alias is not a function

@murashki
Copy link

Пичалька

@Arcanorum
Copy link

This is nuts...

@Eriold
Copy link

Eriold commented Dec 13, 2022

Today have any solution for React 18.2? Because when I use .babelrc and import from tsconfig.js and my error is:

Module not found: Error: Can't resolve '~alias' in '...\src'

I use CRA and Node 18.12

@rayraspberry
Copy link

I was able to get aliases working with react-app-rewired + Node 16.
Switching to Craco isn't required.

"react": "^18.2.0",
"react-app-rewired": "^2.2.1"

devDeps:

    "react-app-alias": "^2.2.2",
    "react-app-rewire-alias": "^1.1.7",
    "react-scripts": "^5.0.1",
    "typescript": "^4.4.4",
    "webpack": "5"

The thing I discovered was that the aliases functionality seems to be limited to folder paths only not file aliases unfortunately.
Aliases need to be defined in a separate tsconfig.paths.json that is included in tsconfig.json

in tsconfig.json

  "extends": "./tsconfig.paths.json"

tsconfig.paths.json

{
"compilerOptions":{
  "baseUrl":"./src",
  "paths":{
    "@assets/*":[
      "./assets/*"
    ],
    "@styles/*":[
      "./assets/styles/*"
    ]
}
}

then in the webpack override file config-overrides.js also needs matching aliases

const { aliasWebpack, aliasJest } = require('react-app-alias')
const { alias } = require('react-app-rewire-alias');

const options = {}; // default is empty for most cases

module.exports.jest = aliasJest(options)

module.exports = aliasWebpack(options)

module.exports = function override(config) {
  const fallback = config.resolve.fallback || {};
  alias({
    '@assets': 'src/assets',
    '@styles': 'src/assets/styles'
})(config);
return config;
};

I tried many other options and combinations of alias packages and this is the only way I've been able to get the alias functionality to work with CRA(rewired).

Repo with the working code is here:
https://github.com/Y-Foundry-Dao/yfd-dapp-gov

@yeezick
Copy link

yeezick commented Dec 23, 2022

Can we get some attention on this? This feels like something that should work out of the box..

@H4mxa
Copy link

H4mxa commented Dec 26, 2022

My solution

  • yarn add react-app-rewired

  • create file config-overrides.js at project root and paste

const path = require('path');

module.exports = function override(config) {
  config.resolve = {
    ...config.resolve,
    alias: { '@modules': path.resolve(__dirname, 'src/modules/') },
  };

  return config;
};
  • change package.json script -> start to "react-app-rewired start"

@danjguzman
Copy link

In 2023 I still cannot get this to work. React 18.2. TS 4.9.4.

The "@Aliases" will not work unless I intentionally break the TS config file by adding "extends: false" to the top of the tsconfig file. But I lose all TS error reporting obviously (still get some warnings).

None of the suggestions in this long thread solves this issue. Craco, Rewire, everything fails to work. I spent weeks on this issue with zero results. I used cra to create a new app as well, so there's no old code messing things up.

This needs some serious attention.

@PrinOrange
Copy link

Although the path alias is still not supported now, but the official documentation has the solution for absolute-import that import modules by tsconfig/jsconfig with options baseUrl so it allows you import components elegantly. And you can do it to finish the similar effect.

@danjguzman
Copy link

My solution

  • yarn add react-app-rewired
  • create file config-overrides.js at project root and paste
const path = require('path');

module.exports = function override(config) {
  config.resolve = {
    ...config.resolve,
    alias: { '@modules': path.resolve(__dirname, 'src/modules/') },
  };

  return config;
};
  • change package.json script -> start to "react-app-rewired start"

Not sure how I missed this, but I just tried what you posted here and it's the only thing that worked. Thanks!

@jackrdye
Copy link

jackrdye commented Feb 13, 2023

Why does this not just work... Next js allows it on create app. Just gives you the option to set up @/ as alias so much cleaner ....

I shouldn't have to mess with webpack for such a common request.

Someone in recta dev team add this!!!!

@TonyGravagno
Copy link

With the solution to use react-app-rewired, in package.json I had to change the build directive too, otherwise the override wasn't called:
"build": "react-app-rewired build",

With console.log(config) and the alias definitely pointing at the right folder, the import was still failing to recognize the alias.

This is really a shame. I'm gonna skip aliases entirely and use relative pathing until this is resolved: as noted by others, we shouldn't need to use other packages if this is supposed to be supported out of the box.

Thanks for everything we do have in this wonderful FOSS though!!

@elmcapp
Copy link

elmcapp commented Mar 7, 2023

This question can be closed. The answer how to use Aliased is in the documents.

How typescript is included in the new version of React Native.
https://reactnative.dev/docs/typescript

How to use Aliased
https://reactnative.dev/docs/typescript#using-custom-path-aliases-with-typescript

These are from the officials docs and works

NOTE: when making changes in the babel.config file you need to clear the cache before everything works

  1. In your terminal or cmd run: yarn start --reset-cache
  2. Restart the development server close all terminal windows then rebuild or run your project

@stag-enterprises
Copy link

Testing with create-react-app version 5.0.1 with craco 7.1, it seems aliases are still unsupported.
Please add this functionality! 😢

@jakubwilk
Copy link

With:

  • create-react-app ver. 5.0.1 (react ver. 18.2.0)
  • @craco/craco ver. 7.1.0

My tsconfig.json:

{
  "compilerOptions": {
    "baseUrl": "./",
    "paths": {
      "@app/pages": ["./src/app/pages/index.ts"],
      "@common": ["./src/modules/common/index.ts"]
    },
    "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"]
}

And craco.config.js:

const CracoAlias = require('craco-alias')

module.exports = {
  plugins: [
    {
      plugin: CracoAlias,
      options: {
        source: 'tsconfig',
        baseUrl: './',
        tsConfigPath: './tsconfig.json',
      },
    },
  ],
}

Import like this is working very well:

import { DialogContextProvider } from '@common'

Check your baseUrl options.

@lukenzo
Copy link

lukenzo commented May 23, 2023

2023 and we still have this issue.. Time to switch to next.js

@JE-lee
Copy link

JE-lee commented Jun 30, 2023

2023 is now ... 🤣

@lehaiquantb
Copy link

Time to switch to vite =))

@icon2341
Copy link

Any movement? Thanks!

@SightStudio
Copy link

SightStudio commented Aug 27, 2023

Why does this not just work? i spent so much time on this 😠

@MrHOY
Copy link

MrHOY commented Aug 28, 2023

Next year is coming soon ...🤣

@xxbek
Copy link

xxbek commented Dec 9, 2023

End 2023! Still not supported

@mohammadhannoun
Copy link

This should be an out of the box thing, we need it to be supported.

@Arcanorum
Copy link

Just use Vite guys, it is easy to set up, is a lot faster, and absolute imports work out of the box.

@iamcrisb
Copy link

iamcrisb commented Feb 6, 2024

it's 2024 and this is still not supported, I'm dying

@PrinOrange
Copy link

The create-react-app seems to be abandoned for maintaining.
Use the Vite to start the react project instead.

@abdulelah-tech
Copy link

My solution

  • yarn add react-app-rewired
  • create file config-overrides.js at project root and paste
const path = require('path');

module.exports = function override(config) {
  config.resolve = {
    ...config.resolve,
    alias: { '@modules': path.resolve(__dirname, 'src/modules/') },
  };

  return config;
};
  • change package.json script -> start to "react-app-rewired start"

2024 and you're the only solution that works for me, Thanks!!

@magrega
Copy link

magrega commented Oct 7, 2024

My solution

  • yarn add react-app-rewired
  • create file config-overrides.js at project root and paste
const path = require('path');

module.exports = function override(config) {
  config.resolve = {
    ...config.resolve,
    alias: { '@modules': path.resolve(__dirname, 'src/modules/') },
  };

  return config;
};
  • change package.json script -> start to "react-app-rewired start"

It works!

@amrithdas
Copy link

My solution

  • yarn add react-app-rewired
  • create file config-overrides.js at project root and paste
const path = require('path');

module.exports = function override(config) {
  config.resolve = {
    ...config.resolve,
    alias: { '@modules': path.resolve(__dirname, 'src/modules/') },
  };

  return config;
};
  • change package.json script -> start to "react-app-rewired start"

you are a lifesaver man. this worked for me.

@Maybis
Copy link

Maybis commented Nov 8, 2024

2024 is now ... 🤣

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests