How to add Jest into your Vite project with TS

Rmag Breaking News

Hi future me! I’m sure you are as amazed as I am right now to find that the guide you are looking for was written by yourself, it happens to the best of us.

Remember you wrote this for:

Vite 5
Jest 29
Typescript 5.2
And… React 18 in case we have something else in the future

Let’s get started!

First, you need to add a couple of dependencies:

npm i -D jest jest-environment-jsdom jest-transform-stub ts-jest @types/jest @testing-library/react

jest: The testing framework
jest-environment-jsdom: Jest environment for testing in a browser-like environment
jest-transform-stub: Jest transformer for handling non-JS files
ts-jest: Jest preset for TypeScript
@types/jest: TypeScript type definitions for Jest
@testing-library/react: Testing utilities for React components

Ok, I agree they are a lot. But that’s the reason why you are writing this, ain’t?

Creating the Jest Config file

So, by default Jest doesn’t parse TS, even if you have the required dependencies. So you need to tell Jest how to parse it, and you do that using a jest.config.cjs file.

Notice that it is a cjs file, because we want to use the old CommonJs module resolution here. Vite supports the new ES module standard by default, and creates a package.json configuration to load .js files as ES module, so by using a cjs we are telling Node to load this file using the CommonJs module resolution instead.

Lucky for us, there is a command we can use to create it:

# Initialize a Jest configuration file for TypeScript
npx ts-jest config:init

That will create a base jest.config.js, that we need to rename to jest.config.cjs and update it with the following content:

/* eslint-disable */

const { pathsToModuleNameMapper } = require(ts-jest);
const { compilerOptions } = require(./tsconfig);

/** @type {import(‘ts-jest’).JestConfigWithTsJest} */
module.exports = {
roots: [<rootDir>],
preset: ts-jest,
testEnvironment: jsdom,
modulePaths: [compilerOptions.baseUrl],
moduleNameMapper: pathsToModuleNameMapper(compilerOptions.paths ?? {}),
transform: {
.+\.(css|less|sass|scss|png|jpg|gif|ttf|woff|woff2|svg)$:
jest-transform-stub,
},
};

So, yes, you found a command a ran it, and then you create another file and updated it until it worked.

You’ll notice that this config file already supports for the path mapping feature from TS. You are welcome!

That’s all! Right? — No

There is an import in the App.tsx created by Vite by default, that is importing a logo from a root like route:

import viteLogo from /vite.svg

I don’t know what’s that, I don’t know where that is being imported from, and I don’t need that, so I removed it to make this configuration works.

Extra: Adding Path mapping support for Vite

Vite doesn’t support Path mapping either, but we have a plugin available for that.

Path mapping is a TypeScript feature that simplifies file imports by allowing developers to create aliases for directory paths relative to the project root. It enhances code readability and maintainability by replacing lengthy or complex import paths with custom aliases.

npm i -D vite-tsconfig-paths

With that, we can update our vite.config.ts file with that.

import { defineConfig } from vite;
import react from @vitejs/plugin-react;
import tsconfigPaths from vite-tsconfig-paths;

// https://vitejs.dev/config/
export default defineConfig({
plugins: [react(), tsconfigPaths()],
});

That’s all future me!

I hope this has been useful to you, and maybe others, but I know you’ll forget this as soon as I publish this. If this is no longer valid, and you are me please update the post so future us can use it. If you are not me, please, let me know in the comments, so I can update the post.

As always, thanks for reading!

Leave a Reply

Your email address will not be published. Required fields are marked *