/react-proj-template

react + ts + eslint + prettier + husky + vite

Primary LanguageTypeScript

React Project Template

Init project steps

  1. choose vite to create proj
$ pnpm create vite
  1. init eslint
$ pnpm create @eslint/config
// package.json
"lint": "eslint --ext .js,.jsx,.ts,.tsx --fix --quiet ./"
// .exlintrc.cjs
module.exports = {
    "env": {
        "browser": true,
        "es2021": true
    },
    "extends": [
        "eslint:recommended",
        "plugin:react/recommended",
        "plugin:@typescript-eslint/recommended"
    ],
    "overrides": [
    ],
		// set react version for eslint
    "settings": {
      "react": {
          "version": "detect"
      }
    },
    "parser": "@typescript-eslint/parser",
    "parserOptions": {
				// Enable JSX support
        "ecmaFeatures": {
            "jsx": true
        },
        "ecmaVersion": "latest",
        "sourceType": "module"
    },
    "plugins": [
        "react",
        "@typescript-eslint"
    ],
    "rules": {
				// New JSX Transform rules
        "react/jsx-uses-react": "off",
        "react/react-in-jsx-scope": "off"
    }
}
  1. integrate eslint with your IDE (WebStrom)

Preferences | Languages & Frameworks | JavaScript | Code Quality Tools | ESLint

if find the problem TypeError: this.libOptions.parse is not a function, update Webstorm or downgrade eslint@8.22.0

if find the problem ESLint: 'React' must be in scope when using JSX(react/react-in-jsx-scope), disable rules react/jsx-in-jsx-scope, more details

  1. install prettier
$ pnpm add prettier -D
// .prettierrc.cjs
module.exports = {
    printWidth: 80,
    tabWidth: 4,
    useTabs: false,
    singleQuote: true,
    semi: false,
    trailingComma: "none",
    bracketSpacing: true
}
  1. integrate prettier with your IDE (WebStrom)

Preferences | Languages & Frameworks | JavaScript | Prettier

  1. integrate prettier and eslint
$ pnpm add eslint-config-prettier eslint-plugin-prettier -D
// .eslintrc.cjs
module.exports = {
    //...
    "extends": [
        //...
        "plugin:prettier/recommended"
    ],
    //...
    "plugins": [
        //...
        "prettier"
    ],
    "rules": {
        "prettier/prettier": "error",
        //...
    }
}
  1. integrate vite and eslint
$ pnpm add vite-plugin-eslint -D
//...
import viteEslint from 'vite-plugin-eslint'

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [
    //...
    viteEslint({
      failOnError: false
    })
  ]
})
  1. install huksy
$ pnpm add husky -D
$ npm pkg set scripts.prepare="husky install"
$ npm run prepare
$ npx husky add .husky/pre-commit "pnpm run lint"
$ npx husky add .husky/pre-push "pnpm run test"

make sure set husky folder as executable file

  1. integrate lint-staged and husky
$ pnpm add lint-staged -D

modified .husky/pre-commit from pnpm run lint to npx lint-staged

// package.json
{
	//..
	"lint-staged": {
		"*.{js,jsx,ts,tsx}": [
			"npm run lint"
		]
	},
	//..
}
  1. install commitlint
$ pnpm add @commitlint/cli @commitlint/config-conventional -D
// .commitlintrc.cjs
module.exports = {
	extends: ["@commitlint/config-conventional"]
}
  1. integrate commitlint and husky
$ npx husky add .husky/commit-msg "npx --no-install commitlint -e $HUSKY_GIT_PARAMS"
  1. support less, css-module and integrate stylelint and husky
$ pnpm add less postcss postcss-less stylelint stylelint-config-css-modules stylelint-config-standard -D
{
    //..
    "script": {
        //..
        "lint:css": "stylelint src/**/*.less --fix --cache --custom-syntax postcss-less"
    },
    "lint-staged": {
      //..
      "*.{css,less}": [
        "pnpm run lint:css"
      ]
    },
    //..
}
// .stylelintrc.cjs
module.exports = {
    extends: [
        'stylelint-config-standard',
        'stylelint-config-css-modules'
    ]
}

Init test steps

  1. install vitest and @tesing-library
$ pnpm add vitest @testing-library/dom @testing-library/jest-dom @testing-library/react jsdom -D
  1. add setup file for @tesing-library
// setup.ts
import '@testing-library/dom'
import matchers from '@testing-library/jest-dom/matchers'
import { expect } from 'vitest'

expect.extend(matchers)
  1. add vitest config in vite.config.ts
/// <reference types="vitest" />
/// <reference types="vite/client" />

import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import viteEslint from 'vite-plugin-eslint'

// https://vitejs.dev/config/
export default defineConfig({
  test: {
    globals: true,
    environment: 'jsdom',
    setupFiles: './tests/setup.ts',
    css: true
  },
  //..
})
  1. add test script
// package.json
{
  "script": {
    //..
    "test": "vitest -w=false",
    "test:coverage": "vitest run --coverage",
    //..
  }
}