Alura > Cursos de Programação > Cursos de Node.JS > Conteúdos de Node.JS > Primeiras aulas do curso ESLint: padronizando código com regras personalizadas

ESLint: padronizando código com regras personalizadas

ESLINT - Configurando o ESLINT

Trabalhamos em um projeto simples que envolve um arquivo de configuração. Nesse projeto, utilizamos um banco de dados MongoDB e um cache com Redis para cadastrar e listar funcionários.

No entanto, o código atual não segue um padrão, apresentando inconsistências, como: o uso de aspas simples e duplas; variáveis não utilizadas; quebras de linha inadequadas; funções sem padronização de nome; e espaçamentos irregulares. Esses tipos de problema dificultam a leitura e o entendimento do código, especialmente em projetos maiores, sejam pessoais ou corporativos.

Configurando o projeto e padronizando o código

A padronização é essencial em todas as áreas da engenharia, incluindo a engenharia de software.

Em equipes maiores, cada pessoa pode ter seu próprio estilo de escrita, o que resulta em inconsistências no código. Por isso, é importante utilizar uma ferramenta compartilhada que padronize o código. No caso do JavaScript, a ferramenta mais conhecida é o ESLint, que analisa o código e aplica regras para garantir uma escrita padronizada.

Dessa forma, facilitamos o entendimento por todas as pessoas da equipe.

Configurações iniciais

As IDEs, geralmente, possuem algumas configurações pré-definidas. Para melhor compreensão deste curso, recomendamos algumas configurações no VS Code ou na IDE de sua preferência.

Primeiramente, verifique se o ESLint está instalado e ativado; se estiver, desative-o temporariamente, sem desinstalar. O mesmo vale para o Prettier.

Em seguida, abra a paleta de comandos na parte superior do VS Code (no Linux, utilizamos o comando "Ctrl + Shift + P") e acesse as configurações. Após clicar em "Open Settings (UI)" na paleta de comandos, desative a opção Format on Save para evitar que a IDE formate o código automaticamente. Também desative o Default Formatter, caso o Prettier esteja selecionado.

Instalando o ESLint

No arquivo app.js, que não está bem formatado, somos responsáveis por criar padrões, tornando o código mais legível. O primeiro passo é instalar o ESLint. Para isso, executaremos no terminal:

npm init @eslint/config@latest

Dessa forma, acessaremos um questionário com perguntas sobre como desejamos utilizar o ESLint, inicialmente: apenas para checar a sintaxe ou também para procurar problemas? Nesse caso, selecionaremos a segunda opção. Em seguida, responderemos sobre o tipo de módulo usado no projeto (JavaScript ou CommonJS); escolheremos a primeira opção.

Depois, o questionário pergunta sobre o framework utilizado. Como não utilizamos React, Vue ou TypeScript, podemos selecionar "None of these". Por fim, ele perguntará onde o projeto está em execução: se no navegador ou no Node. Basta desativar a opção do navegador e ativar a do Node.

Observação: para ativar e desativar as opções, usamos a tecla "Espaço".

Instalando as dependências necessárias

Após essas configurações, o ESLint indicará algumas dependências necessárias, como eslint, globals e @eslint/js. Ainda no terminal, escolheremos o npm como gerenciador de pacotes e permitiremos que ele faça a instalação.

Observando o arquivo package.json, as dependências foram instaladas como ferramentas de desenvolvimento. Além disso, foi criado o eslint.config.js, que vem com um plugin capaz de identificar alguns erros por padrão.

package.json:

// código omitido

"devDependencies": {
  "@eslint/js": "^9.21.0",
  "eslint": "^9.21.0",
  "globals": "^16.0.0"
}

// código omitido

eslint.config.js:

import globals from "globals";
import pluginJs from "@eslint/js";

/** @type {import('eslint').Linter.Config[]} */
export default [
  {languageOptions: { globals: globals.node }},
  pluginJs.configs.recommended,
];

Verificando os erros identificados

Podemos executar o comando abaixo para verificar o que foi identificado:

npx eslint src/app.js

No nosso caso, há uma variável não utilizada (teste). No entanto, desejamos definir algumas regras que não foram capturadas por padrão com esse plugin.

