31

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/...)?

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" Commented Feb 2, 2017 at 3:03
  • Sorry I missed the directory structure. I added the location path for the components and test file which is basically inside /imports as well. Commented Feb 2, 2017 at 3:10
  • 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" . Commented Feb 2, 2017 at 4:45
  • 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. Commented Feb 2, 2017 at 23:05
  • github.com/tleunen/babel-plugin-module-resolver works for me Commented Feb 24, 2017 at 2:06

7 Answers 7

47

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

Sign up to request clarification or add additional context in comments.

5 Comments

"plugins": ["@babel/plugin-proposal-export-default-from"] just added this plugin in package.json#babel. Hopefully it will work for you.
@Daniels solution worked fine, without having to add yet another plugin for something as trivial as this
baseUrl should be . and not the word "imports" as stated
@vsync 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"
You might need to restart such as npm start
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

Comments

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.

1 Comment

This is now depricated in preference of using a jsconfig.json file: stackoverflow.com/questions/56437517/…
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.

2 Comments

Hey this looks promising. I'll have a go after couple days and give updates here. Thanks for the inputs!
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.
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"] 
}

Comments

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.

Comments

1

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

"modulePaths": ["<rootDir>/src/"]

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.