101

I've been using create-react-app package for creating a react website. I was using relative paths throughout my app for importing components, resources, redux etc. eg, import action from '../../../redux/action

I have tried using module-alis npm package but with no success. Is there any plugin that I can use to import based on the folder name or alias i.e. an absolute path?

Eg., import action from '@redux/action' or import action from '@resource/css/style.css'

Ben Smith
  • 19,589
  • 6
  • 65
  • 93
Prem
  • 1,447
  • 2
  • 10
  • 21
  • 1
    Two years on, CRA now has a new approach to configuring absolute imports. See the answer [here](https://stackoverflow.com/a/59195974/203371). – Ben Smith Dec 05 '19 at 13:28

9 Answers9

121

Create a file called .env in the project root and write there:

NODE_PATH=src

Then restart the development server. You should be able to import anything inside src without relative paths.

Note I would not recommend calling your folder src/redux because now it is confusing whether redux import refers to your app or the library. Instead you can call your folder src/app and import things from app/....

We intentionally don't support custom syntax like @redux because it's not compatible with Node resolution algorithm.

Dan Abramov
  • 264,556
  • 84
  • 409
  • 511
  • Can I do this in react-create-app? I tried, but it seem not to work, although guy from here https://medium.com/@ktruong008/absolute-imports-with-create-react-app-4338fbca7e3d suggest the same – yerassyl Sep 07 '17 at 17:15
  • @Mehari what's your version of create-react-app and react-scripts? – qwang07 Nov 30 '17 at 18:45
  • @qwang create-react-app-1.4.3 & react-scripts-1.0.14 – mehari Dec 01 '17 at 09:11
  • More details about implementation can be found here - https://youtu.be/xHiCRpfZIO8 – Prem Mar 21 '18 at 18:58
  • 1
    This works for us locally but not when we're building in Jenkins (we have a React-app within a Node-app), anyway, we got around this problem to add this to React's package.json instead: {"scripts": {"build": "NODE_PATH=./src react-scripts build"}} Now the build works in our Jenkins setup as well. Thanks for the tip! – jwanglof Jul 27 '18 at 09:27
  • 27
    Currently, create-react-app is showing a deprecated warning if you use this approach. The recommended way is now to use a jsConfig.json file: `{ "compilerOptions": { "baseUrl": "src" } }` – Agustin Meriles Apr 30 '19 at 19:35
  • 5
    More information about Agustin's comment found here: https://facebook.github.io/create-react-app/docs/importing-a-component#absolute-imports – Chasen Bettinger Jul 19 '19 at 23:35
  • Two questions: (1) I'm having a hard time importing a folder with index.js. It won't implicitly understand to point to index.js to find the exports. (2) Can we customize the alias of the absolute import? – Con Antonakos Oct 28 '19 at 21:42
  • think of the unfortunate new developer who starts working on your code base and has to deal with the ambiguity of npm packages vs folder names!! – Zach Smith Nov 13 '19 at 10:07
  • 2
    that option is depricated and should not be used... – dmitri Mar 11 '21 at 07:59
112

The approach in the accepted answer has now been superseded. Create React App now has a different way to set absolute paths as documented here.

To summarise, you can configure your application to support importing modules using absolute paths by doing the following:

Create/Edit your jsconfig.json/tsconfig.json in the root of your project with the following:

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

Once you have done this you can then import by specifying subdirectories of "src" (in the following example, components is a subdirectory of src) e.g.

import Button from 'components/Button'
Ben Smith
  • 19,589
  • 6
  • 65
  • 93
  • https://create-react-app.dev/docs/importing-a-component – Vigneshwaran Chandrasekaran Dec 24 '20 at 18:34
  • 2
    @VigneshwaranChandrasekaran that link is already included in my answer. See "...way to set absolute paths as documented [here](https://create-react-app.dev/docs/importing-a-component/#absolute-imports)." – Ben Smith Dec 29 '20 at 00:27
  • 1
    I like this solution better. – puerile Aug 19 '21 at 11:22
  • I really won't choose this solution. It allows aliases for all your `/src` subfolder structure. This could create many design and dependency problems on the writing of all future components by hiding its dependencies in favor of a minimalist import. We must choose wisely what can be aliased and what can be not. – caedes Jul 15 '22 at 14:32
  • Just to clarify, `baseUrl` is not specific to Create React App but is a general typescript setting, so should work in other scenarios - see https://www.typescriptlang.org/tsconfig#baseUrl – Rhumborl Mar 06 '23 at 17:01
6

We can use webpack 2 resolve property in the webpack config.

Sample webpack config using resolve :

Here component and utils are independent folder containing React components.

resolve: {
        modules: ['src/scripts', 'node_modules'],
        extensions: ['.jsx', '.js'],
        unsafeCache: true,
        alias: {
            components: path.resolve(__dirname, 'src', 'scripts', 'components'),
            utils: path.resolve(__dirname, 'src', 'scripts', 'utils'),
        }
    }

After that we can import directly in files :

import UiUtils from 'utils/UiUtils';
import TabContent from 'components/TabContent';

Webpack 2 Resolve Reference

santosh
  • 575
  • 3
  • 12
  • 1
    I use create-react-app package where i cannot modify the webpack config. Is there any other way of doing it? – Prem Jul 20 '17 at 11:36
  • webpack.config.js is available in below path : `/create-react-app/blob/master/packages/react-scripts/config/webpack.config.dev.js` `/create-react-app/blob/master/packages/react-scripts/config/webpack.config.prod.js` – santosh Jul 20 '17 at 11:42
  • 6
    No, it is not supported to modify these configs. You can eject but then you lose many benefits of CRA. Please see my answer for a supported way of doing this. – Dan Abramov Jul 20 '17 at 12:04
6

After you try Ben Smith's solution above if you find eslint complains about importing absolute path add the following line to your eslint config:

settings: {
  'import/resolver': {
    node: {
      paths: ['src'],
    },
  },
},

replace 'src' with your folder if you use your own boilerplate with your folder's name.

Ben Smith
  • 19,589
  • 6
  • 65
  • 93
2

The alias solution for craco or rewired create-react-app is react-app-alias for systems as: craco, react-app-rewired, customize-cra

According docs of mentioned systems replace react-scripts in package.json and configure next:

react-app-rewired

// config-overrides.js
const {aliasWebpack, aliasJest} = require('react-app-alias')

const options = {} // default is empty for most cases

module.exports = aliasWebpack(options)
module.exports.jest = aliasJest(options)

craco

// craco.config.js
const {CracoAliasPlugin} = require('react-app-alias')

module.exports = {
  plugins: [
    {
      plugin: CracoAliasPlugin,
      options: {}
    }
  ]
}

all

Configure aliases in json like this:

// tsconfig.paths.json
{
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "example/*": ["example/src/*"],
      "@library/*": ["library/src/*"]
    }
  }
}