Adicionando regras ao projeto

Com o arquivo eslint.config.js aberto, vamos criar um objeto ({}) logo abaixo do plugin e adicionar rules, onde passaremos algumas propriedades.

Importante! Todas as propriedades usadas estão na documentação do ESLint. Ao acessar a página de regras, encontramos várias opções, incluindo regras para sugestões e outros tipos de configurações. Tudo que for necessário, especialmente trabalhando com classes, pode ser encontrado na documentação, que também fornece explicações detalhadas.

// código omitido

/** @type {import('eslint').Linter.Config[]} */
export default [
  {languageOptions: { globals: globals.node }},
  pluginJs.configs.recommended,
  {
    rules: {

    },
  },
];

Implementando a regra semi

De volta ao projeto, começaremos a implementar algumas regras.

A primeira é a regra semi, referente ao uso de ponto e vírgula. Vamos configurá-la para ser identificada como erro (error), e para que ponto e vírgula esteja sempre presente (always).

// código omitido

rules: {
  semi: ["error", "always"]
},

// código omitido

Após salvar e executar novamente npm eslint src/app.js, são identificados 26 problemas. Podemos corrigi-los linha por linha, ou utilizar o comando --fix para corrigir automaticamente.

npx eslint src/app.js --fix

Ao executar o comando com --fix, todos os pontos e vírgulas são adicionados ao código de app.js, embora o erro de variável não utilizada ainda persista.

Implementando a regra quotes

Nosso próximo passo será configurar a regra quotes para definir o tipo de aspas a ser utilizado. Cada empresa ou projeto pode ter um padrão diferente.

Neste projeto, optamos por trabalhar com aspas simples (single).

// código omitido

rules: {
  semi: ["error", "always"],
  quotes: ["error", "single"]
},

// código omitido

Executando novamente o --fix, todas as aspas são ajustadas para simples.

npx eslint src/app.js --fix

Implementando a regra indent

Outra configuração que podemos definir é a indentação, com a regra indent. Vamos configurá-la para indicar erro e definir uma indentação de dois espaços.

// código omitido

rules: {
  semi: ["error", "always"],
  quotes: ["error", "single"],
  indent: ["error", 2]
},

// código omitido

Executando sem o --fix, são identificados 15 problemas, sendo 14 de indentação.

npx eslint src/app.js

Após executar com --fix, o código fica melhor formatado.

npx eslint src/app.js --fix

Implementando a regra no-trailing-spaces

Também podemos configurar a regra no-trailing-spaces para evitar espaços após as linhas, que consomem alguns bytes e são considerados um problema.

Nesse caso, iremos configurar para apontar erro caso haja espaços após a linha.

// código omitido

rules: {
  semi: ["error", "always"],
  quotes: ["error", "single"],
  indent: ["error", 2],
  "no-trailing-spaces": "error"
},

// código omitido

Após executar com --fix, todos os espaços desnecessários são removidos.

npx eslint src/app.js --fix

Implementando a regra prefer-const

Por fim, adicionaremos a regra prefer-const, que sugere o uso de const em vez de let ou var quando a variável não será reatribuída.

// código omitido

rules: {
  semi: ["error", "always"],
  quotes: ["error", "single"],
  indent: ["error", 2],
  "no-trailing-spaces": "error",
  "prefer-const": "error"
},

// código omitido

Após executar o comando com --fix no terminal, algumas variáveis são ajustadas, mas outras permanecem, pois o ESLint entende que elas podem ser reatribuídas.

npx eslint src/app.js --fix

Conclusão

No próximo vídeo, iremos explorar outras técnicas para aperfeiçoar ainda mais o padrão do nosso código. Nos encontramos na sequência para dar continuidade ao conteúdo!

ESLINT - Mais configurações para o ESLINT

Neste vídeo, daremos continuidade à implementação de regras no projeto.

Adicionando regras ao projeto

Implementando a regra camelcase

Outra regra de estilo e convenção que podemos aplicar é o uso de camelCase. Temos a variável redisconnection, por exemplo, que não está em camelCase.

Acima dela, como teste, criaremos a const student_names que recebe "Thiago" e "Pedro".

app.js:

// código omitido

