Como instalar e configurar o ESlint em um projeto nodejs

Para este tutorial, estou supondo que já possui um projeto escrito em JavaScript, e deseja adicionar o ESlint afim de fazer análise estática do código procurar por errors de sintaxe, erros de lógica a nível de código e verificação de estilo de código.

Então caso já possua o seu projeto em JavaScript, pode fazer essa configuração em seu projeto diretamente seguindo as instruções contidas aqui.

Caso não possua, um projeto você pode utilizar este projeto de exemplo que criei, e continuar seguindo as intruções para fazer a sua configuração. Este projeto é uma prova de conceito apenas para praticar a configuração do ESlint em um projeto que não possui o ESlint configurado. Neste projeto é que vamos configurar o ESlint do zero.

Para utilizar a minha prova de conceito, apenas vá ao repositório e siga as instruções para instalação.

  • Clone o projeto
  • Instale as dependências

Pronto, agora você já possui todos os requisitos para fazer a configuração do ESlint.

Neste tutorial vamos seguir o que orienta a documentação sobre como configurar um projeto, para isso, supondo que está na raiz do projeto que acabou de baixar, basta executar o comando:

  npm init @eslint/config

Após executar este comando, essa será a saída esperada caso dê tudo certo:

Need to install the following packages:
eslint/create-config@0.4.6
Ok to proceed? (y) y

Respondi que sim, e desta forma houve um passo-a-passo no formato de wizard de shell para fazer a configuração do ESlint em meu projeto.

Para isso vá respondendo perguntas de acordo com o estilo e com o problema que o seu aplicativo visa resolver.

Primeira pergunta, como gostaria de utilizar o ESlint?

? How would you like to use ESLint?

Alternativas:

  • Para verificar apenas a sintaxe
  • Para verificar a sintaxe e encontrar problemas
  • Para verificar a sintaxe, encontrar problemas e aplicar estilo de código

Na próxima pergunta temos, que tipo de módulos seu projeto usa?

What type of modules does your project use?

Alternativas:

  • JavaScript modules (import/export)
  • CommonJS (require/exports)
  • Nenhum desses

Próxima, Qual framework seu projeto usa?

Which framework does your project use?

Alternativas:

  • React
  • Vuejs
  • Nenhum

Neste caso selecionamos nenhum, já que o nosso projeto é de backend, e não vamos ter nenhum tipo de framework relacionado à backend.

A seguinte, seu projeto usa TypeScript?

 Does your project use TypeScript?

Aqui é simples, sim ou não.

Logo em seguida, tem a próxima, onde seu projeto roda?

Where does your code run?

Alternativas:

  • Navegador
  • Node

Essa próxima pode ser a última pergunta, como você gostaria de definir um estilo para o seu projeto?

 How would you like to define a style for your project?

Alternativas, aqui temos uma lista de alternativas, que eu sugiro que dê uma pesquisada (se ainda não conhece algum), minha escolha pessoal é o standard ("padrão"), mas veja o que melhor se adequa ao seu projeto. Nas alternativas existem links, então você pode acessar diretamente e descobrir a melhor escolha.

Alternativas:

mais uma, em que formato você deseja que seu arquivo de configuração esteja?

What format do you want your config file to be in?

Neste caso as alternativas são auto-explicativas.

a próxima, ele fez uma verificação pelas minhas escolhas, e verificou que é necessário mais algumas depedências, e perguntou se eu gostaria de instalar. Gostaria de instalá-los agora?

Checking peerDependencies of eslint-config-standard@latest
Local ESLint installation not found.
The config that you've selected requires the following dependencies:
eslint-config-standard@latest eslint@^8.0.1 eslint-plugin-import@^2.25.2 eslint-plugin-n@^15.0.0 || ^16.0.0  eslint-plugin-promise@^6.0.0

Aqui fica a seu critério, eu respondi que não, pois não quero adicionar muitas dependências no projeto, aqui eu prefiro ser conservador e manter o mínimo possível de dependências no meu projeto, e ir instalando conforme necessidade. Mas fique à vontade para instalar as dependências.

Por último, Qual gerenciador de pacotes você usa?

Pronto, agora você já possui o ESlint instalado, e pode executar o lint em qualquer arquivo.

Basta rodar o comando:

npx eslint <seuarquivo>.js

Neste caso o nosso projeto possui apenas um arquivo .js (que é o arquivo app.js), dessa forma vou executar o ESlint apenas nele.

npx eslint app.js