And add this file in extends section of main typescript config file:

// tsconfig.json
{
  "extends": "./tsconfig.paths.json",
  // ...
}
oklas
  • 7,935
  • 2
  • 26
  • 42
2

Feb 2010
Wasted about an hour on this. An example is below:

Goal: Import App.css in HomePage.js

myapp\src\App.css
myapp\src\pages\HomePage.js

File: jsconfig.json

{
  "compilerOptions": {
    "baseUrl": "src"
  }
}

File: src\pages\HomePage.js

import "App.css";
Manohar Reddy Poreddy
  • 25,399
  • 9
  • 157
  • 140
1

I am using babel-plugin-module-resolver for my project to resolve that problem. babel-plugin-module-resolver also is the same as module-alis. So I think you should just resolve using module-alis problem.

Because you didn't tell us why using module-alis was fail? So i cant show you how to fix it.

Dont give up your solution while you dont know the reason!

1

in package.json file,

eject this code in the scripts object like this..

  "scripts": {
    "start": "node scripts/start.js",
    "build": "node scripts/build.js",
    "test": "node scripts/test.js --env=jsdom",
     "eject": "NODE_PATH=src/ react-scripts eject"
  },

this will enable the absolute path imports in your app

parag patel
  • 2,933
  • 1
  • 10
  • 22
  • This gave me a lead how to fix our "react-scripts build". See my comment in @dan-abramov 's answer (https://stackoverflow.com/a/45214138/2986873). Thanks! – jwanglof Jul 27 '18 at 09:29
0

None of the answers worked for me. Some didn't work at all and others worked but the import was already inside src, for example:

import something from 'path/to/file'.

Whereas I wanted to be able to do:

import something from 'src/path/to/file'

Here is how I solved it:

tsconfig.json

{
  "compilerOptions": {
    // ...
    "baseUrl": ".",
    "rootDirs": [
      "src"
    ]
  },
  "include": [
    "src"
  ]
}
Liran H
  • 9,143
  • 7
  • 39
  • 52