Setting up Jest under Expo to work with .jsx files

Russell Hunter
Level Up Coding
Published in
3 min readMay 5, 2020

--

Cat hanging on fence by front paws

I wanted to learn about React Native development as an easy way to create cross platform apps. I followed the set up steps and I was able to easily use Expo to set up a simple app and have it working on my iPhone. One thing I wanted to do with my project was to add in unit testing with Jest. When you set up Expo, it also includes Jest as part of the managed project setup. The simple app showed that everything was working, but I wanted make some changes to my project structure.

First, I wanted to move all of my code to a src folder with a components folder inside. To do this, I first added a src folder to the project. I then moved the App.js file to src folder. Since Expo expects there to be an App.js file in the top folder of the project in order to run, I created a new App.js folder at the top level that imports the contents of the real file. So my App.js file at the top folder has the following contents:

import App from ‘./src/components/App’;
export default App;

This way, there was no code at the top level of my project and I could test all of my code.

Next, I wanted to use .jsx files to keep track of which files were simple .js files and which files were .jsx files with React Native code in them. So in the src folder, I renamed the App.js file to App.jsx. I then added a simple unit test to test the app. I created an App.test.jsx file with these contents:

import React from ‘react’;
import renderer from ‘react-test-renderer’;
import App from ‘./App’;
describe(‘<App />’, () => {
it(‘has 1 children’, () => {
const tree = renderer.create(<App />).toJSON();
expect(tree.children.length).toBe(1);
});
});

When I made these changes to my project, I was not able to get Jest to work. I kept getting this error:

({“Object.<anonymous>”:function(module,exports, require,__dirname,__filename,global,jest){import React from ‘react’;SyntaxError: Cannot use import statement outside a module

I spent a lot of time looking into the error and I tried lots of things to fix it. After looking at lots of other projects and going down many dead-ends, I found the solution. I needed to use babel-jest to transform my files in my folders.

The current Expo project setup puts all of your Jest settings in the package.json file. By default it only include these lines:

"jest": {
"preset": "jest-expo",
},

In order for my changes to work, I needed to add another setting for Jest. Here are my changes to the Jest settings in my package.json file::

"jest": {
"preset": "jest-expo",
"transform": {
"^.+\\.[jt]sx?$": "babel-jest"
}
},

When I made this change, I could then run npm test and have it test my files. This was great news.

The strange thing about my change working is when you look at the Jest documentation, for transform, it shows that the transform I am using should be the default value. But for some reason it is not. To see what configuration Jest is run with, you can use the Jest command line option of — showConfig. In your shell, you can run this command:

npm test — — showConfig

This will show all of the current configurations that Jest is using. When I looked at the output, I found out that the Expo setup has this transformation regex for babel-jest:

"transform": [
["^.+\\.(js|ts|tsx)$",
"/Users/foo/git/expo-app/node_modules/babel-jest/build/index.js"],
["^.+\\.(bmp|gif|jpg|jpeg|mp4|png|psd|svg|webp|ttf|otf|m4v|mov|mp4|mpeg|mpg|webm|aac|aiff|caf|m4a|mp3|wav|html|pdf|obj)$",
"/Users/foo/git/expo-app/node_modules/jest-expo/src/preset/assetFileTransformer.js"]
],

You will notice that the regex is “^.+\\.(js|ts|tsx)$” for bable-jest. Jest will only transform files that end in .js, .ts, or .tsx. Notice that .jsx files are completely missing from the regex. So my change adds transforming .jsx files back into the process for Jest.

Hopefully this helps you set up your Expo project the way you want to and shows you a good debugging flag to use to find issues with Jest.

--

--