# Eslint & Prettier & Stylelint & Husky

## Introduction

* To create the style standard so as to let the code becomes more beautiful
* The dependency is installed when new react project is created

## Eslint

* Install the corresponding dependencies

```bash
npm install eslint-webpack-plugin eslint-config-prettier 
eslint-plugin-prettier eslint-plugin-react 
eslint-plugin-unused-imports babel-eslint @typescript-eslint/eslint-plugin
@typescript-eslint/parser
```

* Install eslint plugin in vsCode  for the hints

![](https://1374779285-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MFW3x2aqEO8GF2kr3VU%2F-MbFyTbRxVrw4YfMg1Dq%2F-MbG-FxTUUmmbfr4Tssh%2Fimage.png?alt=media\&token=e8769713-6abb-487e-8b2b-3b5cc7a7c5be)

* Create eslint config file - .eslintrc.js&#x20;
* React Version

```javascript
// .eslintrc.js
module.exports = {
  parser: "babel-eslint",
  parserOptions: {
    ecmaVersion: 2020,
    ecmaFeatures: { jsx: true },
    sourceType: "module",
  },
  plugins: ["prettier", "unused-imports"],// use plugin
  extends: [
    "react-app",
    "plugin:react/recommended", // as prettier has different set of rule,
    "plugin:prettier/recommended",// we use the recommended set
  ],
  rules: {
    "react/react-in-jsx-scope": "error",  // must include import from react, otherwise show error
    "prettier/prettier": "warn", // styling warning based on prettier
    "react/prop-types": "off", 
    "prefer-const": "warn", // const type is preferred
    "jsx-a11y/anchor-is-valid": "warn",       
    "unused-imports/no-unused-imports": "warn", 
    "unused-imports/no-unused-vars": "warn",
  },
  ignorePatterns: ["generated*"],
};
```

* NextJS + TypeScript Version

```javascript
// .eslintrc.js
module.exports = {
  parser: "@typescript-eslint/parser",
  parserOptions: {
    ecmaVersion: 2020,
    ecmaFeatures: { jsx: true },
    sourceType: "module",
    tsconfigRootDir: __dirname,
    project: "./tsconfig.json",
  },
  plugins: ["prettier", "unused-imports"], // use plugin
  extends: [
    "plugin:react/recommended",
    "plugin:@typescript-eslint/recommended", // as prettier has different set of rule,
    "plugin:prettier/recommended", // we use the recommended set
     "next", 
    "next/core-web-vitals"
  ],
  rules: {
    "prettier/prettier": "warn", // styling warning based on prettier
    "prefer-const": "warn", // const type is preferred
    "jsx-a11y/anchor-is-valid": "off",
    "unused-imports/no-unused-imports": "warn",
    "unused-imports/no-unused-vars": "warn",
  },
  ignorePatterns: ["generated*"],
};

```

## Prettier

* Install the dependency

```javascript
npm install prettier
```

* Create prettierrc file

```javascript
// .prettierrc
{
    "semi": true,
    "printWidth": 80,
    "arrowParens": "always",
    "singleQuote": false,
    "tabWidth": 2,
    "useTabs": false
  }
```

## Stylelint

* Install the dependency

```bash
npm install stylelint stylelint-config-sass-guidelines
yarn add 
```

* Install the plug-in in vsCode for hints

![](https://1374779285-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MFW3x2aqEO8GF2kr3VU%2F-MbFyTbRxVrw4YfMg1Dq%2F-MbG1pCPmzKJimyjEzja%2Fimage.png?alt=media\&token=2170922c-faef-48a8-88be-6d490c0776cf)

* Create stylelint file

```javascript
// .stylelintrc.js
module.exports = {
    "extends": [
        "stylelint-config-standard",
        "stylelint-config-prettier",
        "stylelint-config-sass-guidelines"
    ],
    "plugins": [
        "stylelint-scss",
        "stylelint-order"
    ],
    "rules": {
        "value-keyword-case": null,
        "selector-class-pattern": null,
        "comment-whitespace-inside" : "never",
        "at-rule-semicolon-space-before": null,
        "no-invalid-position-at-import-rule":null,
        "order/properties-alphabetical-order": null, 
        // beautify the bracket
        "block-opening-brace-newline-after":"always-multi-line",
        "block-closing-brace-newline-before": "always-multi-line",
        "declaration-empty-line-before": "never",
        "indentation": "tab",
        "max-empty-lines": 1,
        "function-name-case": null,
        // arrange the css order
        "order/properties-order": [ 
          "position",
          "top",
          "right",
          "bottom",
          "left",
          "z-index",
          "display",
          "justify-content",
          "align-items",
          "float",
          "clear",
          "overflow",
          "overflow-x",
          "overflow-y",
          "padding",
          "padding-top",
          "padding-right",
          "padding-bottom",
          "padding-left",
          "margin",
          "margin-top",
          "margin-right",
          "margin-bottom",
          "margin-left",
          "width",
          "min-width",
          "max-width",
          "height",
          "min-height",
          "max-height",
          "font-size",
          "font-family",
          "text-align",
          "text-justify",
          "text-indent",
          "text-overflow",
          "text-decoration",
          "white-space",
          "color",
          "background",
          "background-position",
          "background-repeat",
          "background-size",
          "background-color",
          "background-clip",
          "border",
          "border-style",
          "border-width",
          "border-color",
          "border-top-style",
          "border-top-width",
          "border-top-color",
          "border-right-style",
          "border-right-width",
          "border-right-color",
          "border-bottom-style",
          "border-bottom-width",
          "border-bottom-color",
          "border-left-style",
          "border-left-width",
          "border-left-color",
          "border-radius",
          "opacity",
          "filter",
          "list-style",
          "outline",
          "visibility",
          "box-shadow",
          "text-shadow",
          "resize",
          "transition"
        ]

    }
}
```

## Husky && Lint-Staged

* To perform the git hook when commit and focus on the commit file
* Update the npm version and install dependencies

```javascript
npm install -g npm@latest
npm install husky lint-staged
```

* Edit the package.json to add prepare script&#x20;

```javascript
 // package.json
 "scripts": {
    // run prepare automatically after npm install
    "prepare": "npx husky",
    "dev": "next dev",
    "watch:style": "postcss ./styles/tailwind.css -o ./styles/output.css  -w",
    "build:style": "postcss ./styles/tailwind.css -o ./styles/output.css --env production ",
    "build": "npm run build:style && next build",
    "start": "next start",
    "lint": "eslint src --ext .ts,.tsx .",
    "lint:style": "npx stylelint --fix src/*.scss"
  },
  // set up the configuration of lint-staged
  "lint-staged":{
    "src/**/*.{ts,tsx}": "eslint --fix",
    "src/**/*.scss": "npx stylelint --fix"
  },
```



* Can also edit the pre-commit setting in .husky/pre-commit file

```javascript
// .husky/pre-commit
npx lint-staged --allow-empty
```

## VS Code

* Close the auto save formatting
* Edit settings.json of vsCode

```javascript
{
    "terminal.integrated.shell.osx": "/bin/bash",
    "editor.codeActionsOnSave": {
        "source.fixAll.eslint": true,
        "source.fixAll.stylelint": true
    }
}
```

* Edit package.json to delete eslint config (default) and add NPM script to fix the styling problem automatically

```javascript
 "scripts": {
    "prepare": "husky install",
    "dev": "next dev",
    "watch:style": "postcss ./styles/tailwind.css -o ./styles/output.css  -w",
    "build:style": "postcss ./styles/tailwind.css -o ./styles/output.css --env prodution ",
    "build": "npm run build:style && next build",
    "start": "next start",
    "lint": "eslint src --ext .ts,.tsx .",
    "lint:style": "npx stylelint --fix src/*.scss"
  },
```

## Reference

{% embed url="https://eslint.org/docs/user-guide/configuring#configuration-file-formats" %}

{% embed url="https://readwriteexercise.com/posts/setting-up-create-react-app-vs-code-eslint-prettier/" %}

{% embed url="https://typicode.github.io/husky/#/" %}

{% embed url="https://stylelint.io/" %}

{% embed url="https://www.npmjs.com/package/lint-staged" %}
