Introdução aos Módulos Nativos do Node.js
O Node.js fornece diversos módulos nativos que permitem interagir com o sistema operacional sem depender de bibliotecas externas. Os quatro módulos que abordaremos — fs, path, os e crypto — são fundamentais para qualquer desenvolvedor JavaScript no backend. Eles cobrem manipulação de arquivos, caminhos de sistema, informações do SO e criptografia, respectivamente. Dominar esses módulos é essencial para construir aplicações robustas e seguras.
Módulo fs: Operações com Arquivos
O módulo fs (File System) permite ler, escrever e manipular arquivos no disco. Node.js oferece duas abordagens: síncrona (bloqueante) e assíncrona (não-bloqueante). Em produção, sempre use métodos assíncronos.
Leitura e Escrita Básica
const fs = require('fs');
// Escrita assíncrona
fs.writeFile('dados.txt', 'Olá, Node.js!', (err) => {
if (err) throw err;
console.log('Arquivo salvo!');
});
// Leitura assíncrona
fs.readFile('dados.txt', 'utf8', (err, data) => {
if (err) throw err;
console.log(data); // Output: Olá, Node.js!
});
Usando Promises e Async/Await
const fs = require('fs').promises;
async function gerenciarArquivos() {
try {
// Escrever
await fs.writeFile('config.json', JSON.stringify({ debug: true }));
// Ler
const conteudo = await fs.readFile('config.json', 'utf8');
console.log(JSON.parse(conteudo));
// Deletar
await fs.unlink('config.json');
} catch (err) {
console.error('Erro:', err.message);
}
}
gerenciarArquivos();
A API Promises (fs.promises) é recomendada em código moderno, permitindo uso com async/await e tratamento de erros mais limpo.
Módulo path: Manipulação de Caminhos
O módulo path gerencia caminhos de arquivos de forma agnóstica ao sistema operacional. Ele resolve diferenças entre Windows (\) e Unix (/) automaticamente.
Operações Comuns
const path = require('path');
// Concatenar caminhos
const caminhoCompleto = path.join(__dirname, 'uploads', 'imagem.jpg');
console.log(caminhoCompleto);
// Windows: C:\projeto\uploads\imagem.jpg
// Unix: /home/usuario/projeto/uploads/imagem.jpg
// Extrair informações
const arquivo = '/home/usuario/dados.json';
console.log(path.dirname(arquivo)); // /home/usuario
console.log(path.basename(arquivo)); // dados.json
console.log(path.extname(arquivo)); // .json
// Resolver caminho absoluto
const relativo = './config/app.js';
console.log(path.resolve(relativo)); // /caminho/completo/config/app.js
// Separadores
console.log(path.sep); // \ (Windows) ou / (Unix)
Caso Prático: Validar Uploads
const path = require('path');
const fs = require('fs').promises;
async function validarUpload(nomeArquivo) {
// Evitar traversal attacks
const uploadDir = path.join(__dirname, 'uploads');
const caminhoFinal = path.resolve(uploadDir, nomeArquivo);
// Verificar se o arquivo está dentro do diretório permitido
if (!caminhoFinal.startsWith(uploadDir)) {
throw new Error('Caminho inválido!');
}
return caminhoFinal;
}
Módulo os: Informações do Sistema Operacional
O módulo os fornece informações sobre o hardware e o SO, sendo útil para decisões de configuração e monitoramento.
Consultas de Sistema
const os = require('os');
// Informações da plataforma
console.log(os.platform()); // 'linux', 'win32', 'darwin'
console.log(os.arch()); // 'x64', 'arm64'
// Recursos de hardware
console.log(os.cpus().length); // Número de núcleos
console.log(os.totalmem()); // Memória total em bytes
console.log(os.freemem()); // Memória livre em bytes
// Caminhos padrão
console.log(os.homedir()); // /home/usuario (Unix) ou C:\Users\usuario (Windows)
console.log(os.tmpdir()); // Diretório temporário do SO
// Uptime do sistema (em segundos)
console.log(os.uptime());
Exemplo Prático: Monitoramento de Memória
const os = require('os');
function verificarMemoria() {
const totalMem = os.totalmem();
const freeMem = os.freemem();
const usedMem = totalMem - freeMem;
const percentualUso = (usedMem / totalMem * 100).toFixed(2);
console.log(`Memória: ${percentualUso}% em uso`);
if (percentualUso > 80) {
console.warn('⚠️ Alerta: Uso elevado de memória!');
}
}
// Verificar a cada 10 segundos
setInterval(verificarMemoria, 10000);
Módulo crypto: Criptografia e Hash
O módulo crypto implementa operações criptográficas: hash, HMAC, criptografia simétrica e assimétrica. É essencial para segurança.
Hash e HMAC
const crypto = require('crypto');
// Gerar hash SHA256 de uma senha
const senha = 'minha_senha_secreta';
const hash = crypto.createHash('sha256').update(senha).digest('hex');
console.log(hash); // a7d8e8c...
// HMAC com chave secreta
const chave = 'chave_privada';
const hmac = crypto.createHmac('sha256', chave)
.update('mensagem')
.digest('hex');
console.log(hmac);
// Verificar senha (nunca compare strings diretas!)
const hashArmazenado = crypto
.createHash('sha256')
.update('minha_senha_secreta')
.digest('hex');
function verificarSenha(senhaDigitada, hashArmazenado) {
const hashDigitada = crypto
.createHash('sha256')
.update(senhaDigitada)
.digest('hex');
// Usar timingSafeEqual para evitar timing attacks
return crypto.timingSafeEqual(
Buffer.from(hashDigitada),
Buffer.from(hashArmazenado)
);
}
Criptografia Simétrica
const crypto = require('crypto');
function criptografar(texto, chave) {
// A chave deve ter 32 bytes para AES-256
const iv = crypto.randomBytes(16);
const cipher = crypto.createCipheriv('aes-256-cbc', Buffer.from(chave), iv);
let encriptado = cipher.update(texto, 'utf8', 'hex');
encriptado += cipher.final('hex');
// Retornar IV + dados (necessário para descriptografar)
return iv.toString('hex') + ':' + encriptado;
}
function descriptografar(dados, chave) {
const [ivHex, encriptado] = dados.split(':');
const iv = Buffer.from(ivHex, 'hex');
const decipher = crypto.createDecipheriv('aes-256-cbc', Buffer.from(chave), iv);
let texto = decipher.update(encriptado, 'hex', 'utf8');
texto += decipher.final('utf8');
return texto;
}
// Uso
const chave = crypto.randomBytes(32);
const original = 'Dados sensíveis';
const criptografado = criptografar(original, chave);
const descriptografado = descriptografar(criptografado, chave);
console.log(descriptografado); // Dados sensíveis
Conclusão
Os quatro módulos nativos abordados formam a base para desenvolvimento backend com Node.js. O fs permite gerenciar arquivos, o path resolve caminhos de forma segura e portável, o os oferece informações do sistema para decisões dinâmicas, e o crypto protege dados sensíveis através de hashing e criptografia. Domine essas APIs e você terá ferramentas poderosas para construir aplicações profissionais. Lembre-se: sempre use operações assíncronizadas em produção, valide caminhos para evitar traversal attacks e implemente criptografia adequada para dados sensíveis.