Introduction
In this article, you'll learn how to set up a React App in ViteJS, with Jest available to test your components.
Why ViteJS?
I've used Create React App (CRA) + Create React App Configuration Override (CRACO) for most of my React development. It's great and probably what you want to use within your company if you already have the infrastructure and developer knowledge.
However, CRA is no longer being maintained, and in my last role, I faced a few issues, such as upgrading and migrating Yarn to a new major version, upgrading the project's dependencies, and navigating the iceberg that is the CRACO configuration. All of this while desperately looking through the issues on CRA/CRACO to find other users trying to do the same thing.
In my personal projects, I moved over to ViteJS as a starting base, and for the purposes of this article, the primary reason I will give is that it will give you as simple of a template as possible to start with. Compared with CRA/CRACO, which, to the benefit of developers everywhere, comes preinstalled with tons of packages to get your React app production ready as quickly as possible.
With Vite, you'll find that we have to do a few steps to get Jest up and running, which could break and leave you scratching your head for some time. However, I strongly believe that going through this process will help you understand how Jest is installed in a project and the packages it requires to transpile and run your Typescript tests.
After following this article, I hope you'll better understand what makes your projects work. Rather than create-react-app react-typescript
and praying that you can, without touching the config, write tests and be productive, and all will be well.
Creating the project
From the ViteJS docs itself, run the following command in an empty directory to get your app off the ground. I use yarn; you can use whatever you want.
# yarn
yarn create vite your-react-app --template react-ts
From here you should have a basic ReactJS + Typescript app, you can 'yarn' and 'yarn dev' to make sure it runs. This app will be so barebones unless the template changes; you won't have Jest, babel, or any JS-based testing environments, so let's install these.
Packages required for Jest
The packages below are pretty standard for this installation; you have React Testing Library, Jest, then some Babel presets that will help transpile your code and configure the testing environment, and lastly, some types. All of these should be added to your DEV dependencies.
yarn add --dev jest @testing-library/react @babel/preset-react @testing-library/jest-dom @babel/preset-env @babel/preset-typescript @types/jest
Add a line in your package.json to run the Jest test command.
"scripts": {
"test": "jest",
// other commands should already exist
},
Before we install some more packages, let's set up the babel configuration. Jest ships with Babel, so we must import the presets (a step above) and create a babel.config.cjs
file in the root directory with this content. This is all it should take to have Babel working, but you won't see the results yet.
module.exports = {
presets: [
"@babel/preset-env",
"@babel/preset-typescript",
["@babel/preset-react", {
"runtime": "automatic"
}]
],
};
Back to package installation, we need 3 packages here to get things working.
yarn add --dev jest-environment-jsdom //The testing environment itself
yarn add --dev ts-jest //Required for Jest to read TS testing files
yarn add --dev ts-node //Required for Jest to read TS config files
Now we need to create our jest config, there's a few ways to do this (in package.json, or a js/ts/cjs and many more files) but I am going to keep it consistent with our babel choice, and use cjs
Create a file called jest.config.cjs
with these contents, however I am going to comment on what's required, and what we will most likely need in the near future.
/** @type {import('ts-jest').JestConfigWithTsJest} */
module.exports = {
preset: 'ts-jest', //REQUIRED
testEnvironment: "jsdom", //REQUIRED
moduleNameMapper: {
"\\.(css|less|sass|scss)$": "<rootDir>/__mocks__/styleMock.js", // REQUIRED FOR CSS IMPORTS
}
};
Because I want to make this article as simple to follow, I highly recommend you add the moduleNameMapper
line and create a style mock (add a folder named mocks in the root directory, then add a file called styleMock.js);
The file that is referenced for style mocks is just a JS file with an empty export.
module.exports = {};
We're so close; if you were to run a yarn test
right now, you should get an error that there are no tests. This is good, now we can add a test file and verify if everything is hooked up correctly. I am opting to test the App.tsx file, but I stripped it back to simplify it. Here's the App.tsx and the App.test.tsx I created
App.tsx
import './App.css' // I recommend importing CSS, to make sure your moduleNameMapper is working
function App() {
return (
<>
<h1>React Vite Jest</h1>
</>
)
}
export default App
App.test.tsx
import { render, screen } from "@testing-library/react";
import "@testing-library/jest-dom";
import App from "./App.tsx";
describe("Basic Testing Library Test - Should Always Pass", () => {
it("Should Pass", function () {
expect(true).toBe(true);
});
});
describe("Render App", () => {
it("component should have basic text", async function () {
render(<App />);
expect(screen.getByText("React Vite Jest"));
});
});
The moment of truth
If you've set up everything above correctly, you should be able to run a yarn
then yarn test
and see your tests pass; if they do, it means you're an amazing developer who now has an extremely simple template to write React code and test it.
If things are failing, don't panic. Carefully read the errors and reiterate the steps above to ensure your code is identical. Otherwise here is a template repo I'm maintaining, which should reflect the exact steps listed above (plus some readme/gitignore stuff)
https://github.com/NickFane/react-ts-vite-jest
On to part 2
Part 2 will cover taking this template and building a solid foundation for your tests. Including some testing methodologies to adhere to, reusability, and the extension of the template for common packages you might include in your React app.
If you've made it this far, I appreciate you taking the time to read through it, and I hope it helps you in future dev work. Please consider giving the article a like, a comment describing how it's helped, or any feedback you may have.
You can find/contact me via
Github - @NickFane
LinkedIn
Top comments (0)