Essa deve ser a saída esperada para o comando acima (supondo que não fez nenhuma mudança nos arquivos fonte da aplicação).

1:35  error  Extra semicolon                                semi
3:22  error  Extra semicolon                                semi
5:1   error  Expected indentation of 2 spaces but found 4   indent
5:50  error  Extra semicolon                                semi
6:3   error  Extra semicolon                                semi
7:38  error  Extra semicolon                                semi
8:17  error  Extra semicolon                                semi
9:63  error  Extra semicolon                                semi
9:64  error  Newline required at end of file but not found  eol-last

Aqui uma exibição simples, uma linha com cada erro que ocorre no arquivo, agora é só corrigir os problemas detectados pelo lint.

Essas verificações no código seguem as regras que estão no arquivo .eslintrc que foi adicionado ao projeto, após a execução do wizard. É nesse arquivo que você pode personalizar as regras que devem ser verificadas ao rodar o comando npx eslint ...

Você pode adicionar novas regras no nó rules, do arquivo .eslintrc , as regras que você pode adicionar podem ser procuradas na documentação.

Para esta aplicação e as configurações atuais, eu ainda desejo adicionar mais algumas regras, segue o conteúdo do meu arquivo (aqui é javascript, então adapte a solução para o seu tipo de arquivo [você escolheu o formato do arquivo durante o wizard]).

module.exports = {
  env: {
    browser: true,
    commonjs: true,
    es2021: true
  },
  extends: 'standard',
  overrides: [
    {
      env: {
        node: true
      },
      files: [
        '.eslintrc.{js,cjs}'
      ],
      parserOptions: {
        sourceType: 'script'
      }
    }
  ],
  parserOptions: {
    ecmaVersion: 'latest'
  },
  rules: {
    'no-console': 2,
        'no-useless-catch': 'off',
        'indent': [
            'error',
            4
        ],
        'linebreak-style': [
            'error',
            ((process.platform === 'win32' || process.platform === 'win64') ? 'windows' : 'unix')
        ],
        'quotes': [
            'warn',
            'single',
        ],
        'semi': [
            'error',
            'always'
        ],
        'eol-last': [
            'error',
            'always'
        ]
  }
}

Agora, após selecionar suas regras de lint para o seu projeto, você pode criar um novo comando em seu módulo, para se encarregar desta tarefa de verificar o lint. A vantagem de ter o script é pra facilitar as tarefas de automação de esteira de CI/CD além de manter mais organizado a execução das tarefas através do uso de uma unica ferramenta para centralizar o uso, nesse caso o npm. Então edite o seu arquivo para  package.json. Fazer essa configuração é melhor para um caso de uso de projetos de mundo real.

Em geral, os meus arquivos de implementação do server (aplicativo express/node) ficam organizados no server então eu crio o meu padrão de verificação de arquivos em pastas da seguinte forma:

***package.json***

{
  "name": "eslintconfiguration",
  "version": "1.0.0",
  "description": "",
  "main": "app.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "start": "node app.js",
    "dev": "node --watch app.js",
    "lint": "npx eslint server/**/*.js server/*.js lib/*.js app.js",
  },
  "repository": {
    "type": "git",
    "url": "git+ssh://git@github.com/danizavtz/eslintconfiguration.git"
  },
  "keywords": [
    "nodejs"
  ],
  "author": "danizavtz",
  "license": "ISC",
  "bugs": {
    "url": "https://github.com/danizavtz/eslintconfiguration/issues"
  },
  "homepage": "https://github.com/danizavtz/eslintconfiguration#readme",
  "dependencies": {
    "express": "^4.18.2"
  },
  "devDependencies": {
    "eslint": "^8.56.0"
  }
}

Em destaque a linha que adicionei na seção scripts do meu arquivo package.json.

"lint": "npx eslint server/**/*.js server/*.js lib/*.js app.js",

Nesse caso todas as vezes que eu executar o comando npm run lint serão verificados com o ESlint:

  • todos arquivos com extensão .js que estão nos subdiretórios que estão na pasta server .
  • todos os arquivos com extensão .js que estão no diretório server.
  • todos os arquivos com extensão .js que estão no diretório lib.
  • o arquivo app.js

A vantagem de fazer uma configuração assim é que automaticamente, se forem adicionados novos arquivos em qualquer um desses diretórios, eles serão verificados pelas regras descritas acima. Essa é apenas uma ideia de como organizar então você pode adaptar para o seu projeto.

Agora é só corrigir os problemas de lint ;-)