Setup Eslint + Prettier para padronização de código em React

Setup Eslint + Prettier para padronização de código em React

Introdução

Durante o processo de desenvolvimento, torna-se importante a definição de um padrão de projeto visando legibilidade, manutenção e aumento da qualidade de código. Para isso, esse artigo vai trazer duas libs que em conjunto permitem verificar o código na busca/solução de problemas e a formatação dele, dada as regras definidas.

Libs

prettier: é a lib responsável pela formatação de código
eslint: é a lib que vai analisar o código visando a busca e solução de problemas

Setup

Para adicionar o prettier:

yarn add prettier –dev

Para adicionar o eslint:

yarn add eslint@8.57.0 eslint-config-prettier –dev

eslint@8.57.0: vai adicionar a versão 8.57.0 (a mais recente abaixo da 9), dado a alguns problemas relacionados com o plugin de react a partir da versão 9, que estão sendo analisados

eslint-config-prettier: vai desativar as regras do eslint que conflitam com o prettier

Para adicionar os plugins do eslint:

yarn add eslint-plugin-prettier eslint-plugin-react eslint-plugin-react-hooks –dev

eslint-plugin-prettier: vai permitir rodar o prettier em conjunto com o eslint

eslint-plugin-react: vai trazer as regras de linting específicas para aplicações React

eslint-plugin-react-hooks: vai trazer as regras de linting para hooks em React

Para permitir executar o eslint para aplicação React que tem o Babel como compilador:

yarn add @babel/eslint-parser –dev

Após a instalação das libs, adicionar na raiz do projeto o arquivo .eslintrc.json para configurar a execução do eslint. Ele vai ser incrementado aos poucos a medida que vão sendo explicadas as configurações:

env

Traz variáveis globais predefinidas.

“browser”: true: referentes ao browser

“node”: true: referentes ao Node.js

“jest”: true: referentes ao Jest

{
env: {
browser: true,
node: true,
jest: true
},
}

Por exemplo, se tenho uma app que usa Jest para os testes e não defino a env “jest”: true, ao executar o eslint vai ser levantados erros do tipo: describe, it, expect não estão definidos.
Quando coloco a env “jest”: true, ao executar o eslint ele já saberá que são termos usados nos testes e não vai levantar erros por causa deles.

extends

Traz configurações adicionais para o eslint.

eslint:recommended: traz regras recomendadas do eslint

plugin:react/recommended: traz regras recomendadas para react (é possível usar devido a adição do plugin eslint-plugin-react)

plugin:react-hooks/recommended: traz regras recomendadas para hooks em React (é possível usar devido a adição do plugin eslint-plugin-react-hooks)

prettier: remove as regras do eslint que podem conflitar com o prettier (é possível usar devido a adição da lib eslint-config-prettier)

{
//…
extends: [
eslint:recommended,
plugin:react/recommended,
plugin:react-hooks/recommended,
prettier
],
}

parser

@babel/eslint-parser: permite executar o eslint para aplicações que usam o babel como compilador

{
//…
parser: @babel/eslint-parser,
}

parserOptions

ecmaVersion: especifica a ECMAScript syntax usada (latest corresponde a mais recente versão suportada)

sourceType: especifica se a aplicação está usando ESM: module ou se está usando CommonJS: script

ecmaFeatures – “jsx”: true: especifica se inclui syntax jsx

{
//…
parserOptions: {
ecmaVersion: latest,
sourceType: module,
ecmaFeatures: {
jsx: true
}
},
}

plugins

Permite adicionar plugins para extender o eslint, que podem adicionar regras de validação, configurações, envs.

prettier: plugin do prettier

react: plugin do React

react-hooks: plugin de hooks em React

{
//…
plugins: [
prettier,
react,
react-hooks
],
}

settings

react – “version”: “detect”: detecta automaticamente a versão do React da aplicação

{
//…
settings: {
react: {
version: detect
}
},
}

ignorePatterns

Arquivos que serão ignorados quando rodar o eslint.

*.stories.tsx: foi colocado no artigo somente como exemplo, nesse caso o eslint não iria olhar os arquivos que terminam com .stories.tsx

{
//…
ignorePatterns: [*.stories.tsx],
}

rules

Permite adicionar as regras do prettier para serem executadas em conjunto com o eslint:

{
//…
rules: {
prettier/prettier: [error]
}
}

