jest: configuring jest to resolve modules

2021-04-30

 | 

~2 min read

 | 

394 words

A common pattern within Javascript applications is to use Webpack or Typescript to treat internal directories as modules so that they can be imported as absolute paths instead of relative paths.

For example, let’s say that we have a project structure like the following:

.
├── src
│   ├── shared
│   │   └── useful-module.js
│   ├── app.js
│   └── index.js
└── package.json

Then, within our app.js we want to make use of the usefulModule.js. If we’re using modules, we could resolve it in the following way:

app.js
import usefulModule from "./shared/useful-module"

But, if we’ve already configured our Typescript to use aliases, or we have a webpack config that has a resolve key for modules, then we’ll need to update our Jest configuration to understand how to resolve this path since by default Jest uses the same Node module resolution algorithm.

For example, if our webpack config looks like this:

webpack.config.js
const path = require("path")

module.exports = {
  resolve: {
    modules: ["node_modules", path.join(__dirname, "src"), "shared"],
  },
}

Then app.js might have an absolute import like this:

app.js
import usefulModule from "usefulModule"

But, now, let’s do a simple rendering test:

app.test.js
import app from "./app.js"
import { render } from "@testing-library/react"

test("it renders", () => {
  render(app)
})

When we run this test, we’ll get a failure similar to:

 FAIL   client  src/app.test.js
  ● Test suite failed to run

    Cannot find module 'usefulModule' from 'src/app.js'

    Require stack:
      src/app.js
      src/app.test.js

      1 | import React from 'react'
      2 | import PropTypes from 'prop-types'
    > 3 | import UsefulModule from 'useful-module'
        | ^

We can fix this by telling Jest to use the same resolution as webpack. To do so, we’ll need to define moduleDirectories within the jest.config.js:

jest.config.js
const path = require("path")

module.exports = {
  rootDir: ".",
  moduleDirectories: ["node_modules", path.join(__dirname, "./src/shared")],
}

Here, we’ve said that Jest should resolve anything in the node_modules as well as what’s in the shared directory within src as a module. Alternatively, and perhaps more understandably, we can use the exact same array as what we have in our webpack.config.js:

jest.config.js
module.exports = {
  rootDir: '.',
-   moduleDirectories: ['node_modules', path.join(__dirname, './src/shared') ],
+   moduleDirectories: ['node_modules', path.join(__dirname, 'src'), 'shared'],,
}

Once we make these changes and rerun the tests, we’ll see that the error goes away as Jest was able to successfully resolve the module!


Hi there and thanks for reading! My name's Stephen. I live in Chicago with my wife, Kate, and dog, Finn. Want more? See about and get in touch!