javascriptreactjsjestjsbabeljsbabel-jest

Why does the stack trace for my jest tests point to the wrong line numbers?


When I run jest tests in my repo containing errors, the stack trace points to the wrong line numbers. This makes it very difficult to debug. For example:

Expected error

  ● SimpleComponent › renders

    ReferenceError: retur is not defined

      4 | export const Simple = () => {
      5 |   const [count, setCount] = useState(0);
    > 6 |   retur (
        |   ^
      7 |     <div>
      8 |       <p>You clicked {count} times</p>
      9 |       <button onClick={() => setCount(count + 1)}>Click me</button>

      at Simple (src/SimpleComponent.jsx:6:3)
      at Object.<anonymous> (tst/SimpleComponentTest.jsx:8:5)

Received error

Note that it's pointing to the wrong line number - 34 instead of 6.

  ● SimpleComponent › renders

    ReferenceError: retur is not defined



      at Simple (src/SimpleComponent.jsx:34:3)
      at Object.<anonymous> (tst/SimpleComponentTest.jsx:14:23)

My findings

I found that if I comment out the moduleDirectories entry in jest.config.js, then I get the expected error message. I don't understand why moduleDirectories has such an impact though.

However, I want to keep my moduleDirectories.

Question

Why does the stack trace for jest tests point to the wrong line numbers? How can I fix it?

Files

I have uploaded a minimal example in https://github.com/bluprince13/jest-wrong-line-numbers-in-stack-trace

Source

Note that return statement is spelt wrong.

// src/SimpleComponent.jsx
import React, {useState} from "react"

export const Simple = () => {
  const [count, setCount] = useState(0);
  retur (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>Click me</button>
    </div>
  );
};

Test

// tst/SimpleComponentTest.jsx
import { Simple } from "../src/SimpleComponent";
import { render } from "@testing-library/react";
import React from "react";

describe("SimpleComponent", () => {
  it("renders", () => {
    render(<Simple />);
  });
});

.babelrc

{
    "presets": [
        "@babel/preset-react",
        [
            "@babel/preset-env"
        ]
    ]
}

jest.config.js

module.exports = {
  moduleDirectories: [
    "<rootDir>/src",
    "<rootDir>/tst",
    "<rootDir>/node_modules"
  ],
  testMatch: ["**/tst/**/(*)Test.js?(x)", "**/?(*.)(spec|test).js?(x)"],
  transform: {
    "^.+\\.jsx?$": "babel-jest"
  }
};

package.json

{
    "scripts": {
        "test": "jest --runInBand"
    },
    "dependencies": {
        "react": "^16.14.0",
        "react-dom": "^16.14.0",
        "snapshot-diff": "^0.6.2"
    },
    "devDependencies": {
        "babel-jest": "^25.2.4",
        "@babel/preset-env": "7.x",
        "@babel/preset-react": "7.x",
        "@testing-library/react": "^9.2.0",
        "jest": "^26.6.3"
    }
}

Solution

  • Why does the stack trace for jest tests point to the wrong line numbers? How can I fix it?

    It has to do with source maps. If those are not correctly generated or processed, the debugger will show the wrong line.

    I found three ways how to fix this issue:

    1. Changing <rootDir>/node_modules to node_modules in your moduleDirectories

      Why does this fix the issue?

      • If <rootDir> is added, jest or more precisely its underlying module source-map-support uses the source_map module from node_modules/source-map. Which in my case with a fresh install of your example, is 0.7.3. But the source_map_support relies on ^0.6.0. It actually brings the right version under node_modules/source-map-support/source-map. But for some reason with the <rootDir> specified, it can't access it anymore. And that brings us to the second solution.
    2. Downgrade the source-map module to ^0.6.0 by manually including it as a dependency of your project. In that case node_modules/source-map will provide the right version again, but that might break something else, since it is not clear, where this wrong version is originating from.

    3. Upgrade your project dependencies to the newest version. try npm outdated and you will see, that they are all outdated: enter image description here