Search code examples
reactjswebpackcreate-react-appreact-typescript

How to make a path alias in CRA TypeScript in 2022?


I just initiated CRA npx create-react-app my-app --template typescript and I want to make an alias when calling components, like:

import components from '@components'

where the components is located at src/components.

I've tried to config in tsconfig.json by adding:

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

Also in webpack.config.js by adding:

// const TsconfigPathsPlugin = require('tsconfig-paths-webpack-plugin')
const path = require('path')

module.exports = {
  resolve: {
    // plugins: [new TsconfigPathsPlugin()],
    alias: {
      '@utils': path.resolve(__dirname, './src/utils/'),
      '@utils/*': path.resolve(__dirname, './src/utils/*')
    }
  }
}

But it's still doesn't work.

Anyone could help me to solving these problem? But, I don't wont to use other libraries like @craco/craco.


Solution

  • The issue is that CRA uses its own Webpack config under the hood. Simply making a new webpack.config file doesn't actually point CRA to it, unless you run npm run eject.

    Doing so is irreversible, but will add the config files to your project. From there, you should be able to modify your build settings to fit your needs.

    Reminder that this cannot be undone in your project, barring perhaps a git reset, and may be more than you bargained for.

    This issue with aliases seems to be a known one. Something people deemed possible earlier seems to no longer be working, or supported. Some people are speculating this could have something to do with the recent update of Webpack to version 5. And while some people claim that craco doesn't work for them, I was able to get it to work in a brand new CRA app with minimal changes. I know you're not interested in that so I won't post it here.

    Alternatively, CRA allows the use of absolute imports via the src baseUrl. This will point both VSCode and Webpack to your final files, but you won't be able to set up custom paths.

    "baseUrl" : "."
    

    Using multiple index.ts files and exporting nested code up to the highest level in the directory, I'm able to keep the import paths as short as an alias:

    import { persistor, store } from "src/state-management";
    

    This could be good enough for you. If not, consider adding a package to override some of CRA's Webpack settings, or ejecting and taking matters into your own hands.