Using @/ path mapping on Create React App projects
Marcos Dias

Marcos Dias @marcosdiasdev

About: Over(React)ing as usual.

Location:
Palmas - TO, Brazil
Joined:
Oct 20, 2018

Using @/ path mapping on Create React App projects

Publish Date: Jul 5 '23
8 2

Path Mapping in a Map

I recently configured an old project created with Create React App (CRA) to use path mapping/aliasing like @atoms, @molecules or @organisms.

After using NextJS for a while, I got used to the idea of using @/ instead of just @ as a prefix for path mapping as it makes it a little bit clearer what is a path alias and what's not, like @apollo-client or @fortawesome.

The point in this post is how to enable your project to use @/ path mapping, but you can use the same settings to be able to use any other aliases, like @utils or just utils.

Configuring the path mapping

Considering you're using CRA, the first thing is to install @craco/craco in your project to enable overriding original CRA's configuration.

To install @craco/craco, just run:



yarn add -D @craco/craco


Enter fullscreen mode Exit fullscreen mode

or



npm i -D @craco/craco


Enter fullscreen mode Exit fullscreen mode

After installing @craco/craco, in your package.json, update your start, build and test scripts to use craco instead of react-scripts, like recommended in CRACO's docs.

And then create a craco.config.js file in your project's root adding your aliases to the alias property of the webpack property, where the key should be the alias's name and the value its path:



const path = require('path');

module.exports = {
  webpack: {
    alias: {
      '@atoms': path.resolve(__dirname, './src/atoms'),
      '@molecules': path.resolve(__dirname, './src/molecules'),
    },
  },
};


Enter fullscreen mode Exit fullscreen mode

If you're using TypeScript, you should add those same path aliases to your tsconfig file. In your tsconfig file, look for compilerOptions and add a paths object like the following:



{
  "compilerOptions": {
    "paths": {
      "@atoms/*": [
        "./src/atoms/*"
      ],
      "@molecules/*": [
        "./src/molecules/*"
      ],
    }
  }
}


Enter fullscreen mode Exit fullscreen mode

At this point, you should be able to import your components using the aliases you just defined:



import Button from '@atoms/Button'; 
import Table from '@molecules/Table'


Enter fullscreen mode Exit fullscreen mode

Remember @atoms and @molecules are just examples. You can use any other aliases.

Allowing @/ path aliases

If you prefer to use @/ instead of @ as the alias prefix, you might face some trouble with ESLint as it might be complaining about missing file extensions on your imports:



Missing file extension for "@/pages/MainPage" eslint(import/extensions)


Enter fullscreen mode Exit fullscreen mode

To allow ESLint to understand @/ aliases, you'll have to install the eslint-import-resolver-typescript plugin.

Run



yarn add -D eslint-import-resolver-typescript


Enter fullscreen mode Exit fullscreen mode

or



npm i -D eslint-import-resolver-typescript


Enter fullscreen mode Exit fullscreen mode

Then, go to your .eslintrc file and add the following configuration within the settings section:



  "settings": {
    "import/resolver": {
      "typescript": {}
    }
  }


Enter fullscreen mode Exit fullscreen mode

Now ESLint should've stopped complaining about missing file extensions. If you're still getting a warning about extensions, check your import/extensions rule inside the rules section. You can read more about this rule here.

🎁 Bonus round: enabling Jest to use path aliases

Again, considering you're using TypeScript, to allow Jest to read your path aliases you'll have to install and configure ts-jest.

Run



yarn add -D ts-jest


Enter fullscreen mode Exit fullscreen mode

or



npm i -D ts-jest


Enter fullscreen mode Exit fullscreen mode

After installing ts-jest, update your craco.config.js file like the following, telling Jest to use the paths configured in your tsconfig file:



const path = require('path');
const { pathsToModuleNameMapper } = require('ts-jest');
const { compilerOptions } = require('./tsconfig.json');

module.exports = {
  webpack: {
    alias: {
      '@atoms': path.resolve(__dirname, './src/atoms'),
      '@molecules': path.resolve(__dirname, './src/molecules'),
    },
  },
  jest: {
    configure: {
      preset: 'ts-jest',
      moduleNameMapper: pathsToModuleNameMapper(compilerOptions.paths, {
        prefix: '<rootDir>/',
      }),
    },
  },
};


Enter fullscreen mode Exit fullscreen mode

That's it! You now should be able to use path mapping in your project, including your unit tests and also using @/ path aliases.

Comments 2 total

  • kiswayODG
    kiswayODGMay 28, 2024

    After reading several tutorials, it's your which helped me to solve my problem.

    I saw in a tutorial where he used one line in craco.config.js like this
    '@' : path.resolve(__dirname,'src'),

    Is it possible?!
    I couldn't make it work.

    • Marcos Dias
      Marcos DiasMay 28, 2024

      Hey, @kiswayodg . I guess you can use something like the following in your tsconfig:

      {
        "compilerOptions": {
          "paths": {
            "@/*": [
              "./src/*"
            ]
          }
        }
      }
      
      Enter fullscreen mode Exit fullscreen mode

      And the following in your craco.config:

      module.exports = {
        webpack: {
          alias: {
            '@': path.resolve(__dirname, './src')
          },
        },
      };
      
      Enter fullscreen mode Exit fullscreen mode

      I'm not able to test it right now, but tell me if this works for you.

      Glad to help!

Add comment