Introdução ao Node.js: rodando JS no servidor
1. O que é Node.js e por que ele existe?
Historicamente, o JavaScript estava confinado ao navegador. Era a linguagem que dava vida às páginas web, mas não tinha como interagir com o sistema de arquivos, criar servidores ou acessar bancos de dados. Tudo mudou em 2009, quando Ryan Dahl pegou o motor V8 do Google Chrome — o mesmo que interpreta JavaScript no navegador — e o executou fora dele. Nasceu o Node.js.
A diferença fundamental é simples: enquanto o navegador oferece APIs como window, document e fetch para manipular a interface do usuário, o Node.js fornece módulos como fs (file system), http e path para construir aplicações server-side. Em vez de manipular o DOM, você lê arquivos, escuta portas de rede e gerencia processos.
2. Instalação e primeiro "Hello World"
A maneira mais comum de instalar o Node.js é através do site oficial (nodejs.org). Você encontrará duas versões: LTS (Long Term Support), recomendada para produção, e Current, com as features mais recentes. Gerenciadores de versão como o nvm (Node Version Manager) permitem alternar entre versões facilmente.
Após a instalação, crie um arquivo hello.js:
console.log("Olá, servidor!");
Execute no terminal:
node hello.js
Pronto: você acabou de rodar JavaScript no servidor. O Node.js também oferece um REPL interativo. Basta digitar node no terminal sem nenhum arquivo e começar a testar expressões:
> 2 + 2
4
> const msg = "Node.js é incrível"
> msg.toUpperCase()
'NODE.JS É INCRÍVEL'
3. O modelo assíncrono e event-loop
O Node.js é single-threaded, mas isso não significa que executa uma tarefa por vez. Graças ao event-loop e ao I/O não bloqueante, ele pode lidar com milhares de conexões simultâneas sem criar uma thread para cada uma.
Compare a leitura síncrona e assíncrona de um arquivo:
const fs = require('fs');
// Síncrono (bloqueante)
const dadosSync = fs.readFileSync('arquivo.txt', 'utf-8');
console.log('Leitura síncrona concluída:', dadosSync);
// Assíncrono com callback
fs.readFile('arquivo.txt', 'utf-8', (erro, dados) => {
if (erro) throw erro;
console.log('Leitura assíncrona concluída:', dados);
});
console.log('Este log aparece antes da leitura assíncrona!');
Com Promises e async/await, o código assíncrono fica mais legível:
const fs = require('fs').promises;
async function lerArquivo() {
try {
const dados = await fs.readFile('arquivo.txt', 'utf-8');
console.log('Dados lidos:', dados);
} catch (erro) {
console.error('Erro ao ler arquivo:', erro);
}
}
lerArquivo();
4. Módulos nativos do Node.js
O Node.js vem com módulos nativos poderosos. O fs permite manipular arquivos:
const fs = require('fs');
// Escrever em um arquivo
fs.writeFileSync('mensagem.txt', 'Conteúdo salvo com Node.js!');
// Ler diretório
fs.readdir('.', (err, arquivos) => {
console.log('Arquivos no diretório atual:', arquivos);
});
O módulo path resolve problemas de caminhos entre sistemas operacionais:
const path = require('path');
const caminhoCompleto = path.join(__dirname, 'arquivos', 'dados.json');
console.log('Caminho completo:', caminhoCompleto);
console.log('Extensão:', path.extname('imagem.jpg'));
5. Criando um servidor HTTP básico
Com o módulo http, você cria um servidor web sem frameworks:
const http = require('http');
const servidor = http.createServer((req, res) => {
// Configurando cabeçalhos
res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' });
if (req.url === '/') {
res.end('<h1>Bem-vindo ao servidor Node.js!</h1>');
} else if (req.url === '/api') {
// Retornando JSON
res.writeHead(200, { 'Content-Type': 'application/json' });
res.end(JSON.stringify({ mensagem: 'API funcionando', status: 'ok' }));
} else {
res.writeHead(404);
res.end('<h1>404 - Página não encontrada</h1>');
}
});
servidor.listen(3000, () => {
console.log('Servidor rodando em http://localhost:3000');
});
Execute e acesse http://localhost:3000. Você criou um servidor HTTP funcional com poucas linhas de código.
6. Gerenciamento de dependências com npm
O npm (Node Package Manager) é o gerenciador de pacotes oficial. Inicie um projeto:
npm init -y
Isso cria o arquivo package.json. Instale pacotes:
npm install lodash
npm install express
O package.json agora lista as dependências, e a pasta node_modules armazena os pacotes baixados. Use-os no código:
const _ = require('lodash');
const numeros = [4, 2, 8, 1, 9];
console.log('Números ordenados:', _.sortBy(numeros));
7. Node.js no ecossistema React
React depende do Node.js para desenvolvimento e build. Ferramentas como Create React App, Vite e Next.js usam Node.js para:
- Compilar JSX para JavaScript puro
- Servir arquivos em ambiente de desenvolvimento com hot reload
- Gerar builds otimizados para produção
Exemplo: servindo um build estático do React com Node.js puro:
const http = require('http');
const fs = require('fs');
const path = require('path');
const servidor = http.createServer((req, res) => {
let caminhoArquivo = req.url === '/' ? 'index.html' : req.url.slice(1);
caminhoArquivo = path.join(__dirname, 'build', caminhoArquivo);
fs.readFile(caminhoArquivo, (err, conteudo) => {
if (err) {
res.writeHead(404);
res.end('Arquivo não encontrado');
return;
}
res.writeHead(200);
res.end(conteudo);
});
});
servidor.listen(5000, () => {
console.log('Aplicação React servida em http://localhost:5000');
});
8. Boas práticas e próximos passos
Em desenvolvimento, use nodemon para reiniciar automaticamente o servidor a cada alteração. Em produção, considere:
- Gerenciamento de erros com try/catch e logs estruturados
- Variáveis de ambiente para configurações sensíveis
- Process managers como PM2 para manter o servidor ativo
// Exemplo de log estruturado
const logger = {
info: (msg) => console.log(`[INFO] ${new Date().toISOString()} - ${msg}`),
erro: (msg) => console.error(`[ERRO] ${new Date().toISOString()} - ${msg}`)
};
logger.info('Servidor iniciado com sucesso');
Referências
- Documentação oficial do Node.js — Guia completo com todos os módulos nativos, APIs e tutoriais oficiais
- Node.js Tutorial - W3Schools — Tutorial introdutório com exemplos práticos para iniciantes
- The Node.js Event Loop - Node.js Documentation — Explicação detalhada do event-loop e modelo assíncrono
- npm Documentation — Guia oficial do gerenciador de pacotes, incluindo comandos e boas práticas
- Create React App Documentation — Como o Node.js é usado no ecossistema React para desenvolvimento e build
- Node.js Crash Course - Traversy Media — Videoaula gratuita cobrindo os fundamentos do Node.js na prática