DEV Community

Marcos Dias
Marcos Dias

Posted on • Edited on

4 1

Using @/ path mapping on Create React App projects

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.

Image of Timescale

🚀 pgai Vectorizer: SQLAlchemy and LiteLLM Make Vector Search Simple

We built pgai Vectorizer to simplify embedding management for AI applications—without needing a separate database or complex infrastructure. Since launch, developers have created over 3,000 vectorizers on Timescale Cloud, with many more self-hosted.

Read more →

Top comments (2)

Collapse
 
kiswayodg profile image
kiswayODG

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.

Collapse
 
marcosdiasdev profile image
Marcos Dias

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!

Billboard image

The Next Generation Developer Platform

Coherence is the first Platform-as-a-Service you can control. Unlike "black-box" platforms that are opinionated about the infra you can deploy, Coherence is powered by CNC, the open-source IaC framework, which offers limitless customization.

Learn more