DEV Community

Vinodh Kumar
Vinodh Kumar

Posted on • Edited on

Create a react app using Vite - Part 1

Introduction

The 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 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.

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
corepack enable
corepack prepare pnpm@latest --activate
Enter fullscreen mode Exit fullscreen mode
  • 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.

pnpm create vite react-app-v2 --template react-ts

  pnpm create vite <app-name> --template react-ts
  cd <app-name>
  pnpm install && pnpm update
Enter fullscreen mode Exit fullscreen mode

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.
  git init
  echo -e "node_modules\ncoverage" > .gitignore
  npm pkg set engines.node=">=20.11.0" // Use the same node version you installed
Enter fullscreen mode Exit fullscreen mode
  • Specify the latest PNPM version to use for this project by setting the packageManager property in the package.json file.
  npm pkg set packageManager="pnpm@9.12.3"
  pnpm -v
Enter fullscreen mode Exit fullscreen mode

Code formatter

I'm going with Prettier 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.

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

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.

mkdir .vscode && touch .vscode/settings.json
Enter fullscreen mode Exit fullscreen mode
{
  "editor.formatOnSave": true,
  "editor.defaultFormatter": "esbenp.prettier-vscode",
  "files.associations": { "*.svg": "html" },
  "[html]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  }
}
Enter fullscreen mode Exit fullscreen mode
  • 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.

The vite starter template recommends few improvements to the linter for production app in the Readme file so lets add that as well.

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

  pnpm add -D eslint-plugin-react eslint-plugin-jsx-a11y
Enter fullscreen mode Exit fullscreen mode
  • The updated linter configuration will look something like this,
import js from '@eslint/js'
import globals from 'globals'
import reactHooks from 'eslint-plugin-react-hooks'
import reactRefresh from 'eslint-plugin-react-refresh'
import tseslint from 'typescript-eslint'
import react from 'eslint-plugin-react'
import jsxA11y from 'eslint-plugin-jsx-a11y'

export default tseslint.config(
  { ignores: ['coverage', 'public', 'dist', 'pnpm-lock.yaml'] },
  {
    extends: [js.configs.recommended, ...tseslint.configs.recommended],
    files: ['**/*.{ts,tsx}'],
    languageOptions: {
      parserOptions: {
        ecmaFeatures: { jsx: true },
        project: ['./tsconfig.node.json', './tsconfig.app.json'],
        tsconfigRootDir: import.meta.dirname,
      },
      ecmaVersion: 2020,
      globals: globals.browser,
    },
    plugins: {
      'jsx-a11y': jsxA11y,
      react,
      'react-hooks': reactHooks,
      'react-refresh': reactRefresh,
    },
    rules: {
      ...reactHooks.configs.recommended.rules,
      ...react.configs.recommended.rules,
      ...react.configs['jsx-runtime'].rules,
      'react/react-in-jsx-scope': 'off',
      'react-refresh/only-export-components': ['warn', { allowConstantExport: true }],
    },
    settings: { react: { version: 'detect' } },
  }
)
Enter fullscreen mode Exit fullscreen mode

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
  pnpm add -D eslint-config-prettier eslint-plugin-prettier
Enter fullscreen mode Exit fullscreen mode
  • Add the eslintPluginPrettierRecommended as the last element in the array.
import eslintPluginPrettierRecommended from 'eslint-plugin-prettier/recommended'

/** @type {import('eslint').Linter.Config[]} */
export default [
  ...,
  {
    extends: [
      js.configs.recommended,
      ...tseslint.configs.recommended,
      eslintPluginPrettierRecommended,
    ],
    ...
  }
]
Enter fullscreen mode Exit fullscreen mode

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.
  npm pkg set scripts.lint="eslint ."
  npm pkg set scripts.format="prettier --write ."
Enter fullscreen mode Exit fullscreen mode
  • 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

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 and 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,
  pnpm add -D @commitlint/cli @commitlint/config-conventional
  echo -e "export default { extends: ['@commitlint/config-conventional'] };" > commitlint.config.mjs
  pnpm add -D husky lint-staged
  pnpm exec husky init
  echo "pnpm lint-staged" > .husky/pre-commit
  echo "npx --no -- commitlint --edit \${1}" > .husky/commit-msg
Enter fullscreen mode Exit fullscreen mode
  • 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.
  "lint-staged": {
    "**/*.{js,ts,jsx,tsx}": [
      "eslint --fix"
    ],
    "**/*": "prettier --write --ignore-unknown"
  },
Enter fullscreen mode Exit fullscreen mode

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
 pnpm add -D @types/node
Enter fullscreen mode Exit fullscreen mode
  • Open the vite.config.ts file and update it like this,
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/') } },
})
Enter fullscreen mode Exit fullscreen mode
  • Update the tsconfig.json file with the baseUrl for the imports to work in the editor.
{
  "compilerOptions": {
    "baseUrl": "./",
    ....
  }
}
Enter fullscreen mode Exit fullscreen mode
  • The resolve property helps us to use absolute import paths instead of relative. For ex:
import { add } from 'src/utils/arithmetic'
import { App } from 'src/components/app'
Enter fullscreen mode Exit fullscreen mode

App code cleanup:

  • Update the App.tsx with the following content,
export const App = () => {
  return <div className="font-semibold text-lg text-green-500">Rendered from react app</div>
}
Enter fullscreen mode Exit fullscreen mode
  • Delete the App.css file
  rm -rf src/App.css
Enter fullscreen mode Exit fullscreen mode
  • Update the Import in the src/main.tsx file
  - import App from "./App";
  + import { App } from "./app";
Enter fullscreen mode Exit fullscreen mode
  • Run the app and you will see the content in the app.tsx with tailwind classes applied.
  pnpm dev
Enter fullscreen mode Exit fullscreen mode

Next part

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

Top comments (0)