const student_names = ["Thiago", "Pedro"];

const redisconnection = async () => {
  // código omitido
};

// código omitido

Em eslint.config.js, podemos criar a regra camelcase recebendo error:

eslint.config.js:

// código omitido

rules: {
  semi: ["error", "always"],
  quotes: ["error", "double"],
  indent: ["error", 2],
  "no-trailing-spaces": "error",
  "prefer-const": "error",
  "no-param-reassign": "error",
  "array-bracket-spacing": ["error", "never"],
  "comma-dangle": ["error", "always-multiline"],
  camelcase: "error"
},

// código omitido

Ao executar o comando npx, identificamos que student_names não está em camelCase. Após recarregar a IDE, o erro é identificado no código.

npx eslint src/app.js

O camelCase funciona apenas para casos de sublinhado. No TypeScript, existem vários plugins que, se configurados corretamente, podem identificar nomes juntos, mas isso é complexo sintaticamente, pois envolve a junção de palavras.

No nosso caso, precisamos ajustar manualmente. Em casos de sublinhado, seja em propriedades ou objetos, ele indicará que não está declarado corretamente.

app.js:

// código omitido

const studentNames = ["Thiago", "Pedro"];

const redisConnection = async () => {
  // código omitido
};

// código omitido

Agora, o erro de camelCase em studentNames não aparece mais. Ao alterar o nome de redisconnection para o correto (redisConnection), haverá uma indicação de que não está condizente em redisClient, mas basta ajustar a chamada.

// código omitido

mongoConnection();
var redisClient = await redisConnection();

// código omitido

Implementando a regra no-var

No momento, ainda utilizamos var para declarar as variáveis do código de app.js, o que não é recomendado. Para corrigir isso, usaremos a regra no-var.

Importante! Sempre que houver dúvidas sobre o nome das regras a serem aplicadas, é possível consultar a página de regras na documentação do ESLint.

No arquivo de configuração, definiremos no-var como error.

eslint.config.js:

// código omitido

rules: {
  semi: ["error", "always"],
  quotes: ["error", "double"],
  indent: ["error", 2],
  "no-trailing-spaces": "error",
  "prefer-const": "error",
  "no-param-reassign": "error",
  "array-bracket-spacing": ["error", "never"],
  "comma-dangle": ["error", "always-multiline"],
  camelcase: "error",
  "no-var": "error"
},

// código omitido

Após salvar, os valores de var são substituídos automaticamente por const, pois ele entende que não há reatribuição de valores. Se houvesse reatribuição, ele preferiria let em vez de const.

Essas são algumas regras básicas que podemos implementar no ESLint.

Implementando a regra import/no-cycle

No próximo tópico, apresentaremos uma série de regras de uso geral, que são boas sugestões para utilização. Algumas regras emitem um aviso quando há console.log(), pois algumas pessoas preferem não usá-lo em projetos.

Por outro lado, existem alguns casos em que será necessário instalar plugins. Por exemplo: vamos pensar no contexto de reconhecer uma dependência circular.

Para isso, podemos implementar a regra import/no-cycle em rules, configurando como error. Se a extensão não identificar, basta executar npx para verificar.

// código omitido

rules: {
  semi: ["error", "always"],
  quotes: ["error", "double"],
  indent: ["error", 2],
  "no-trailing-spaces": "error",
  "prefer-const": "error",
  "no-param-reassign": "error",
  "array-bracket-spacing": ["error", "never"],
  "comma-dangle": ["error", "always-multiline"],
  camelcase: "error",
  "no-var": "error",
  "import/no-cycle": "error",
},

// código omitido
npx eslint src/app.js

Essa configuração é externa e vem de plugins. Podemos adicionar vários plugins ao ESLint para melhorar seu funcionamento. Um dos mais famosos é o do Airbnb, que já vem com várias formatações. No entanto, é importante configurar o melhor para o projeto, em vez de usar configurações prontas, como o plugin mencionado.

Instalando um plugin

Para instalar um plugin, a primeira coisa a fazer é executar npm install eslint-plugin-import --save-dev para instalar a dependência de desenvolvimento.

npm install eslint-plugin-import --save-dev

