Conteúdo sobre Front-end por Matheus Pergoli.

Blog.

Setup para desenvolvimento Backend com Node / TS / Jest

Author image

Matheus Pergoli

Cover image

Guia de setup para um ambiente de desenvolvimento Backend
com Node / TS / Jest

Neste setup vamos utilizar algumas tecnologias para nos ajudar a manter um código bem escrito e organizado seguindo as boas práticas

Lista das dependências que vamos utilizar no setup

  • prettier

  • typescript

  • @types/node

  • eslint eslint-plugin-promise eslint-plugin-import eslint-plugin-n @typescript-eslint/eslint-plugin eslint-config-standard-with-typescript

  • lint-staged

  • husky

  • commitlint

  • jest @types/jest ts-jest ts-node

Vamos começar a instalar um por um e explicando cada configuração

Antes de tudo vamos iniciar um projeto com npm

npm init -y

E vamos também criar um repositório git dentro do nosso projeto

git init

Precisamos também do arquivo .gitignore para excluirmos alguns arquivos a serem enviados para o GitHub
Crie um na raiz do projeto e adicione o seguinte conteudo:

node_modules
dist
coverage

A pasta node_modules é muito grande e não precisamos enviar para o GitHub
A pasta dist é onde ficará todo nosso código javascript compilado
E a pasta coverage é onde ficará o coverage dos nossos testes e também não precisamos enviar

Instalação das dependências

  • prettier

Para formatação e organização do nosso código

npm install -D prettier

Vamos também utilizar um arquivo de configuração para o prettier
Crie na raiz do seu projeto um arquivo chamado .prettierrc.json e adicione o seguinte conteúdo:

{
  "tabWidth": 2,
  "semi": false,
  "useTabs": false,
  "endOfLine": "lf",
  "printWidth": 120,
  "singleQuote": true,
  "jsxSingleQuote": true,
  "bracketSpacing": true,
  "bracketSameLine": true,
  "trailingComma": "none"
}

E também vamos criar um arquivo .prettierignore para que ele ignore algumas pastas/arquivos
Adicione o seguinte conteúdo:

node_modules
dist
coverage
  • typescript

Pacote nescessário para utilização do typescript em nosso projeto

npm install -D typescript

Precisamos de um arquivo de configuração para o typescript
Crie na raiz do projeto um arquivo chamado tsconfig.json e adicione o seguinte conteúdo:

{
  "compilerOptions": {
    "outDir": "./dist",
    "module": "CommonJS",
    "target": "ES2020",
    "esModuleInterop": true,
    "allowJs": true,
    "strict": true,
    "strictNullChecks": true
  }
}

Explicação do arquivo:
outDir: Pasta que será criada para manter todo nosso código compilado
module: Para podermos utilizar import/export mas compilar o código para o formato require
target: Versão para qual o typescript será compilado
esModuleInterop: Converte import/export para require em módulos que ainda usam esse formato
allowJs: Permite incluir arquivos JS na compilação para pasta Dist
strict: Para habilitar o modo estrito do typescript para melhor qualidade do código
strictNullChecks: Habilita uma verificação mais rigorosa para valores null & undefined

  • @types/node

npm install -D @types/node

Pacote que adiciona tipagens para o Node que nos ajuda a evitar alguns erros bobos

  • eslint eslint-plugin-promise eslint-plugin-import eslint-plugin-n @typescript-eslint/eslint-plugin eslint-config-standard-with-typescript

npm install -D eslint eslint-plugin-promise eslint-plugin-import eslint-plugin-n @typescript-eslint/eslint-plugin eslint-config-standard-with-typescript

Como vamos utilizar o padrão Standard Javascript precisamos incluir todos esses pacotes para que o eslint consiga configurar esse padrão para o typescript

Precisamos também de mais dois arquivos de configuração para o ESLINT
Crie na raiz do projeto o arquivo chamado .eslintrc.json e adicione o seguinte conteúdo:

{
  "extends": "standard-with-typescript",
  "parserOptions": {
    "project": "./tsconfig.json"
  },
  "rules": {
    "@typescript-eslint/space-before-function-paren": "off"
  }
}

Explicação do arquivo:
extends: Extensão das regras padrões do ESLINT para adicionar mais regras para o typescript
parserOptions: Opções que podemos passar para análise do parser do ESLINT
project: Para usar as configurações definidas no arquivo tsconfig.json do nosso projeto
rules: Onde podemos habilitar ou desabilitar regras do ESLINT

Também precisamos de outro arquivo chamado .eslintignore que vai sinalizar ao ESLINT quais pastas/arquivos ele deve ignorar na análise de código, crie um e adicione o seguinte conteúdo:

node_modules
dist
coverage
  • lint-staged

Pacote que vamos utilizar para rodar scripts apenas em arquivos modificados na área staged do Git

npm install -D lint-staged

Precisamos de um arquivo de configuração para o lint-staged
Crie na raiz do projeto um arquivo chamado .lintstagedrc.json e adicione o seguinte conteúdo:

{
  "*.ts": ["eslint 'src/**/*' --fix"]
}

Fazendo isso estamos dizendo para o lint-staged rodar o comando em qualquer arquivo dentro de qualquer pasta dentro de src que tenha a extensão .ts

  • husky