prettier/prettier: adiciona as regras do prettier quando for executado o eslint

error: define que caso alguma regra do prettier não seja satisfeita, retorne erro. Além de error, é possível passar warn que levantaria um warning se alguma regra não fosse satisfeita. Ou off para desativar as regras

Permite customizar as regras do eslint:

{
//…
rules: {
react/jsx-uses-react: off,
react/react-in-jsx-scope: off,
prettier/prettier: [error]
}
}

“react/jsx-uses-react”: “off” e “react/react-in-jsx-scope”: “off”: desativa no eslint a regra que retorna erro se não é colocado o import React from ‘react’ nos arquivos. Bom para versões de React 17 para frente que não tem essa necessidade

Permite customizar as regras do prettier:

{
//…
rules: {
react/jsx-uses-react: off,
react/react-in-jsx-scope: off,
prettier/prettier: [
error,
{
singleQuote: true
}
]
}
}

singleQuote: define como regra de formatação as strings terem aspas simples

Após finalizar a definição do arquivo de configuração, adicionar em package.json os scripts:

scripts: {
//…
lint: eslint .,
lint-files: eslint,
lint-fix: eslint . –fix,
lint-fix-files: eslint –fix,
},

Por default seguindo essa configuração, o eslint vai olhar os arquivos .js. Para verificar outros tipos de arquivos é nos scripts acima adicionar depois de eslint –ext=js,{outro_tipo_de_arquivo}

eslint .: ao rodar yarn lint vai verificar em todos os arquivos se estão de acordo com as regras do eslint e prettier

eslint: ao rodar yarn lint-files {nome_do_arquivo ou nome_da_pasta} vai verificar o arquivo passado ou todos os arquivos da pasta passada, se estão de acordo com as regras do eslint e prettier

eslint . –fix: ao rodar yarn lint-fix vai formatar e corrigir o código seguindo as regras do eslint e prettier

eslint –fix: ao rodar yarn lint-fix-files {nome_do_arquivo ou nome_da_pasta} vai formatar e corrigir o código seguindo as regras do eslint e prettier, para o arquivo ou todos os arquivos da pasta passada

Sugestão: caso sempre é executado para uma pasta específica (por exemplo src), para facilitar pode trocar os . dos scripts para src.

Exemplo

Vamos partir do arquivo de configuração completo definido acima:

{
env: {
browser: true,
node: true,
jest: true
},
extends: [
eslint:recommended,
plugin:react/recommended,
plugin:react-hooks/recommended,
prettier
],
parser: @babel/eslint-parser,
parserOptions: {
ecmaVersion: latest,
sourceType: module,
ecmaFeatures: {
jsx: true
}
},
plugins: [
prettier,
react,
react-hooks
],
settings: {
react: {
version: detect
}
},
ignorePatterns: [*.stories.tsx],
rules: {
react/jsx-uses-react: off,
react/react-in-jsx-scope: off,
prettier/prettier: [
error,
{
singleQuote: true
}
]
}
}

Arquivo de exemplo:

import Component from ./Component;

const Example = () => <p>Eslint article</p>;

export default Example;

Ao executar yarn lint-files para esse arquivo:

Ele retorna 3 erros, 2 do prettier e 1 do eslint, informando que dois são corrigidos pelo –fix:

Primeiro erro: referente a regra do eslint que retorna erro para variável declarada mas não usada no código
Segundo erro: referente a regra customizada definida para usar aspas simples no prettier
Terceiro erro: referente a regra do prettier de espaçamento

Ao executar yarn lint-fix-files para esse arquivo:

Ele corrige dois dos erros que tinha levantado, e continua avisando do que não era auto corrigível. Ficando o arquivo dessa forma:

import Component from ./Component;

const Example = () => <p>Eslint article</p>;

export default Example;

Removendo o import que não é utilizado, não terá mais erros aparecendo na execução do eslint.

Conclusão

A ideia foi trazer as libs necessárias para configuração do eslint com o prettier, focando em como executar eles em conjunto e mostrar onde é possível customizar as regras referentes a ambos. Tentei trazer de forma geral o que representa os elementos do arquivo de config, dependendo da app pode ser que não seja necessário a adição de todos os elementos mostrados acima ou uma pequena alteração em um deles, segue a doc referente a versão 8.57.0 do eslint. No próximo artigo vou focar em trazer regras que são interessantes se customizar tanto para o prettier quanto ao eslint.