JavaScript

Dominando Módulos Nativos do Node.js: fs, path, os e crypto em Projetos Reais

8 min de leitura

Dominando Módulos Nativos do Node.js: fs, path, os e crypto em Projetos Reais

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 Usando Promises e Async/Await A API Promises ( ) é recomendada em código moderno, permitindo uso com 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

<h2>Introdução aos Módulos Nativos do Node.js</h2>

<p>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 — <strong>fs</strong>, <strong>path</strong>, <strong>os</strong> e <strong>crypto</strong> — 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.</p>

<h2>Módulo fs: Operações com Arquivos</h2>

<p>O módulo <strong>fs</strong> (File System) permite ler, escrever e manipular arquivos no disco. Node.js oferece duas abordagens: <strong>síncrona</strong> (bloqueante) e <strong>assíncrona</strong> (não-bloqueante). Em produção, sempre use métodos assíncronos.</p>

<h3>Leitura e Escrita Básica</h3>

<pre><code class="language-javascript">const fs = require(&#039;fs&#039;);

// Escrita assíncrona

fs.writeFile(&#039;dados.txt&#039;, &#039;Olá, Node.js!&#039;, (err) =&gt; {

if (err) throw err;

console.log(&#039;Arquivo salvo!&#039;);

});

// Leitura assíncrona

fs.readFile(&#039;dados.txt&#039;, &#039;utf8&#039;, (err, data) =&gt; {

if (err) throw err;

console.log(data); // Output: Olá, Node.js!

});</code></pre>

<h3>Usando Promises e Async/Await</h3>

<pre><code class="language-javascript">const fs = require(&#039;fs&#039;).promises;

async function gerenciarArquivos() {

try {

// Escrever

await fs.writeFile(&#039;config.json&#039;, JSON.stringify({ debug: true }));

// Ler

const conteudo = await fs.readFile(&#039;config.json&#039;, &#039;utf8&#039;);

console.log(JSON.parse(conteudo));

// Deletar

await fs.unlink(&#039;config.json&#039;);

} catch (err) {

console.error(&#039;Erro:&#039;, err.message);

}

}

gerenciarArquivos();</code></pre>

<p>A API Promises (<code>fs.promises</code>) é recomendada em código moderno, permitindo uso com <code>async/await</code> e tratamento de erros mais limpo.</p>

<h2>Módulo path: Manipulação de Caminhos</h2>

<p>O módulo <strong>path</strong> gerencia caminhos de arquivos de forma agnóstica ao sistema operacional. Ele resolve diferenças entre Windows (<code>\</code>) e Unix (<code>/</code>) automaticamente.</p>

<h3>Operações Comuns</h3>

<pre><code class="language-javascript">const path = require(&#039;path&#039;);

// Concatenar caminhos

const caminhoCompleto = path.join(__dirname, &#039;uploads&#039;, &#039;imagem.jpg&#039;);

console.log(caminhoCompleto);

// Windows: C:\projeto\uploads\imagem.jpg

// Unix: /home/usuario/projeto/uploads/imagem.jpg

// Extrair informações

const arquivo = &#039;/home/usuario/dados.json&#039;;

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 = &#039;./config/app.js&#039;;

console.log(path.resolve(relativo)); // /caminho/completo/config/app.js

// Separadores

console.log(path.sep); // \ (Windows) ou / (Unix)</code></pre>

<h3>Caso Prático: Validar Uploads</h3>

<pre><code class="language-javascript">const path = require(&#039;path&#039;);

const fs = require(&#039;fs&#039;).promises;

async function validarUpload(nomeArquivo) {

// Evitar traversal attacks

const uploadDir = path.join(__dirname, &#039;uploads&#039;);

const caminhoFinal = path.resolve(uploadDir, nomeArquivo);

// Verificar se o arquivo está dentro do diretório permitido

if (!caminhoFinal.startsWith(uploadDir)) {

throw new Error(&#039;Caminho inválido!&#039;);

}

return caminhoFinal;

}</code></pre>

<h2>Módulo os: Informações do Sistema Operacional</h2>

<p>O módulo <strong>os</strong> fornece informações sobre o hardware e o SO, sendo útil para decisões de configuração e monitoramento.</p>

<h3>Consultas de Sistema</h3>

<pre><code class="language-javascript">const os = require(&#039;os&#039;);

// Informações da plataforma

console.log(os.platform()); // &#039;linux&#039;, &#039;win32&#039;, &#039;darwin&#039;

console.log(os.arch()); // &#039;x64&#039;, &#039;arm64&#039;

// 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());</code></pre>

<h3>Exemplo Prático: Monitoramento de Memória</h3>

<pre><code class="language-javascript">const os = require(&#039;os&#039;);

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 &gt; 80) {

console.warn(&#039;⚠️ Alerta: Uso elevado de memória!&#039;);

}

}

// Verificar a cada 10 segundos

setInterval(verificarMemoria, 10000);</code></pre>

<h2>Módulo crypto: Criptografia e Hash</h2>

<p>O módulo <strong>crypto</strong> implementa operações criptográficas: hash, HMAC, criptografia simétrica e assimétrica. É essencial para segurança.</p>

<h3>Hash e HMAC</h3>

<pre><code class="language-javascript">const crypto = require(&#039;crypto&#039;);

// Gerar hash SHA256 de uma senha

const senha = &#039;minha_senha_secreta&#039;;

const hash = crypto.createHash(&#039;sha256&#039;).update(senha).digest(&#039;hex&#039;);

console.log(hash); // a7d8e8c...

// HMAC com chave secreta

const chave = &#039;chave_privada&#039;;

const hmac = crypto.createHmac(&#039;sha256&#039;, chave)

.update(&#039;mensagem&#039;)

.digest(&#039;hex&#039;);

console.log(hmac);

// Verificar senha (nunca compare strings diretas!)

const hashArmazenado = crypto

.createHash(&#039;sha256&#039;)

.update(&#039;minha_senha_secreta&#039;)

.digest(&#039;hex&#039;);

function verificarSenha(senhaDigitada, hashArmazenado) {

const hashDigitada = crypto

.createHash(&#039;sha256&#039;)

.update(senhaDigitada)

.digest(&#039;hex&#039;);

// Usar timingSafeEqual para evitar timing attacks

return crypto.timingSafeEqual(

Buffer.from(hashDigitada),

Buffer.from(hashArmazenado)

);

}</code></pre>

<h3>Criptografia Simétrica</h3>

<pre><code class="language-javascript">const crypto = require(&#039;crypto&#039;);

function criptografar(texto, chave) {

// A chave deve ter 32 bytes para AES-256

const iv = crypto.randomBytes(16);

const cipher = crypto.createCipheriv(&#039;aes-256-cbc&#039;, Buffer.from(chave), iv);

let encriptado = cipher.update(texto, &#039;utf8&#039;, &#039;hex&#039;);

encriptado += cipher.final(&#039;hex&#039;);

// Retornar IV + dados (necessário para descriptografar)

return iv.toString(&#039;hex&#039;) + &#039;:&#039; + encriptado;

}

function descriptografar(dados, chave) {

const [ivHex, encriptado] = dados.split(&#039;:&#039;);

const iv = Buffer.from(ivHex, &#039;hex&#039;);

const decipher = crypto.createDecipheriv(&#039;aes-256-cbc&#039;, Buffer.from(chave), iv);

let texto = decipher.update(encriptado, &#039;hex&#039;, &#039;utf8&#039;);

texto += decipher.final(&#039;utf8&#039;);

return texto;

}

// Uso

const chave = crypto.randomBytes(32);

const original = &#039;Dados sensíveis&#039;;

const criptografado = criptografar(original, chave);

const descriptografado = descriptografar(criptografado, chave);

console.log(descriptografado); // Dados sensíveis</code></pre>

<h2>Conclusão</h2>

<p>Os quatro módulos nativos abordados formam a base para desenvolvimento backend com Node.js. O <strong>fs</strong> permite gerenciar arquivos, o <strong>path</strong> resolve caminhos de forma segura e portável, o <strong>os</strong> oferece informações do sistema para decisões dinâmicas, e o <strong>crypto</strong> 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.</p>

<h2>Referências</h2>

<ul>

<li><a href="https://nodejs.org/api/fs.html" target="_blank" rel="noopener noreferrer">Node.js fs Documentation</a></li>

<li><a href="https://nodejs.org/api/path.html" target="_blank" rel="noopener noreferrer">Node.js path Documentation</a></li>

<li><a href="https://nodejs.org/api/os.html" target="_blank" rel="noopener noreferrer">Node.js os Documentation</a></li>

<li><a href="https://nodejs.org/api/crypto.html" target="_blank" rel="noopener noreferrer">Node.js crypto Documentation</a></li>

<li><a href="https://cheatsheetseries.owasp.org/cheatsheets/Cryptographic_Storage_Cheat_Sheet.html" target="_blank" rel="noopener noreferrer">OWASP: Cryptographic Storage Cheat Sheet</a></li>

</ul>

Comentários

Mais em JavaScript

React: Fundamentos, JSX e Componentes Funcionais: Do Básico ao Avançado
React: Fundamentos, JSX e Componentes Funcionais: Do Básico ao Avançado

React: O que é e por que aprender React é uma biblioteca JavaScript desenvolv...

Boas Práticas de Variáveis de Ambiente e Configuração em Projetos JavaScript para Times Ágeis
Boas Práticas de Variáveis de Ambiente e Configuração em Projetos JavaScript para Times Ágeis

Introdução: Por Que Variáveis de Ambiente Importam Variáveis de ambiente são...

Estruturas de Controle em JavaScript: if, switch e Tratamento de Fluxo: Do Básico ao Avançado
Estruturas de Controle em JavaScript: if, switch e Tratamento de Fluxo: Do Básico ao Avançado

Estruturas Condicionais: A Base da Lógica em JavaScript As estruturas de cont...