DEV Community

Marcos Dias
Marcos Dias

Posted on • Updated on

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.

Top comments (0)