React boilerplate with Typescript and TDD
Tags: react, typescript, beginners, test
Published: 2022-10-21 11:51:52

TL;DR: Creating a ReactJS application with a boilerplate [react-boilerplate](https://github.com/akshaykamate/react-boilerplate). This post is regarding the tools used to built a good application

## Integration

- ViteJS: a rapid development tool for modern web projects ⚡
- TailwindCSS: CSS framework 💄
- Jest - TDD testing framework 🧪
- Prettier - opinionated code formatter 🥰
- Eslint - identifying problematic patterns found in JavaScript code 📃
- Husky - improves your commits and more 🐶 woof!
- Typescript - a strict syntactical superset of JavaScript 📝

## Manual setup each tool

### ViteJS

[Official Docs get started with Vite](https://vitejs.dev/guide/)

```bash
npm create vite@latest react-boilerplate -- --template react-ts
cd react-boilerplate
npm i
npm run dev # Run the react application
```

### Prettier

Install dependency

```bash
npm i -D prettier
```

Create config file `.prettierrc`

```json
{
 "printWidth": 80,
 "trailingComma": "none",
 "tabWidth": 2,
 "semi": false,
 "singleQuote": true,
 "jsxSingleQuote": true,
 "bracketSameLine": true
}
```

Ignore files to be modified by prettier `.prettierignore`

```text
node_modules
dist
dist-ssr
*.local
.DS_Store
```

### Eslint

Install dependencies

```bash
npm i -D @typescript-eslint/eslint-plugin @typescript-eslint/parser eslint eslint-config-prettier eslint-plugin-import eslint-plugin-jsx-a11y eslint-plugin-prettier eslint-plugin-react eslint-plugin-simple-import-sort
```

Create config file `.eslint.json`

```json
{
  "root": true,
  "parser": "@typescript-eslint/parser",
  "parserOptions": {
    "ecmaVersion": 2020,
    "sourceType": "module",
    "ecmaFeatures": {
      "jsx": true
    }
  },
  "settings": {
    "react": {
      "version": "detect"
    },
    "import/resolver": {
      "node": {
        "paths": ["src"],
        "extensions": [".js", ".jsx", ".ts", ".tsx"]
      }
    }
  },
  "env": {
    "browser": true,
    "amd": true,
    "node": true
  },
  "extends": [
    "eslint:recommended",
    "plugin:@typescript-eslint/recommended",
    "plugin:react/recommended",
    "plugin:jsx-a11y/recommended",
    "plugin:prettier/recommended" // Make sure this is always the last element in the array.
  ],
  "plugins": ["simple-import-sort", "prettier"],
  "rules": {
    "prettier/prettier": ["error", {}, { "usePrettierrc": true }],
    "react/react-in-jsx-scope": "off",
    "jsx-a11y/accessible-emoji": "off",
    "react/prop-types": "off",
    "@typescript-eslint/explicit-function-return-type": "off",
    "simple-import-sort/imports": "error",
    "simple-import-sort/exports": "error",
    "jsx-a11y/anchor-is-valid": [
      "error",
      {
        "components": ["Link"],
        "specialLink": ["hrefLeft", "hrefRight"],
        "aspects": ["invalidHref", "preferButton"]
      }
    ]
  }
}
```

Ignore files to be lint by eslint `.eslintignore`

```text
node_modules
.DS_Store
dist
dist-ssr
*.local
node_modules/*
```

### TailwindCSS

[Official Docs](https://tailwindcss.com/docs/installation)

Install dependencies

```bash
npm install -D tailwindcss postcss autoprefixer
npx tailwindcss init
```

create `postcss.config.cjs`

```js
module.exports = {
  plugins: {
    content: ['./src/**/*.{js,jsx,ts,tsx}'],
    tailwindcss: {},
    autoprefixer: {}
  }
}
```

create config file `tailwind.config.cjs`

```js
/** @type {import('tailwindcss').Config} */
module.exports = {
  content: ['./src/**/*.{js,jsx,ts,tsx}'],
  theme: {
    extend: {}
  },
  plugins: []
}
```

update `src/index.css`

```css
@tailwind base;
@tailwind components;
@tailwind utilities;
```

sample test for tailwindCSS component `src/App.jsx`

```jsx
export default function App() {
  return (
    <div className='flex h-screen'>
      <div className='m-auto'>
        <h1 className='text-5xl'>Welcome to React Boilerplate</h1>
      </div>
    </div>
  )
}
```

### Jest

Install dependencies

```bash
npm i -D @types/jest babel-jest jest jest-environment-jsdom ts-jest
```

create config file `jest.config.cjs`

```js
import type { Config } from 'jest'

const config: Config = {
  verbose: true,
  rootDir: 'src',
  transform: {
    '^.+\\.tsx?$': 'ts-jest'
  },
  moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'],
  testEnvironment: 'jsdom'
}

export default config
```

### Husky

Install dependencies

```bash
npm i -D husky lint-staged
```

create pre commit checks via husky `.husky/pre-commit`

```bash
#!/bin/sh

npx lint-staged
npm test
```

update for linting `package.json`

```json
{
  ...
  "lint-staged": {
    "*.{js,css,md,vue,json,ts,tsx,jsx}": "lint"
  }
}
```

### Miscellaneous

```bash
npm i -D ts-node
```

create an editor config file `.editorconfig`

```yaml
# http://editorconfig.org
root = true
[*]
charset = utf-8
end_of_line = lf
indent_size = 2
indent_style = space
insert_final_newline = true
max_line_length = 80
trim_trailing_whitespace = true
```