Node.js + Express + ES6 + ESLint + Sucrase Prettier de forma simples e rápida

Neste post demonstrarei como é simples iniciar um projeto sobre a plataforma Node.js, agregando a esta: ferramentas, técnicas e abordagens voltadas a garantir a qualidade do código.

Pessoalmente gosto bastante da combinação citada no título deste post. Em parte, isso se deve ao fato dela me proporciona um start simples e rápido de novos projetos. Observe que dei preferência a utilizar o Express como alvo da demonstração, porém, os conceitos e técnicas aqui exploradas se aplicariam facilmente a qualquer outro framework/lib ou script alone, em muitos casos sem a necessidade de qualquer ajuste.

Livros

Em meu repositório no GitHub você encontrará link para download de alguns livros publicados por mim, bem como poderá acompanhar o desenvolvimento das obras mais recentes, tais como o livro de Node.js para iniciantes. Acesse: https://github.com/fabiojaniolima/livros

ESLint vs Prettier

Sem dúvida essa dupla de peso merece nossa atenção, vai por mim. No passado já as ignorei, porém, quando resolvi abraçar a causa, ganhei muito em termos de produtividade e padronização do estilo de código. Não as negligencie como assim o fiz no passado.

Não se deixe enganar pelo título deste post, a premissa de rivalidade entre essas duas ferramentas é falsa, porém, este título representa uma dúvida comum entre iniciantes e veteranos do mundo "underground" dos desenvolvedores. ESLint e Prettier são ferramentas que se complementam com o intuito de agregar maior qualidade ao código.

ESLint

Este é o linter mais famoso do mundo JavaScript e tudo indica que será do TypeScript também. Essa ferramenta faz a analise estática do código de modo a identificar quebras de estilização e erros que poderiam levar sua aplicação a uma falha em tempo de execução.

Por exemplo, antes mesmo de executarmos nosso código, o ESlint pode nos alertar que estamos utilizando uma variável que nunca foi declarada, que estamos tentando sobrescrever o valor de uma constante ou até mesmo que estamos tentando utilizar um método inválido no contexto do objeto.

Prettier

Está é uma ferramenta voltada a formatação e estilização do código. Sabe aquelas discussões de fanáticos de ponto e vírgula, aspas duplas ou simples? Pois bem, seus problemas acabaram! O Prettier é o formatador que todos precisávamos, ele cuida de manter a consistência estética do nosso código, obviamente somos livres para customizar o que bem entendermos, mas o ponto chave aqui não é qual estilo iremos seguir, mas sim manter a consistência do estilo definido de modo a evitar aqueles códigos "mutantes".

Propósitos diferentes que se complementam

O ESLint e o Prettier se complementam de modo a enriquecer a qualidade do código. Acredito que você já tenha criado uma linha de raciocínio que converge para este fato. Porém, antes de concluirmos este tópico, vamos à algumas duvidas remanescentes que podem ter surgido:

O ESLint também consegue identificar quebra de estilos. Então não preciso do Prettier, correto?

Não diria que está nem certo nem errado. Como foi esclarecido nos tópicos anteriores, cada qual tem um propósito diferente. Vamos imaginar assim, um Jipe e uma Ferrari, ambos podem nos atender da mesma forma em diferentes momentos, mas você não vai de Ferrari para o Rally dos Sertões, não é mesmo!

Em resumo, ESLint tem a capacidade de forçar o padrão de formatação em alguns aspectos, porém, como este não é o propósito primordial dele, o Prettier é mais recomendado segundo a humilde opinião da minha pessoa.

Instalar o ESLint e o Prettier não vai gerar conflito? Tipo, o ESLint definir que deve usar aspas duplas e o Prettier que às aspas devem ser simples?

Isso vai depender de como você configura as coisas. Ao seguir este post você não corre o risco de ter este problema. Iremos utilizar dois plugins que possuem a finalidade de evitar este comportamento, sendo eles eslint-config-prettier, que tem por finalidade desativar regras do ESLint que podem gerar conflitos com o Prettier, e eslint-plugin-prettier que passa para o Prettier a gestão das regras de formatação estética.

Então devo configurar as regras de formatação estética somente no Prettier?

Eu diria que será o mais recomendado! O Prettier é o mais indicado para este trabalho, além disso, fica mais simples gerenciar um único arquivo de configuração, evitando ainda a armadilha de configurarmos regras em dois locais distintos que podem acabar gerando divergências entre si.

Resumindo: o ESLint deve cuidar de fatores ligados a sintaxe e recomendações de uso, tais como, aplicar funções de retorno em getters, proibir condições duplicadas em cadeias if-else-if... Já no Prettier, centralize tudo que for ligado a estética, como padrão das aspas (simples ou dupla), final de linha com ou sem ponto-e-virgula e assim por diante.

Chega de papo, vamos por a mão na massa!

