BLOG

How to setup jest test runner in react application with parcel.js

Recently I tried to migrate one my React app to Parcel.js and had challenge to set up jest test runner.

Here is some step-by-step guide how to do it.

I had a project with following structure:

/
├─ package.json
└─ src
   ├─ components
   │  ├─ SomeComponent.js
   │  ├─ SomeComponent.test.js
   │  └─ SomeComponent.css
   ├─ index.html
   ├─ index.js
   ├─ index.css
   ├─ App.js
   ├─ App.test.js
   └─ App.css

Also I don't use enzyme test runner, but a simple react-test-renderer

It is a common structure generated by default by create-react-app:

  • test files named by *.test.js
  • css is located in separate file *.css

First, I followed official jest guide (https://jestjs.io/docs/en/tutorial-react#setup-without-create-react-app) and added these dependencies to project:

yarn add --dev jest babel-jest @babel/preset-env @babel/preset-react react-test-renderer

Now add/modify test script in package.json to look as:

// package.json
"scripts": {
  "test": "jest"
}

And execute yarn run test.

In theory it should work. But didn't. An error was shown:

    SyntaxError: Unexpected token .

      1 | import React from 'react';
    > 2 | import './App.css';
        | ^

So seems that jest doesn't know what to do with .css files. After some investigation I found following config. Just added it into my package.json file:

// package.json

"jest": {
  "verbose": true,
  "transform": {
    "^.+\\.js$": "babel-jest",
    ".+\\.(css|styl|less|sass|scss)$": "jest-css-modules-transform"
  },
  "globals": {
    "NODE_ENV": "test"
  },
  "moduleFileExtensions": ["js", "jsx"],
  "moduleDirectories": ["node_modules"]
}

And installed one dependency for transforming css:

yarn add -D jest-css-modules-transform

Now it should work in most of the cases. I also used absolute paths in my project according Parcel.js guide so my imports look like (notice leading /):

// App.js
import { SomeComponent } from "/components/SomeComponent";

So if you get some similar error:

    Cannot find module '/components/SomeModule' from 'App.js'

    However, Jest was able to find:
        './App.css'
        './App.js'
        './App.test.js'

    You might want to include a file extension in your import, or update your 'moduleFileExtensions', which is currently ['js', 'jsx'].

    See https://jestjs.io/docs/en/configuration#modulefileextensions-array-string

      1 | import React from 'react';
      2 | import './App.css';
    > 3 | import { SomeModule } from '/components/SomeModule';
        | ^

Then simply add this block to jest config:

// package.json
"jest": {
  "moduleNameMapper": {
    "^/(.*)$": "<rootDir>/src/$1"
  },
  ... other config options
}

It works as alias. All imports started by / and followed by whatewer till the end of path is replaced by <rootDir>/src/$1

Final jest config should look:

// package.json

"jest": {
  "moduleNameMapper": {
    "^/(.*)$": "<rootDir>/src/$1"
  },
  "verbose": true,
  "transform": {
    "^.+\\.js$": "babel-jest",
    ".+\\.(css|styl|less|sass|scss)$": "jest-css-modules-transform"
  },
  "globals": {
    "NODE_ENV": "test"
  },
  "moduleFileExtensions": ["js", "jsx"],
  "moduleDirectories": ["node_modules"]
}

Now everything should work.