Import react components with absolute path
Asked Answered
H

7

28

Here is my test file

// /imports/components/main.test.js
import React from 'react'
import { shallow, mount } from 'enzyme'
import Main from './main'
import TextInput from "/imports/ui/textInput"
...

and the main.js has

// /imports/components/main.js
import { action1 } from "/imports/actions/myAction"

but it throws an error when I run the test, saying

Cannot find module '/imports/actions/myAction' from 'main.js'

If I comment the import './main', same thing happen with importing TextInput. I have no issue with importing modules in node_modules.

How can I tell Jest or webpack to import the component using absolute path from project directory (i.e import Foo from /imports/...)?

Helpmeet answered 2/2, 2017 at 2:54 Comment(6)
If there is a directory called imports at the same level of your test file, you should at a dot like: import TextInput from "./imports/ui/textInput"Cannonry
Sorry I missed the directory structure. I added the location path for the components and test file which is basically inside /imports as well.Helpmeet
you can simply import like import TextInput from "../ui/textInput" in main.test.js and import { action1 } from "../actions/myAction" . If you want to import with absolute path, then you must do aliasing in your webpack.config and then import like import { action1 } from "imports/actions/myAction" .Slaver
The ../actions/myAction is imported from main.js, not test file, and it is working perfectly fine on the component. And I don't need to import that on test file. In test file, I just need to import the main.js component and textInput for testing shallow rendering. I am sorry if it is confusing.Helpmeet
github.com/tleunen/babel-plugin-module-resolver works for meIcarus
@Icarus yup works for me too!Helpmeet
K
3

My file structure follows exactly the same pattern as yours. To teach Jest into using imports beginning with a /, I use babel-plugin-module-resolver and its handy root option. My .babelrc for Jest looks like this:

{
  "presets": ["es2015", "meteor"],
  "plugins": [
    "transform-class-properties",
    "transform-react-constant-elements",
    "transform-react-inline-elements",
    "transform-react-remove-prop-types",
      ["module-resolver", {
      "root": ["../"],
      "alias": {
        "react-router-dom": "react-router-dom/umd/react-router-dom.min.js",
        "redux": "redux/dist/redux.min.js",
        "react-redux": "react-redux/dist/react-redux.min.js"
      }
    }]
  ]
}

As I'm using Meteor which customized its root imports, I hide my Jest usage and configuration into a .jest directory at the root of my repository allowing me to have a specific .babelrc without risking conflicts with Meteor's one.

Kuvasz answered 16/2, 2017 at 9:44 Comment(2)
Hey this looks promising. I'll have a go after couple days and give updates here. Thanks for the inputs!Helpmeet
Sorry for the late update, but this solution works great! Installed the resolver module and set the root, now I able to use import .. from '/imports/foo. Thanks.Helpmeet
J
46

Better way to solve relative path import issue, is by creating jsconfig.json file adjacent to package.json file.

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

then import { action1 } from "actions/myAction"; will work

Jinny answered 6/9, 2019 at 9:23 Comment(5)
"plugins": ["@babel/plugin-proposal-export-default-from"] just added this plugin in package.json#babel. Hopefully it will work for you.Jinny
@Daniels solution worked fine, without having to add yet another plugin for something as trivial as thisDorella
baseUrl should be . and not the word "imports" as statedAmoritta
@Amoritta Thanks for the feedback, It was a typo from my side. It should be directory from which you would like to set baseUrl. In my case, it is "src"Jinny
You might need to restart such as npm startFaber
F
30

If you're using Create React App, you can set up the absolute imports path in a jsconfig.json (need to create in a fresh JavaScript template) or tsconfig.json (already created in the TypeScript template) at the root of your project to serve your usage.

Example:

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

Official docs: https://create-react-app.dev/docs/importing-a-component/#absolute-imports

Flory answered 4/12, 2020 at 0:8 Comment(0)
T
7

Another solution is to create an .env file within the root directory of your project.

Within it you will add NODE_PATH=src/

Thats all

Save the file and restart your dev environment in terminal.

Afterwards, you will go through your project and update some import statements accordingly.

Tripetalous answered 5/9, 2018 at 23:38 Comment(1)
This is now depricated in preference of using a jsconfig.json file: #56438017Adhere
K
3

My file structure follows exactly the same pattern as yours. To teach Jest into using imports beginning with a /, I use babel-plugin-module-resolver and its handy root option. My .babelrc for Jest looks like this:

{
  "presets": ["es2015", "meteor"],
  "plugins": [
    "transform-class-properties",
    "transform-react-constant-elements",
    "transform-react-inline-elements",
    "transform-react-remove-prop-types",
      ["module-resolver", {
      "root": ["../"],
      "alias": {
        "react-router-dom": "react-router-dom/umd/react-router-dom.min.js",
        "redux": "redux/dist/redux.min.js",
        "react-redux": "react-redux/dist/react-redux.min.js"
      }
    }]
  ]
}

As I'm using Meteor which customized its root imports, I hide my Jest usage and configuration into a .jest directory at the root of my repository allowing me to have a specific .babelrc without risking conflicts with Meteor's one.

Kuvasz answered 16/2, 2017 at 9:44 Comment(2)
Hey this looks promising. I'll have a go after couple days and give updates here. Thanks for the inputs!Helpmeet
Sorry for the late update, but this solution works great! Installed the resolver module and set the root, now I able to use import .. from '/imports/foo. Thanks.Helpmeet
T
2

With webpack(v4) and babel, you can provide absolute paths in your directory. Follow these steps In your .babelrc file, make this entry for plugins.Make sure you have babel-plugin-root-import in your package.json as well.

"plugins": [
    [
        "babel-plugin-root-import",
        {
          "paths": [
            {
              "rootPathPrefix": "~",
              "rootPathSuffix": "./"
            },
            {
              "rootPathPrefix": "@src",
              "rootPathSuffix": "src"
            },
            {
                "rootPathPrefix": "@any-other-folder",
                "rootPathSuffix": "src/client/../any-other-folder"
              }
          ]
        }
      ]
]

Now if you run into eslint issue, you can add these lines in your eslintrc:

"settings": {
"import/resolver": {
  "babel-plugin-root-import": [
    {
      "rootPathPrefix": "@src",
      "rootPathSuffix": "src"
    },
    {
      "rootPathPrefix": "@any-other-folder",
      "rootPathSuffix": "src/client/../any-other-folder"
    }
  ]
 }
}

Now to make your editor recognize these paths, you can create this entry in jsconfig file.

{
"compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "~/*": ["/*"],
      "@src/*": ["src/*"],
      "@any-other-folder/*": ["src/client/../any-other-folder/*"] ==> absolute path to any other folder
    }
  },
  "exclude": ["node_modules"] 
}
Tetryl answered 29/1, 2021 at 6:3 Comment(0)
M
1

I had jest configs in package.json file (under "jest" key). So I just have added there this row:

"modulePaths": ["<rootDir>/src/"]
Mouldy answered 25/11, 2020 at 15:29 Comment(0)
S
1

Add below in your jsconfig.json/tsconfig.json file.

{
  "compilerOptions": {
    "baseUrl": "src",
  },
  "include": ["src"],
  "exclude": ["node_modules", "build"]
}

suppose folder structure is like src->components->Header.tsx then you arevable to import as below.

import Header from 'components/Header';

because baseUrl mentioned in tsconfig.json/jsconfig.json as src.

Note: nothing else is required but if you want to import with prefix @/ way then please let me know.

Statampere answered 23/10, 2023 at 9:13 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.