Este tutorial tem como objetivo mostrar com exemplos práticos as boas práticas de desenvolvimento com NodeJS.
Algumas boas práticas no desenvolvimento NodeJS incluem:
- Utilização de módulos e padrões de arquitetura para modularizar o código.
- Gerenciamento de erros de forma clara e objetiva.
- Uso de promises ou async/await para lidar com requisições assíncronas.
- Utilização de frameworks de testes, como Mocha, Cypress ou Jest, para realizar testes unitários e integração.
- Utilização de ferramentas de gerenciamento de pacotes, como npm ou yarn, para gerenciar dependências.
- Adoção de uma boa estratégia de versionamento.
- Documentação clara e objetiva do código.
- Utilização de linting e análise de código estático para garantir a qualidade e padronização do código.
Utilização de módulos e padrões de arquitetura para modularizar o código.
A utilização de módulos é uma boa prática no desenvolvimento NodeJS pois permite que o código seja modularizado e reaproveitado em diferentes partes da aplicação. É possível usar módulos nativos do NodeJS ou módulos instalados via npm.
Por exemplo, o módulo fs
(File System) pode ser usado para acessar arquivos do sistema operacional, e o módulo express
é muito utilizado para criar aplicações web.
Aposte na Mega da Virada 2024!
Prepare-se para uma chance única de mudar sua vida. O prêmio histórico de R$ 600 milhões da Mega da Virada 2024 está esperando por você!
Além disso, conheça os bolões da Sorte Online, que são os mais premiados e oferecem as melhores chances de ganhar! Ao participar dos bolões, você se junta a centenas de apostadores e aumenta suas chances de faturar uma bolada.
Faça sua Aposta AgoraA seguir um exemplo de como importar e utilizar o módulo fs
:
const fs = require('fs');
fs.readFile('arquivo.txt', 'utf-8', (err, data) => {
if (err) throw err;
console.log(data);
});
Já a utilização de padrões de arquitetura, como MVC (Model-View-Controller), ajuda a manter o código organizado e fácil de manter. Aqui está um exemplo de como o padrão MVC pode ser implementado em uma aplicação NodeJS:
// controllers/usuario.js
const Usuario = require('../models/usuario');
exports.criarUsuario = (req, res) => {
const novoUsuario = new Usuario(req.body);
novoUsuario.save((err) => {
if (err) res.send(err);
res.json({ mensagem: 'Usuário criado com sucesso!' });
});
};
// models/usuario.js
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const UsuarioSchema = new Schema({
nome: String,
email: String,
senha: String
});
module.exports = mongoose.model('Usuario', UsuarioSchema);
Gerenciamento de erros de forma clara e objetiva.
Gerenciamento de erros é importante em qualquer aplicação para garantir a integridade e a confiabilidade dos dados. No NodeJS, você pode gerenciar erros de forma clara e objetiva utilizando try-catch blocks. Veja um exemplo:
try {
// código que pode gerar erro
const result = someFunctionThatMayThrowError();
console.log(result);
} catch (error) {
console.error(error);
}
Além disso, é importante utilizar a função de callback de forma correta e tratar seus erros com tratamento de erro adequado, como por exemplo:
fs.readFile('some-file.txt', (err, data) => {
if (err) {
console.error(err);
} else {
console.log(data);
}
});
Neste exemplo, a função readFile
é passada como um callback que será chamada quando o arquivo for lido. Se houver um erro ao ler o arquivo, a função de callback irá receber um objeto de erro como primeiro argumento. Se não houver erro, a função de callback irá receber o conteúdo do arquivo como segundo argumento.
Uso de promises ou async/await para lidar com requisições assíncronas
No NodeJS, as promises e o async/await são usados para lidar com requisições assíncronas, evitando o callback hell.
Exemplo usando Promise:
const fs = require('fs');
const readFile = file => {
return new Promise((resolve, reject) => {
fs.readFile(file, 'utf-8', (err, data) => {
if (err) return reject(err);
return resolve(data);
});
});
};
readFile('file.txt')
.then(data => {
console.log(data);
})
.catch(err => {
console.error(err);
});
Exemplo usando async/await:
const fs = require('fs');
const util = require('util');
const readFile = util.promisify(fs.readFile);
async function readData() {
try {
const data = await readFile('file.txt', 'utf-8');
console.log(data);
} catch (err) {
console.error(err);
}
}
readData();
Nestes exemplos, a Promise readFile
é criada e retorna um arquivo file.txt
lido. A função then
é usada para lidar com o resultado bem-sucedido da Promise, e a função catch
é usada para lidar com erros. Já o exemplo usando async/await usa a função readData
que é marcada como async
, permitindo o uso de await
para esperar a Promise readFile
ser resolvida antes de ler o arquivo.
Utilização de frameworks de testes, como Mocha, Cypress ou Jest, para realizar testes unitários e integração.
A utilização de frameworks de testes é uma boa prática para garantir a qualidade do código e evitar erros futuros. Alguns dos frameworks mais populares para testes no Node.js incluem Mocha, Cypress e Jest. Vamos dar uma olhada em exemplos práticos de como cada um pode ser usado:
Mocha: É um framework simples e versátil para testes unitários. Aqui está um exemplo de como testar uma função soma em Mocha:
const assert = require("assert");
function sum(a, b) {
return a + b;
}
describe("sum", () => {
it("should return the sum of two numbers", () => {
assert.equal(sum(1, 2), 3);
});
});
Cypress: É uma ferramenta de teste end-to-end que permite automatizar testes do usuário final. Aqui está um exemplo de como testar uma interação do usuário com um botão em Cypress:
describe("Button interaction", () => {
it("should display a message when clicked", () => {
cy.visit("https://example.com");
cy.get("button").click();
cy.get("#message").should("contain", "Button was clicked");
});
});
Jest: É um framework completo para testes unitários e integração que inclui recursos como snapshots e mocks. Aqui está um exemplo de como testar uma função de soma com Jest:
function sum(a, b) {
return a + b;
}
test("sum adds numbers", () => {
expect(sum(1, 2)).toBe(3);
});
Estes são apenas alguns exemplos de como utilizar frameworks de testes no Node.js para garantir a qualidade do código. É importante escolher o framework que se adequa melhor às suas necessidades e implementá-lo de forma eficiente para garantir testes robustos e confiáveis.
Utilização de ferramentas de gerenciamento de pacotes, como npm ou yarn, para gerenciar dependências.
O npm (Node Package Manager) e o yarn são as principais ferramentas de gerenciamento de pacotes utilizadas no desenvolvimento Node.js.
Exemplo de instalação de dependências usando npm:
// instalar uma dependência
npm install express
// instalar uma dependência de forma global
npm install -g nodemon
// instalar todas as dependências do seu projeto a partir do arquivo package.json
npm install
Exemplo de instalação de dependências usando yarn:
// instalar uma dependência
yarn add express
// instalar uma dependência de forma global
yarn global add nodemon
// instalar todas as dependências do seu projeto a partir do arquivo package.json
yarn
Ambos permitem a instalação, atualização e remoção de dependências, além de permitir a criação de scripts para automatizar tarefas comuns. O yarn é considerado mais rápido que o npm, mas ambos funcionam de forma semelhante e escolher um ou outro é uma questão de preferência pessoal.
Adoção de uma boa estratégia de versionamento.
A estratégia de versionamento é importante para garantir a manutenibilidade e rastreabilidade do código em projetos de software. Uma boa estratégia de versionamento pode incluir as seguintes ações:
- Utilização do sistema semântico de versionamento: Isso significa usar uma estrutura de versão como X.Y.Z, onde X é a versão maior, Y é a versão menor e Z é a correção de bugs.
- Criação de branches: Utilize branches separadas para desenvolvimento, correção de bugs e produção, para evitar conflitos de código.
- Tag de versão: Adicione tags para cada versão publicada, para facilitar o acesso às versões antigas.
- Commits bem escritos: Escreva commits claros e objetivos, para que outros desenvolvedores possam entender o que foi alterado.
- Utilização de Pull Requests: Utilize Pull Requests para revisar e aprovar mudanças no código antes de serem mescladas ao branch principal.
Exemplo de uso de uma boa estratégia de versionamento com Git e Github:
- Inicialize um repositório Git no seu projeto:
$ git init
- Adicione arquivos ao repositório:
$ git add .
- Realize um commit inicial:
$ git commit -m "Initial commit"
- Crie uma branch para o desenvolvimento:
$ git checkout -b develop
- Adicione e commite as mudanças realizadas na branch de desenvolvimento:
$ git add .
$ git commit -m "Adicionando novas funcionalidades"
- Crie uma tag de versão:
$ git tag -a v1.0.0 -m "Versão 1.0.0 lançada"
- Envie as mudanças para o repositório remoto no Github:
$ git push origin develop
$ git push origin v1.0.0
Com esta estratégia, é possível garantir uma boa gestão de versões no seu projeto Node.js, tornando mais fácil o gerenciamento de bugs, o acesso a versões antigas e a revisão de mudanças no código.
Documentação clara e objetiva do código.
A documentação do código é importante para ajudar outros desenvolvedores a entender e colaborar com o código. Aqui estão algumas boas práticas para documentar o código em Node.js:
- Documentação de cabeçalho: Adicione comentários claros e concisos no topo de cada arquivo de código para descrever o propósito geral do arquivo.
- Comentários de função: Adicione comentários claros e concisos antes de cada função para descrever o propósito da função, seus argumentos e o que ela retorna.
- Documentação de código JSDoc: Use a notação JSDoc para adicionar documentação mais detalhada ao código, incluindo tipos de argumentos, tipos de retorno, etc.
Exemplo de documentação de cabeçalho:
/**
* File: database.js
* Purpose: Arquivo de conexão com o banco de dados
*/
Exemplo de documentação de função:
/**
* getData
* @param {string} table - Nome da tabela
* @param {string} id - Id do registro
* @returns {Object} - Objeto de dados do registro
*/
function getData(table, id) {
// código da função
}
Exemplo de documentação JSDoc:
/**
* @typedef {Object} User
* @property {string} name - Nome do usuário.
* @property {string} email - Email do usuário.
*/
/**
* getUser
* @param {string} id - Id do usuário
* @returns {User} - Dados do usuário
*/
function getUser(id) {
// código da função
}
Utilização de linting e análise de código estático para garantir a qualidade e padronização do código.
A utilização de linting e análise de código estático é uma boa prática para garantir a qualidade e padronização do código em Node.js. Isso pode ser feito usando ferramentas como ESLint, JSHint ou StandardJS.
Exemplo de uso do ESLint:
- Instale o ESLint usando o npm ou o yarn:
npm install eslint --save-dev
Inicialize o ESLint com as configurações padrão:
npx eslint --init
- Edite o arquivo
.eslintrc
com as regras personalizadas. - Adicione a seguinte linha no package.json:
"lint": "eslint ."
- xecute o lint com o seguinte comando:
npm run lint
Agora, ao executar o comando acima, o ESLint irá verificar todo o seu código e informar sobre qualquer erro ou aviso encontrado, seguindo as regras definidas no arquivo .eslintrc
. Dessa forma, é possível garantir que o código esteja de acordo com as boas práticas e padrões definidos.
Conclusão
Seguindo este padrão de boas práticas no desenvolvimento de aplicações NodeJS você alcançará qualidade de código e melhor engajamento com a equipe de desenvolvedores dos projetos onde trabalhará.
LEIA TAMBÉM: