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 apackage.json
configuration to load.js
files as ES module, so by using acjs
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!