How to avoid using relative path imports (/../../../redux/action/action1) in create-react-app
Asked Answered
B

9

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'

Burse answered 20/7, 2017 at 11:22 Comment(1)
Two years on, CRA now has a new approach to configuring absolute imports. See the answer here.Acquaintance
M
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.

Machos answered 20/7, 2017 at 12:2 Comment(10)
Can I do this in react-create-app? I tried, but it seem not to work, although guy from here medium.com/@ktruong008/… suggest the sameSlaughterhouse
@Mehari what's your version of create-react-app and react-scripts?Valedictorian
@qwang create-react-app-1.4.3 & react-scripts-1.0.14Entrench
More details about implementation can be found here - youtu.be/xHiCRpfZIO8Burse
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!Ereshkigal
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" } }Mendelism
More information about Agustin's comment found here: facebook.github.io/create-react-app/docs/…Khalsa
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?Brassica
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!!Dulse
that option is depricated and should not be used...Attainture
A
113

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'
Acquaintance answered 5/12, 2019 at 13:11 Comment(5)
create-react-app.dev/docs/importing-a-componentStegodon
@VigneshwaranChandrasekaran that link is already included in my answer. See "...way to set absolute paths as documented here."Acquaintance
I like this solution better. 👍Manas
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.Entomostracan
Just to clarify, baseUrl is not specific to Create React App but is a general typescript setting, so should work in other scenarios - see typescriptlang.org/tsconfig#baseUrlPortentous
C
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

Chrisy answered 20/7, 2017 at 11:29 Comment(3)
I use create-react-app package where i cannot modify the webpack config. Is there any other way of doing it?Burse
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.jsChrisy
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.Machos
B
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.

Brainless answered 27/4, 2020 at 12:26 Comment(1)
Cheers for the reference and +1 for getting eslint to work nicely with the solution.Acquaintance
K
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",
  // ...
}
Kendry answered 13/3, 2020 at 5:42 Comment(0)
A
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";
Abductor answered 13/2, 2021 at 9:31 Comment(0)
A
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!

Asco answered 20/7, 2017 at 11:47 Comment(1)
This won't work with Create React App. It does not support custom Babel plugins.Machos
E
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

Entomophagous answered 17/7, 2018 at 22:36 Comment(1)
This gave me a lead how to fix our "react-scripts build". See my comment in @dan-abramov 's answer (https://mcmap.net/q/210639/-how-to-avoid-using-relative-path-imports-redux-action-action1-in-create-react-app). Thanks!Ereshkigal
B
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"
  ]
}
Boardman answered 27/2, 2021 at 15:57 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.