DEV Community

Cover image for Configuring absolute paths in React for Web without ejecting [en-US]
Bruno A.
Bruno A.

Posted on • Updated on

Configuring absolute paths in React for Web without ejecting [en-US]

After you've done an article showing how to set up absolute paths in React Native, now I've been showing you how to do this in React for Web.

While the React team does not implement this in the CRA, we'll set up with our own hands and without ejecting. Keep reading and you will see the magic happening.

A small introduction β˜•

Why not eject the project?

Well, the reason for that is you're breaking CRA's β€œguarantees”. But calm, I've seen several projects that have been ejected and they are still working perfectly in production, the only problem is to eject, the settings will be mine and I have to support them.

"Stuff can break" - Dan Abramov

But fortunately, using tools like craco, we can easily go back to the CRA default settings if things go wrong. And this is incredible!

Since we will only touch alias, you do not have much to worry about, the craco will inject the new settings we make in the craco.config.js file within the CRA default settings.

In case you do not know, the intention to configure absolute paths in a project made with Reactjs, is to facilitate the import of files. For this we can use a symbol to represent a root directory of our codes. See an example below:


Use this 😍
import Form from '@/components/Form'

E Avoid this 😀
import Form from '../../../../../components/Form'

Enter fullscreen mode Exit fullscreen mode

They say that it is practicing that you learne 🏊

☝ So come on, open your terminal and install the necessary dependencies:

# yarn
yarn add @craco/craco

# npm
npm i @craco/craco
Enter fullscreen mode Exit fullscreen mode

✌ After performing the craco installation, we will need to rename some package.json command lines.

Replace the "react-scripts" with "craco".

{
  "scripts": {
  "start": "craco start",
  "build": "craco build",
  "test": "craco test",
}

Enter fullscreen mode Exit fullscreen mode

This will cause the CRA scripts to be executed by craco which will make injections of the settings that will be in the craco.config.js file.

πŸ›  Create the file in the project root directory called: craco.config.js and add the following settings:

const path = require('path');

module.exports = {
  webpack: {
    alias: {
      '@': path.resolve(__dirname, 'src/')
    }
  },
  jest: {
    configure: {
      moduleNameMapper: {
        '^@(.*)$': '<rootDir>/src$1'
      }
    }
  }
};
Enter fullscreen mode Exit fullscreen mode

A pinch of VueJS, please! 🍲

I'm using alias "@" copying as Vuejs uses. You can use alias that you find interesting, such as "~" or "#", for example.

My VSCode is not understanding anything 😒

When doing this we will come across the first problem, the autocomplete. We are already accustomed to having autocomplete when we are going to import the files using relative paths.

This error happens because VSCode does not understand that the "@" is the "src" folder of our project. To enable autocomplete we will need to configure the VSCode so that it understands. And for this we need to create a file called jsconfig.json in the project root directory.

Learn more about jsconfig.json.

Include the following properties within the file:

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

Amazing!

Now it works perfectly, use the command: npm start to run your project.

A tool that likes to complain all the time! 😑

If you are using eslint, you will notice that it will complain on all imports that you perform using "@".

Thank God, there is a way to calm eslint using eslint-import-alias.

☝ First add the libraries below as development dependencies, for God's sake! 😰

# yarn
yarn add eslint-plugin-import eslint-import-resolver-alias -D

# npm
npm i eslint-plugin-import eslint-import-resolver-alias -D

Enter fullscreen mode Exit fullscreen mode

✌ In your .eslintrc.json file include the following properties:

  "settings": {
    "import/resolver": {
      "alias": {
        "map": [["@", "./src"]]
      }
    }
  }

Enter fullscreen mode Exit fullscreen mode

Questions that look stupid but are not πŸ˜³πŸ’¬

Can I use this technique in projects that go to production?

Answer: Yes, you can use it without any problem!

Can I use it in React Native?

Answer: No, the setting in React Native is different, I show you how to do this article:
Configuring Absolute Paths in React Native.

Can my test files fail?

Answer: If you have followed step by step correctly, it probably will not give you an error. If you have changed the symbol that you are going to use as alias, make sure you have also placed this in the jest configuration there in the craco.config.js file in the moduleNameMapper property.

Why are not you using the Babel plugin root import?

Answer: Unlike the Babel plugin root import, we only import a library that solves the problem, as well as being simple to use. Another thing that has been bothering me is that it is not supporting CRA 3.0, so the use of Craco.

Imagine if everything in life worked perfectly πŸ¦„

Like any lib, you may find bugs in @craco, if found please open a issue in the official project for the community to improve the library and make it functional for everyone.

But cool, use it fearlessly for this tutorial.

It's time to say goodbye 😩

I'm really enjoying spending this time with you. If you want to know what I'm up to, follow me on Github bybruno.

Help your developer friends to stop suffering with relative imports by sharing this article!

A big hug and until next time!

Top comments (2)

Collapse
 
zarabotaet profile image
Dima • Edited

In cra 3 this stuff out of the box.
facebook.github.io/create-react-ap...
In cra 2 you can use env variable.

Collapse
 
averyfreeman profile image
Avery Freeman

Now instead of NODE_PATH=src in .env, React and NextJS are using jsconfig.json - just place this in the project root:

{
"compilerOptions": {
"baseUrl": "src"
},
"include": ["src"]
}

Reference: create-react-app.dev/docs/importin...