Após isso, vamos acessar as importações em eslint.config.js. Podemos dar um nome ao import do plugin: usamos pluginJs anteriormente, e agora usaremos pluginImport.

Assim, teremos import pluginImport from "eslint-plugin-import".

eslint.config.js:

import globals from "globals";
import pluginJs from "@eslint/js";
import pluginImport from "eslint-plugin-import";

// código omitido

Acima de rules, finalizamos as opções de linguagem (languageOptions).

Antes disso, há um espaço para abrir um objeto, onde vamos adicionar plugins, abrir e fechar um novo objeto, e passar pluginImport para import.

// código omitido

/** @type {import('eslint').Linter.Config[]} */
export default [
  pluginJs.configs.recommended,
  {
    plugins: {
      import: pluginImport,
    },
    languageOptions: { globals: globals.node },

// código omitido

Após isso, verificamos que o arquivo app.js reclama de uma palavra desconhecida. Podemos executar o comando npx novamente; ao fazer isso, um ciclo de dependência é detectado. Clicando sobre ele, é exibido o import de employeController.

Quando recarregamos a janela, as importações estão sublinhadas em vermelho e é indicada uma dependência circular, que podemos remover manualmente.

Não importamos employeController e não pasamos redisClient como parâmetro. Portanto, não precisamos importar redisClient e podemos apagar essa dependência circular. Ele indicará que redisClient está indefinido, então passaremos por parâmetro.

Dessa forma, não precisamos importar o arquivo app.js.

Trecho a ser removido do arquivo employe.controller.js:

import { redisClient } from "../app.js";

employe.controller.js:

// código omitido

const employeController = (redisClient) => {
  const router = express.Router();

// código omitido

Com isso, nosso projeto está concluído.

Disponibilizaremos uma série de regras do dia a dia para consulta. Para projetos em TypeScript, ele será um plugin para o ESLint, sendo necessário apenas configurar o projeto com um comando diferente, indicando o uso de TypeScript. Deixaremos explicações mais aprofundadas em um guia à parte, pois a configuração após as regras será praticamente a mesma. No arquivo eslint.config.js, começamos com alguns plugins e com a parte de TypeScript configurada. A lógica do Lint será igual, mas podemos adicionar nossas regras para melhor funcionamento.

Conclusão

Concluímos a configuração do ESLint no projeto. Disponibilizaremos outras configurações padrão para uso. No entanto, lembre-se que é importante combinar o ESLint com o Prettier. Se precisar de plugins externos, pesquise e instale.

O ESLint facilita a instalação de plugins e a exportação de configurações. Configurado o plugin, é possível exportar essa configuração para outros projetos.

Em projetos pessoais, normalmente, usamos uma configuração própria do ESLint para manter consistência. Da mesma forma, em uma empresa, é comum usar a mesma configuração do ESLint para todos os projetos, mesmo em projetos grandes com configurações diferentes. Manter um padrão facilita o trabalho em equipe.

Confira as atividades disponibilizadas para aprender a configurar projetos TypeScript. A única diferença é a etapa inicial do processo, com comandos adicionais para instalação e uso em projetos TypeScript. Além disso, deixaremos outras configurações comuns em projetos para consulta.

Em caso de dúvidas, consulte a documentação do ESLint, que possui regras adaptáveis a cada projeto. Projetos orientados a objeto têm regras específicas, assim como projetos funcionais.

Esperamos que tenha aproveitado o conteúdo! Revise as atividades para conhecer configurações extras e executar todos os comandos necessários. Pratique bastante e use o ESLint, mesmo em projetos pessoais e pequenos, seguindo o objetivo de manter um padrão no código.

Nos encontramos em uma próxima oportunidade!

Sobre o curso ESLint: padronizando código com regras personalizadas

O curso ESLint: padronizando código com regras personalizadas possui 24 minutos de vídeos, em um total de 10 atividades. Gostou? Conheça nossos outros cursos de Node.JS em Programação, ou leia nossos artigos de Programação.

Matricule-se e comece a estudar com a gente hoje! Conheça outros tópicos abordados durante o curso:

Aprenda Node.JS acessando integralmente esse e outros cursos, comece hoje!

Conheça os Planos para Empresas