Pré-requisitos

  • Node.js
  • NPM ou Yarn
  • VSCode*

Ao longo deste post irei utilizar o Yarn como gerenciador de dependências, fique livre para utilizar o NPM se assim preferir. Já como editor de código, utilizarei o VSCode, porém, você é livre para utilizar o sabor de editor que preferir.

Passos

  • Primeiramente devemos:
Crie um diretório; e
Acesse este diretório
  • Para criar um novo projeto basta executar:
yarn init -y
  • init: essa instrução instrui o yarn a criar um arquivo Package.json, responsável por guardar algumas definições iniciais do projeto e a lista de dependências;
  • -y: ativa confirmação silenciosa, ou seja, preencher todas as perguntas com a resposta padrão, deste modo não seremos questionados quanto as escolhas durante o processo de criação.

Agora iremos instalar nossas primeiras dependências de produção:

yarn add express cors dotenv
  • express: micro-framework simples e flexível;
  • cors (cross-origin): é uma especificação que define meios para que um recurso do servidor seja acessado remotamente via web/rede; Resumidamente, o cors permite que nossa aplicação seja acessada de um endereço externo;
  • dotenv: é um módulo de dependência zero, responsável por carregar variáveis de ambiente de um arquivo .env em process.env.*.

Agora iremos adicionar as dependências de desenvolvimento do nosso projeto:

yarn add eslint prettier eslint-config-prettier eslint-plugin-prettier sucrase nodemon -D

Obs: lembre-se de que além de instalar o ESLint via NPM ou Yarn, é necessário acessar a "marketplace" do seu editor de código, seja ele VSCode, WebStorm, Sublame Text entre outros, e instalar o plugin do ESLint para o editor de código ou IDE que você está utilizando. Consulte as instruções do seu editor/IDE para verificar como instalar plugins. Caso não faça isso, provavelmente não terá o recurso de linting integrado ao editor/IDE, mas ainda poderá fazer uso via "Command Line Interface", conforme veremos mais adiante neste post.

  • eslint: utilizado para análise de código estático e identificação de padrões problemáticos presentes no código;
  • sucrase: responsável por fazer a transpilação do código, ou seja, traduzir as especificações mais recentes da linguagem, que ainda não são nativamente suportadas pelo Node.js para um padrão que o mesmo já suporte. Essa ferramenta é altamente recomendada para ambiente de desenvolvimento devido a sua abordagem de transpilação, porém, não é adequada para um ambiente de produção;
  • nodemon: monitora o diretório e realiza restart automático do server sempre que um arquivo for alterado;
  • prettier: formata o código de modo a manter um padrão estético, os plugins eslint-config-prettier e eslint-plugin-prettier cuidam de fazer a integração entre o ESLint e o Prettier (assunto já abordado no inicio deste post), de modo a promover correções automáticas no código sempre que o ESLint apontar uma erro, obviamente você pode incluir regras personalizadas ou ignorar as predefinidas que não te atenderem.

Feito isso, vamos configurar o ESLint. A instrução abaixo irá realizar o download de algumas outras dependências de desenvolvimento e gerar o arquivo de configuração .eslintrc.* (a extensão final pode ser js, json ou yml, veremos isso mais adiante):

yarn eslint --init

Segue abaixo o fluxo de perguntas emitidas pelo ESLint para geração do arquivo .eslintrc, sendo assim, reproduza estas conforme as imagens apresentadas.

Selecione a opção To check syntax and find problems com o uso das setas e pressione ENTER:

Imagem 1: define como o ESLint irá funcionar, verificando a sintaxe e rastreando problemas.

Obs: dependendo do que você selecionar na etapa acima, os passos seguintes podem mudar um pouco. Por exemplo, ao selecionar a ultima opção, você terá passos adicionais para determinar qual será o padrão de estilização a ser considerado. Pessoalmente gosto de seguir o JavaScript Standard Style, padrão seguido pelo Prettier, sendo assim, não necessito que o ESLint force um estilo de código…

Agora selecione a primeira opção e pressione ENTER:

Imagem 2: define como será feito o import/export de módulos.

Obs: no momento em que escrevo este código o import/export não é suportado pelo Node.js, foi justamente por isso que instalamos o sucrase, ele vai se encarregar de transpilar estas e outras features que porventura ainda não são suportadas nativamente.

Como não estamos utilizando nem React nem Vue.js, selecione a última opção e pressione ENTER:

Imagem 3: especifica que não serão utilizados frameworks.

Como neste projeto não iremos utilizar TypeScript, pressione ENTER, essa ação irá considerar a opção default, neste caso N:

imagem 4: questiona se iremos utilizar TypeScript

Utilize a tecla <i> para inverter a seleção de Browser para Node, então pressione ENTER para continuar:

Imagem 5: define que o código irá rodar sobre o Node, ou seja, no back-end.

Neste momento iremos escolher o formato do arquivo que irá guardar as configurações do ESLint, este arquivo se chama eslintrc.*, pessoalmente prefiro utilizar o formato JSON (exceto em casos específicos). Selecione conforme imagem abaixo e pressione ENTER:

Imagem 6: especifica que o arquivo de configurações do ESLint seguirá o formado JSON.

A instalação terminou. Agora vamos as configurações…

Edite o arquivo .eslintrc.json, seu conteúdo original deve se parecer com:

{
"env": {
"es2021": true,
"node": true
},
"extends": "eslint:recommended",
"parserOptions": {
"ecmaVersion": 12,
"sourceType": "module"
},
"rules": {}
}

Modifique o arquivo para que este fique assim:

{
"env": {
"es2021": true,
"node": true
},
"extends": [
"eslint:recommended",
"prettier"
],
"parserOptions": {
"ecmaVersion": 12,
"sourceType": "module"
},
"plugins": [
"prettier"
],
"rules": {
"prettier/prettier": "error"
}
}

Crie o arquivo .prettierrc e adicione este conteúdo a ele:

{
"semi": false,
"singleQuote": true,
"trailingComma": "es5"
}

As configurações acima representam uma escolha pessoal minha. Explicando:

  • semi: não imprime ponto e vírgula no final das instruções;
  • singleQuote: usar aspas simples em vez de aspas duplas;
  • trailingComma: imprima vírgulas à direita sempre que possível quando houver várias linhas. (Uma matriz de linha única nunca receberá vírgulas). Essa opção pode parecer um pouco sem sentido, porém, me ajuda bastante, as vezes acabo adicionando uma nova entrada na lista e esqueço de incluir a virgula após o item anterior, ao deixar sempre a lista multilinhas com uma virgula a direita, evito ser pego desprevenido.

Obs: a lista completa de regras/opções disponíveis podem ser encontradas no link: https://prettier.io/docs/en/options.html.

Na raiz do projeto crie um arquivo .env com o conteúdo:

PORT=3000

Importante: Utilizamos este arquivo para centralizar configurações sensíveis, tais como, chaves de API, senhas e outros dados que não devem fazer parte do controle de versões, ou seja, é uma boa prática incluir este arquivo no .gitignore do seu projeto.

Crie um diretório src e dentro um arquivo índex.js, adicionando a este arquivo o conteúdo:

import 'dotenv/config'
import cors from 'cors'
import express from 'express'
const app = express()// Permite acesso externo
app.use(cors())
// Desativa o X-Powered-By: Express
app.disable('x-powered-by')
// Criamos uma rota raiz com o texto Hello World!
app.get('/', (req, res) => {
res.send('Hello World!')
})
// Passamos a porta onde o servidor ficará ouvindo
app.listen(process.env.PORT || 3000, () => {
console.log(`Listening on port: ${process.env.PORT}`)
})

Importante: utilizo app.disable('x-powered-by') para remover da resposta HTTP a referência de que o Express/Node compõem a lista de tecnologias utilizadas, isso irá afastar rotinas mais simples de varredura e ataques automatizados.

Obs: Gosto de organizar meu código dentro de um diretório src, é uma estrategia que utilizo até mesmo em projetos baseados em outras linguagens, como PHP.

Por fim edite o arquivo package.json e inclua o bloco referente a tag "scripts". Veja um exemplo:

{
"name": "teste",
"version": "1.0.0",
"main": "./src/index.js",
"license": "MIT",
"scripts" : {
"dev": "nodemon --exec sucrase-node ./src/index.js"
},
"dependencies": {
//...

Terminamos.

Agora podemos executar no terminal a instrução:

yarn dev

Abrir o navegador e acessar http://localhost:3000 e teremos um “Hello World!” sendo exibido no canto superior esquerdo da tela.

Até o momento

Do momento em que configuramos o ESLint e o Prettier em diante, ao digitarmos um código que venha a ferir as regras de validação do ESLint e/ou formatação do Prettier, nosso editor irá nos avisar. Vega o que aconteceu quando baguncei o código do arquivo src/index.js:

Imagem 7: exemplo de uso do ESLint e Prettier

Observe que na imagem acima existem vários destaques (sublinhados) em vermelho. Ao passar o mouse sobre as marcações uma pop-up irá nos indicar o motivo da critica, no exemplo, precisamos deletar o ponto-e-virgula, pois ele viola segundo o ESLint a regra definida no Prettier. Pode confessar, é lindo ver isso funcionando não é mesmo!? :)

Ao clicar em salvar o código será automaticamente ajustado e formatado de acordo com as regras. Veja:

Imagem 8: código corrigido automaticamente pelo ESLint e Prettier

Importante: se você salvou o arquivo e nada aconteceu não entre em pânico, isso pode ser devido ao fato do autoFixOnSave e do validate não estarem devidamente configurados em seu editor/IDE. Se este for o caso, leia o tópico seguinte.

ESLint: autoFixOnSave e validate

Essa é a cereja do bolo, até aqui já temos o ESLint fazendo o linting do nosso código e indicando os pontos de atenção e/ou erro. Mas existem 2 recursos que podem agregar ainda mais valor a essa solução, o source.fixAll.eslint que vai dá aquele tapa bonito no código, tal como ajustar a indentação, padronizar as aspas e assim por diante, isso irá se repetir automaticamente toda vez que salvarmos o código. Já o eslint.probe serve para indicar quais "linguagens" devem ser observadas pelo ESLint.

Ao instalar o ESLint o mesmo injeta em nosso editor de código ou IDE algumas configurações padrões, sendo elas:

"editor.codeActionsOnSave": {},
"eslint.probe": [
"javascript",
"javascriptreact",
"typescript",
"typescriptreact",
"html",
"vue"
],

A única coisa que precisamos fazer é alterar a primeira linha de modo que fiquei deste jeito:

"editor.codeActionsOnSave": {
"source.fixAll.eslint": true,
},

Essa instrução irá ativar uma correção automática toda vez que o arquivo for salvo. Este comportamento será aplicado a todas as linguagens mapeadas no array eslint.probe.

No VSCode podemos fazer isso acessando e alterando o arquivo de configurações do usuário:

  • No MacOS: Code > Preferences > Settings
  • No Windows e Linux: File > Preferences > Settings

Altere para a visualização em formato JSON (passo 1) e inclua o código que ativa o autoFix (passo 2):

Imagem 9: visualização em formato json das configurações do VSCode

Tudo pronto! Agora é só salvar e fechar o arquivo :)

Outra forma de ter acesso as configurações é via uso de atalhos. Veja:

  • No MacOS: SHIFT + COMMAND + P
  • No Windows e Linux: SHIFT + CTRL + P

Será aberta uma caixa para inserção de valor, digite Settings. Veja:

Imagem 10: prompt de comandos do VSCode.

No passo 1 digitamos o valor coringa Settings e uma lista de correspondências é apresentada. Observe que existe um sinal de maior a esquerda do valor digitado, este símbolo indica que estamos em um prompt de comandos. Já as duas outras setas:

  • Open Default Settings (JSON): abre o arquivo JSON de configurações padrão para visualização. O conteúdo deste arquivo serve tão somente como referência de consulta;
  • Open Settings (JSON): abre o arquivo JSON de configurações do usuário, os valores contidos neste local sobrescreve as configurações do arquivo apresentado no tópico anterior.

Caso tenha aberto o arquivo de configurações no modo de visualização de formulário, é possível alterar para a visão em formato JSON conforme mostrado na imagem 9 passo 1.

ESLint Command Line Interface

O ESLint vai muito além do uso embutido em nosso editor/IDE, ele pode ser utilizado diretamente no terminal. Veja um exemplo:

Imagem 11: ESLint sendo utilizado no terminal

Obs: caso algum erro seja encontrado você verá algo como a imagem acima. Do contrário verá só um output de Done in x.xxs.

Veja que no exemplo acima utilize o comando:

yarn eslint index.js

Caso esteja utilizando NPM, você tem duas opções, ou instalar o ESLint global ou utilizar o NPX (já vem por padrão quando você instala o Node.js) para executar o ESLint. Veja um exemplo:

npx eslint index.js

E se quisermos executar um auto-fix em um diretório? Veja esse exemplo:

yarn eslint --fix --ext .js src/

A instrução acima é bem sugestiva. Ela roda um auto-fix (correção automática) em todos os arquivos com extensão .js do diretório src. Se tudo correr bem você verá só um Done in x.xxs, do contrário o ESLint solicitará sua intervenção manual.

Para mais detalhes quanto aos comandos disponíveis para a CLI, acesse o link: https://eslint.org/docs/user-guide/command-line-interface

Sugestão de leitura

EditorConfig — Padronizando Características essenciais: https://medium.com/@fabiojanio/editorconfig-padronizando-caracter%C3%ADsticas-essenciais-768a806ad33c

Recomendações para ambiente produtivo

Segue uma lista de recomendações para uso do Express em ambiente produtivo:

Links alternativos

Os links abaixo demonstram formas alternativas de realizar a implementação que demonstrei neste post, alguns deles utilizam outros utilitários, como o babel. Você pode inclusive combinar minhas dicas com abordagens presentes nos links abaixo. Lembre-se, somos artistas, então impressione!

--

--

Palestrante, analista de sistemas e webmaster. Apaixonado pelo universo da tecnologia e um profundo admirador da filosofia do software livre.

Love podcasts or audiobooks? Learn on the go with our new app.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store