Create a react app using Vite - Part 1
Tags: react, vite, typescript, javascript
Published: 2023-08-15 04:56:56

## Introduction

The [create-react-app](https://github.com/facebook/create-react-app) is the go-to approach to quickly set up a react application for a long time. But with the introduction of [Vite](https://vitejs.dev/) bundler, things have changed dramatically. With the right set of tools, you will see how much easier and super fast your React app can be built. The developer experience with this is pure bliss compared to the create react app(CRA) because of the following reasons,

- CRA abstracts a lot of technologies or tools that are used to deliver the final bundle so as a developer you will have a limited understanding of what is happening under the hood, which is kind of a bummer for your career.
- It uses a lot of popular third-party packages internally that are not exposed to the outside world which makes it difficult to customise.
- It may not support all the latest libraries or tools that you intend to use.

## Objective

The main objective of this article is to get your hands dirty and understand what it takes to build a simple hello-world application from scratch.

## Technologies/Features used

The app we are going to build will have the following features. Again this is my set of tools feel free to change it based on your preference.

| Feature                   | Technology used |
| ------------------------- | --------------- |
| Package manager           | PNPM            |
| Package bundler           | Vite            |
| Programming language      | Typescript      |
| JS Framework/library      | React           |
| CSS library               | TailwindCss     |
| Basic linting             | ESLint          |
| Code formatting           | Prettier        |
| Pre-commit hook validator | Husky           |
| Linting only staged files | lint-staged     |
| Lint git commit subject   | commitlint      |

## Prerequisites

### Tools

You will need the following things properly installed on your computer.

- [Git](http://git-scm.com/downloads)
- [Node.js](http://nodejs.org/)

### PNPM install

- If you have installed the latest v16.x or greater node version in your system, then enable the pnpm using the below cmd

```bash
corepack enable
corepack prepare pnpm@latest --activate
```

- If you are using a lower version of the node in your local system then check this page for additional installation methods https://pnpm.io/installation

## App creation

- Let's create our app by running these commands.

```bash
  pnpm create vite <app-name> --template react-ts
  cd <app-name>
  pnpm install && pnpm update
```

That's it, your app is ready. Run `pnpm dev` and check out your app.

- Initialize git if you want and enforce the node version with some info in the README.md.

```bash
  git init
  npm pkg set engines.node=">=18.16.1" // Use the same node version you installed
  echo "#React app" > README.md
```

## Code formatter

I'm going with [Prettier](https://prettier.io/) to format the code. Formatting helps us to keep our code uniform for every developer.

### Installation

Let's install the plugin and set some defaults. Here I'm setting the single quote to be true, update it according to your preference.

```bash
  pnpm add -D prettier
  echo '{\n  "singleQuote": true\n}' > .prettierrc.json
  echo -e "coverage\npublic\ndist\npnpm-lock.yaml" > .prettierignore
```

### VS Code plugin

- If you are using VS Code, then navigate to the `Extensions` and search for `Prettier - Code formatter` and install the extension.

Extension link: https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode

- Let's update the workspace to use the prettier as the default formatter and automatically format the file on save.

- Create the workspace settings JSON and update it with the following content.

```bash
mkdir .vscode && touch .vscode/settings.json
```

```json
{
  "editor.formatOnSave": true,
  "editor.defaultFormatter": "esbenp.prettier-vscode",
  "files.associations": { "*.svg": "html" },
  "[html]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  }
}
```

- Now open the `src/App.tsx` in your VSCode editor and save it. If the semicolons are automatically created then it confirms that our auto formatting is working fine.

## Linting

Vite `react-ts` template comes with a built-in ESLint setup which covers the plugins for react and typescript support.

Let's add a few more plugins to keep our linting strong.

### eslint-plugin-react

For some reason, the Vite react-ts template did not add this [eslint-plugin-react](https://www.npmjs.com/package/eslint-plugin-react) but I feel it's pretty useful so let's add that as well.

```bash
  pnpm add -D eslint-plugin-react
```

- Add the plugin to the ESLint config file with some basic configs.

```
  extends: [..., 'plugin:react/recommended'],
  rules: {
  ...,
  'react/react-in-jsx-scope': 'off',
  },
  settings: { react: { version: 'detect' } },
```

### Accessibility linter

Accessibility linter will make sure all the HTML elements have the necessary aria rules to improve the accessibility of your app.

- Install the [eslint-plugin-jsx-a11y](https://www.npmjs.com/package/eslint-plugin-jsx-a11y)

```bash
  pnpm add -D eslint-plugin-jsx-a11y
```

- Add the plugin to the eslint config file.

```
  extends: [..., 'plugin:jsx-a11y/recommended'],
  plugins: [..., 'jsx-a11y'],
```

### Integrating Prettier with ESLint

Linters usually contain not only code quality rules but also stylistic rules. Most stylistic rules are unnecessary when using Prettier, but worse – they might conflict with Prettier!

We are going to use Prettier for code formatting concerns, and linters for code-quality concerns. So let's make the linter to run the stylistic rules from prettier instead.

- Install the necessary plugins

```bash
  pnpm add -D eslint-config-prettier eslint-plugin-prettier
```

- Add the `plugin:prettier/recommended` as the **last element** in the extends property in eslintrc.js

```js
module.exports = {
  extends: [..., 'plugin:prettier/recommended'],
}
```

For more info on this: https://prettier.io/docs/en/integrating-with-linters.html

- Let's create scripts for running the linter and prettier in the package.json file.

```bash
  npm pkg set scripts.lint="eslint ."
  npm pkg set scripts.format="prettier --write ."
```

- Update the `eslintignore` file

```bash
  echo -e "coverage\npublic\ndist\npnpm-lock.yaml" > .eslintignore
```

- Run the `pnpm lint` cmd to run the ESLint. If it throws, errors like below then our linter prettier integration is working as expected.

![Image Description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/o7hodob3ln1pm9a6y9bo.png)

To fix it just run `pnpm format` cmd and run the `pnpm lint --fix` cmd again. Now the errors should be gone.

## Pre-commit hook validation

Even if we added all these linter and formatter mechanisms to maintain the code quality, we can't expect all the developers to use the same editor and execute the `lint` and `format` command whenever they are pushing their code.

To automate that we need some kind of pre-commit hook validation. That's where [husky](https://typicode.github.io/husky/) and [lint-staged](https://www.npmjs.com/package/lint-staged) plugins come in handy let's install and set them up.

- Install the husky, commitlint, and lint-staged NPM package and initialize it as shown below,

```bash
  pnpm add -D @commitlint/cli @commitlint/config-conventional
  echo -e "export default { extends: ['@commitlint/config-conventional'] };" > commitlint.config.js
  pnpm add -D husky lint-staged
  npx husky install
  npx husky add .husky/pre-commit "pnpm lint-staged"
  npx husky add .husky/commit-msg  'npx --no -- commitlint --edit ${1}'
  npm pkg set scripts.prepare="husky install"
```

- Update the package.json file and include the following property. This will run the ESLint on all the script files and prettier on the other files.

```json
  "lint-staged": {
    "**/*.{js,ts,tsx}": [
      "eslint --fix"
    ],
    "**/*": "prettier --write --ignore-unknown"
  },
```

## Absolute path import support

We often move around the files to make it more meaningful, when we are doing that, it would be great if we don't have to update the import statements. To do that,

- Install the @types/node NPM package

```bash
 pnpm add -D @types/node
```

- Open the vite.config.ts file and update it like this,

```js
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import { resolve } from 'path'

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [react()],
  resolve: { alias: { src: resolve('src/') } },
})
```

The `resolve` property helps us to use absolute import paths instead of relative. For ex:

```javascript
import { add } from 'src/utils/arithmetic'
import { App } from 'src/components/app'
```

## App code cleanup:

- Rename the `App.tsx` to `app.tsx` and add the following content,

```js
export const App = () => {
  return <div className="font-semibold text-lg text-green-500">Rendered from react app</div>
}
```

- Delete the App.css file

```bash
  rm -rf src/App.css
```

- Update the Import in the `src/main.tsx` file

```js
  - import App from "./App";
  + import { App } from "./app";
```

- Run the app and you will see the content in the `app.tsx` with tailwind classes applied.

```bash
  pnpm dev
```

### Next part

In the next part of this series, we will see how to add styling support and image rendering using SVG.