Pacote para podermos adicionar hooks ao git fazendo com que ele rode scripts durante alguns estágios que escolhermos

npm install -D husky

Para habilitar os hooks rode o seguinte comando:

npx husky install

Vamos adicionar um hook que vai rodar um script sempre que fizermos um commit

npx husky add .husky/pre-commit "npx lint-staged"

Esse comando cria na raiz do seu projeto uma pasta chamada .husky onde ficará todos os seus hooks e os scripts que vão ser rodados sempre que alguma ação definida acontecer

Vamos utilizar o lint-staged para rodar scripts nos arquivos modificados do git
O lint-staged será o responsável por rodar os scripts que definimos dentro do arquivo .lintstagedrc.json

  • commitlint

Para padronizar os commits seguindo o Conventional commits

De baixo dos panos é criado um hook que verifica cada commit e valida se estamos seguindo o padrão Conventional commits

npm install -D @commitlint/config-conventional @commitlint/cli

Vamos precisar criar mais um arquivo de configuração para o commitlint
Crie um arquivo chamado .commitlintrc.json e adicione o seguinte código:

{ "extends": ["@commitlint/config-conventional"] }

Após instalar o husky e o commitlint e criado o arquivo de configuração use o seguinte comando:

npx husky add .husky/commit-msg  'npx --no -- commitlint --edit ${1}'

Feito isso seu linter de commits deve funcionar normalmente

  • jest @types/jest ts-jest ts-node

Pacotes nescessários para utilização do Jest com Typescript

npm install -D jest @types/jest ts-jest ts-node

Após terminar a instalação dos pacotes vamos rodar o seguinte comando:

npx jest --init

E isso irá iniciar algumas perguntas:

Would you like to use Jest when running "test" script in "package.json"?
Aqui ele está perguntando se queremos criar o script "test": "jest" no nosso arquivo package.json
Escolha a resposta yes porque vamos utilizar esse script

Would you like to use Typescript for the configuration file?
Aqui informamos se queremos criar um arquivo de configuração com typescript
E já que estamos utilizando typescript vamos escolher a resposta yes

Choose the test environment that will be used for testing
Aqui é onde escolhemos o ambiente onde vamos fazer o testes
E como é backend vamos selecionar a resposta node

Do you want Jest to add coverage reports?
Aqui é onde escolhemos se queremos coverage dos nossos arquivos gerado pelo Jest
É uma boa escolha ter o coverage do nosso projeto pra ter uma noção do que falta ser testado
Escolha a resposta yes

Which provider should be used to instrument code for coverage?
Aqui vamos escolher a resposta v8 para instrumentar nosso código

Automatically clear mock calls, instances, contexts and results before every test?
Aqui vamos escolher a resposta no para sinalizar ao Jest que não queremos que ele limpe nossos mocks para termos um melhor controle sobre nossos mocks durante os testes

Após todas as perguntas ele vai criar um arquivo na raiz do nosso projeto chamado jest.config.ts
Dentro desse arquivo substitua o conteúdo por essas opções:

export default {
  roots: ['<rootDir>/src'],
  
  coverageProvider: 'v8',
  
  collectCoverage: true,

  collectCoverageFrom: ['<rootDir>/src/**/*.ts'],

  coverageDirectory: 'coverage',
  
  testEnvironment: 'node',

  transform: {
    '.+\\.ts$': 'ts-jest'
  },
  
  testMatch: ['**/__tests__/**/*.[jt]s?(x)', '**/?(*.)+(spec|test).[tj]s?(x)']
}

Explicação do arquivo:
roots: Especifica os diretórios que contêm os arquivos de código-fonte do projeto
coverageProvider: Especifica o provedor de cobertura de código que será usado pelo Jest
collectCoverage: Ativa a coleta de informações de cobertura de código
collectCoverageFrom: Especifica os arquivos de código-fonte que serão usados para coletar as informações de cobertura de código.
coverageDirectory: Especifica o diretório onde os resultados da cobertura de código serão armazenados
testEnvironment: Especifica o ambiente em que os testes serão executados
transform: Especifica como os arquivos de código-fonte serão transformados antes de serem executados, vamos utilizar o ts-jest para compilar arquivos para JS apenas para o Jest
testMatch: Especifica os arquivos de teste que serão executados

Agora vamos testar se todo nosso setup está rodando corretamente

Crie na raiz do projeto uma pasta chamada src e dentro dela crie um arquivo controller.spec.ts com o seguinte código:

describe('Controller Test', () => {
  test('Should pass the test', () => {
    expect(1).toBe(1)
  })
})

Após isso rode o comando:

npm run test

Se o setup foi feito corretamente você deverá ver o resultado do seu primeiro teste

Vamos também testar se nossos commits estão padronizados
Rode os seguintes comandos:

git add .
git commit -m "Testando os commits"

E de novo, se o setup foi feito corretamente você deverá ver uma mensagem de erro dizendo que seu commit deve seguir o padrão definido no projeto.

Mais Artigos

Post image

Core Javascript Principles

Aprenda sobre os princípios mais importantes do Javascript

Author image

Matheus Pergoli

Post image

Aprenda a criar uma Árvore Binária de Busca com Javascript

Aprenda como criar uma estrutura de dados de Árvore com Javascript

Author image

Matheus Pergoli