How to add Jest into your Vite project with TS

Michael De Abreu - Mar 30 - - Dev Community

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
Enter fullscreen mode Exit fullscreen mode
  • 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
Enter fullscreen mode Exit fullscreen mode

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",
  },
};
Enter fullscreen mode Exit fullscreen mode

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'
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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()],
});
Enter fullscreen mode Exit fullscreen mode

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!

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .