Creating a Modern React Project Vite, TypeScript, Test, EsLint, Prettier, Lint-Staged, Commitlint and husky

Kayra Berk Tuncer
6 min readMay 8, 2022
Photo by Lautaro Andreani on Unsplash

We need to benefit from many resources to create a modern, fast and good react app.

We will create a modern react app using up-to-date technologies and see the use of tools that will increase readability and maintenance.

Why do we need these technologies?

Most of the technologies we will use are used in the react app, some of which were integrated later, some were established at the beginning of the project. Thanks to these technologies:

  • We will increase code readability
  • We will increase maintenance
  • We will write our commit messages understandable
  • We will avoid most of the code errors

Git

Git is a version control system(VCS) that allows us to develop our code safely as a team.

We create a .git file with the git init command and the changes we made to git are kept there.

Vite

Vite is a build tool that aims to provide a faster and leaner development experience for modern web projects.

We start the installation of our project with npm. To use Vite you need to have Node version 12.2.0 and above.

$ npm create vite@latest

We start the installation and follow the steps below.

Husky & Commitlint

Husky improves your commits and more 🐶 woof!

Commitlint helps your team adhering to a commit convention.

Before proceeding with the installation, let’s make our initial commit.

$ git add .
$ git commit -m "Initial commit"

Lets setup the commitlint.

# Install and configure if needed 
$ npm install --save-dev @commitlint/{cli,config-conventional}
# For Windows:
$ npm install --save-dev @commitlint/config-conventional @commitlint/cli
# Configure commitlint to use conventional config
$ echo "module.exports = { extends: ['@commitlint/config-conventional'] };" > commitlint.config.js

Then we setup husky

# Install Husky 
$ npm install husky --save-dev
# Active hooks
$ npx husky install
# Add hook
cat <<EEE > .husky/commit-msg
#!/bin/sh
. "\$(dirname "\$0")/_/husky.sh"

npx --no -- commitlint --edit "\${1}"
EEE

Now our commit messages will be applied in accordance with conventional commit thanks to commitlint and husky.

Let’s check if it works.

$ git add .
$ git commit -m "foo: test commit"

If you haven’t received any output, you should use the chmod ug+x .husky/* command.

$ git add .
$ git commit -m "chore: lint on commitmsg"

Jest & React Testing Library

Generally, Jest and React Testing Library are used for unit testing, so I wanted to use these technologies. You can also use different technologies according to your needs.

npm i -D @testing-library/jest-dom @testing-library/react @types/jest @types/testing-library__jest-dom jest jest-environment-jsdom @swc/core @swc/jest

Add Scripts:

"jest:watch": "jest --watch","jest:run": "jest"
Add jest.setup.js file
Add jest.config.js file

React Testing Library

React Testing Library builds on top of DOM Testing Library by adding APIs for working with React components.

Jest

Jest is a delightful JavaScript Testing Framework with a focus on simplicity.

@swc/jest

To make your Jest tests run faster, you can swap out the default JavaScript-based runner (ts-jest) for a drop-in Rust replacement using SWC.

Simple Test

Add src/app.test.tsx file.

import React from 'react';test('Should 1 + 1 equals 2', () => {expect(1 + 1).toEqual(2);});

After running this command(npm run jest:run) you will see that your test is running.

Cypress

Fast, easy and reliable testing for anything that runs in a browser.

npm i -D cypress eslint-plugin-cypress identity-obj-proxy

Let’s run cypress

You can check the tests that are ready after Cypress is running.

npx cypress open

Add Scripts:

"cypress:open": "cypress open","cypress:run": "cypress run","test": "run-p cypress:run jest:run"

Ignore cypress files

cypress/videoscypress/screenshots

Add these in .gitignore

Add husky command

Let’s add the test command(npm test)we added to the husky and see that our tests are running when we commit.

Prettier

Prettier is an opinionated code formatter. Prettier takes your code and reprints it from scratch by taking the line length into account.

Step 1: Install prettier

$ npm install -D prettier

Step 2: Configure prettier

$ echo {}> .prettierrc.json

Step 3: Generate rules

With the playground feature in the prettier, you can customize it according to you. You can get the properties by clicking the Copy config json button in the playground.

Then you can add it to our .prettierrc.json file that we have created.

Step 4: Check the format of all files

With the following command, you can examine all the files and find the incompatible ones.

$ npx prettier --check .

My output was as below.

Step 5: Fix the format

First, we saw the files that needed to be fixed. Now we’re going to ask the prettier to fix them.

$ npx prettier --write .

All files have been optimized for prettier.

Step 6: Turn them into npm scripts.

Let’s add the following scripts to package.json.

"prettier": "prettier . --ignore-path .gitignore","format:check": "npm run prettier -- --check","format:fix": "npm run prettier -- --write"

Then run one by one.

$ npm run prettier
$ npm run format:check
$ npm run format:fix

EsLint

EsLint is a very useful tool that finds and fixes errors and is configured according to us.

Install eslint

$ npm install -D eslint

Configure eslint

$ npx eslint --init

You can proceed with the options as follows.

Let’s add the following script to package.json.

"lint": "eslint --ext .tsx,.ts ."

and run

$ npm run lint

Let’s also install the necessary packages for prettier and eslint.

$ npm install -D eslint-config-prettier eslint-plugin-security

Let’s edit our eslint file as follows.

TypeScript

edit tsconfig.json

Add this to the “scripts” in package.json.

"type:check": "tsc"

We should apply this step for type checking.

$ npm run type:check

Validation: Using all three

Install run-p to run the above three scripts in parallel.

$ npm install -D npm-run-all

The package can be used as npm-run-all, run-s, or run-p. We will use run-p for parallel execution.

"validate": "run-p lint type:check format:check"

We have run all the scripts.

Lint staged

Running our validation script in the pre-commit git hook is fine. But should we lint, format, type-check an entire project if the developer only changed a couple of files? Lint staged solves that problem.

$ npx mrm@2 lint-staged

The above command will set up lint-staged using husky’s pre-commit hook.

Create a file lint-staged.config.js as paste the below.

module.exports = {
'*.{ts,tsx}': (filenames) => [
'npm run format:fix',
'npm run validate',
],
}

Let’s test our changes.

$ git add .
$ git commit -m "chore: test lint-staged"

Our output should be like this:

--

--