Regras customizáveis para Prettier + Eslint em React
Tags: react, eslint, prettier, webdev
Published: 2024-06-24 21:07:36

## Introdução

No [artigo](https://dev.to/griseduardo/setup-eslint-prettier-para-padronizacao-de-codigo-em-react-4029) do mês passado apresentei o setup de Eslint com Prettier para aplicação React, com foco em usar as libs como ferramentas de padronização de código e antecipação de erros. Nesse artigo vou apresentar como fazer a customização das regras e apresentar algumas interessantes a se analisar, mas não sugerindo o uso ou não delas, dado que isso é relativo ao projeto e a definição do time envolvido no desenvolvimento dele.

## Regras

Relembrando a definição usada no artigo passado, dentro do arquivo de configuração do eslint `.eslintrc.json`, definimos para usar as regras recomendadas do eslint, react, react-hooks e usar o prettier em conjunto:

```js
{
  //...
  "extends": [
    "eslint:recommended",
    "plugin:react/recommended",
    "plugin:react-hooks/recommended",
    "prettier"
  ],
  "rules": {
    "prettier/prettier": ["error"]
  }
}
```

Caso o código não esteja de acordo com as regras provenientes dessa configuração, é retornado erro na execução do eslint.

## Customização Prettier

Para customizar as regras, no arquivo do `.eslintrc.json` segue-se a seguinte estrutura:

```js
{
  //...
  "rules": {
    "prettier/prettier": [
      "tipo_de_erro",
      {
        //...
        regra: expectativa_de_regra,
        regra: expectativa_de_regra
      }
    ]
  }
}
```

Em `tipo_de_erro` podem ser definidos dois tipos:

- warn: retorna um aviso se as regras não forem satisfeitas
- error: retorna erro se as regra não forem satisfeitas

Em `regra` é definida a regra que vai ser customizada e em `expectativa_de_regra` o que é esperado que seja satisfeito no código.
  
## Regras Prettier

| Regra | Default | Tipo |
| :---: | :-----: | :--: |
| singleQuote | false | boolean |
| tabWidth | 2 | número |
| printWidth | 80 | número |
| jsxSingleQuote | false | boolean |
| arrowParens | "always" | "always" ou "avoid"

`singleQuote`: define se o projeto vai usar aspas simples, sem considerar jsx (por default está definido como false, ou seja, para usar aspas duplas)
`tabWidth`: define o espaço na indentação
`printWidth`: define o tamanho de linha desejável
`jsxSingleQuote`: define se vai usar aspas simples para jsx (por default está definido como false, ou seja, para usar aspas duplas)
`arrowParens`: define se inclui parenteses para arrow function com um parâmetro (por default definido sempre)

- "always": `(x) => x`
- "avoid": `x => x`
 
Para mostrar como é feita a customização, segue um exemplo de definição no `.eslintrc.json`:

```js
{
  //...
  "rules": {
    "prettier/prettier": [
      "error",
      {
        //...
        "singleQuote": true,
        "jsxSingleQuote": true,
        "arrowParens": "avoid"
      }
    ]
  }
}
```

## Customização Eslint

Para customizar as regras, no arquivo do `.eslintrc.json` segue-se a seguinte estrutura:

```js
{
  //...
  "rules": {
    //...
    regra: tipo_de_erro,
    regra: [tipo_de_erro, expectativa_de_regra]
  }
}
```

Em `tipo_de_erro` podem ser definidos três tipos:

- warn: retorna um aviso se a regra não for satisfeita
- error: retorna erro se a regra não for satisfeita
- off: desabilita a regra

Para o eslint, há duas formas de definição de regras. Para a que só se faz a ativação ou desabilitação, segue-se a estrutura: `regra: tipo_de_erro`. Para regra que corresponde a definição de valor ou algo que não se resume somente a ativar ela, segue-se a estrutura: `regra: [tipo_de_erro, expectativa_de_regra]`, onde em `expectativa_de_regra` é definido o que é esperado que seja satisfeito no código.

## Regras Eslint

| Procedência | Regra | Default |
| :---------: | :---: | :-----: |
| eslint | no-duplicated-imports | desabilitada |
| eslint | no-console | desabilitada |
| eslint | no-nested-ternary | desabilitada |
| eslint | eqeqeq | desabilitada |
| plugin react | react/jsx-uses-react | ativa |
| plugin react | react/react-in-jsx-scope | ativa |
| plugin react | react/jsx-no-useless-fragment | desabilitada |
| plugin react | react/no-array-index-key | desabilitada |
| plugin react | react/destructuring-assignment | desabilitada |
| plugin react-hooks | react-hooks/rules-of-hooks | ativa |
| plugin react-hooks | react-hooks/exhaustive-deps | ativa |

`no-duplicated-imports`: não permite duplicação de chamada de imports provenientes de um mesmo caminho relativo
`no-console`: não permite console.log()
`no-nested-ternary`: não permite nested ternários
`eqeqeq`: define para comparação somente `===` ou `!==`
`react/jsx-uses-react` e `react/react-in-jsx-scope`: define a necessidade de realizar o `import React`, mas para aplicações de React 17+ que não necessitam desse import é interessante desabilitar essas regras
`react/jsx-no-useless-fragment`: não permite fragmentos desnecessários
`react/no-array-index-key`: não permite como chave de array o index
`react/destructuring-assignment`: define o uso de destructuring para props, state e context
`react-hooks/rules-of-hooks`: define o uso das regras de hooks, que inclui por exemplo não colocar hook dentro de condicional (dentre outras que vou colocar o link no final do artigo)
`react-hooks/exhaustive-deps`: define a necessidade de colocar todas as dependências dentro dos hooks

Para mostrar como é feita a customização, segue um exemplo de definição no `.eslintrc.json`:

```js
{
  //...
  "rules": {
    //...
    "no-console": "warn",
    "eqeqeq": "error",
    "react/destructuring-assignement": "error",
    "react/no-array-index-key": "error",
    "react-hooks/exhaustive-deps": "warn"
  }
}
```

## Conclusão

A ideia desse artigo foi trazer como customizar regras com objetivo de definição de padrão de projeto e antecipação de erros em React, apresentando algumas interessantes provenientes do prettier, eslint, plugin react e plugin react-hooks. Porém a quantidade de regras que podem ser customizadas é bem extensa, dado isso irei colocar os links referentes as disponíveis abaixo. Caso achem outras interessantes, se puder coloquem nos comentários para outras pessoas verem mais opções por lá.

## Links

[Prettier](https://prettier.io/docs/en/options.html)
[Eslint](https://eslint.org/docs/v8.x/rules/)
[Plugin react (regras no final do README)](https://github.com/jsx-eslint/eslint-plugin-react?tab=readme-ov-file)
[Plugin react-hooks](https://www.npmjs.com/package/eslint-plugin-react-hooks)
[Regra de hooks](https://react.dev/reference/rules/rules-of-hooks)