Programação Web

Introdução ao Node.js e Setup de Projeto MVC com Express

Nesta página você vai ter um primeiro contato com o Node.js, entender o modelo assíncrono, o event loop Mecanismo interno do Node.js que organiza a execução do código JavaScript, chamando callbacks de forma assíncrona conforme eventos e operações de I/O são concluídos. , módulos, NPM e package.json, e em seguida montar o esqueleto do projeto do semestre em Node + Express, já organizado em MVC.

1. O que é Node.js?

Node.js é um ambiente de execução de JavaScript fora do navegador, construído sobre o motor V8 do Google Chrome O V8 é o motor que executa JavaScript. Em termos simples, ele lê o código JavaScript, prepara esse código para execução e o roda de forma eficiente. O Chrome usa o V8 no navegador, e o Node.js também usa esse mesmo motor para executar JavaScript fora do browser. e focado em aplicações de rede rápidas e escaláveis.

Em vez de usar JavaScript apenas para interagir com o DOM no browser, com Node.js podemos criar servidores HTTP, lidar com arquivos, acessar bancos de dados e construir APIs completas usando a mesma linguagem do front-end.

Para lembrar: pense no Node.js como um “cérebro de back-end” que entende JavaScript. No front-end, o navegador cuida da interface. No back-end, o Node cuida das regras de negócio, acesso a dados e comunicação com outros sistemas.
Como nas aulas anteriores você já escreveu funções, usou if, for e arrays em JavaScript, já tem a base necessária. O que muda agora é o ambiente de execução e as bibliotecas a serem usadas.

2. Modelo assíncrono e Event Loop

2.1. Execução single-thread e I/O não bloqueante

O Node.js executa JavaScript em uma única thread, mas consegue lidar com muitas conexões simultâneas porque delega operações de I/O (leitura de arquivos, acesso a rede) ao sistema operacional e usa um modelo assíncrono baseado em eventos.

Bloqueante
O código espera a operação terminar para continuar (ex.: ler um arquivo grande de forma síncrona).
Não bloqueante
O código dispara a operação e registra um callback para ser chamado quando o resultado ficar pronto.

2.2. O que é o Event Loop?

O event loop é o mecanismo interno que controla a ordem em que o Node.js executa o código, processa callbacks assíncronos e lida com timers e I/O.

Fluxo simplificado do event loop
  1. Seu script é carregado e o código síncrono é executado linha a linha.
  2. Chamadas assíncronas (como timers e I/O) são registradas e delegadas a APIs do sistema.
  3. Quando essas operações terminam, callbacks são colocados em filas de eventos.
  4. O event loop passa por fases organizadas (timers, I/O callbacks, etc.), esvaziando filas e executando callbacks.

2.3. Exemplo prático: setTimeout vs. código síncrono

Observe este pequeno script em Node:


// arquivo: exemplo-event-loop.js

console.log("Início");

setTimeout(() => {
  console.log("Timeout executado");
}, 0);

console.log("Fim");
        

Ordem da saída:

  • Início
  • Fim
  • Timeout executado

Mesmo com setTimeout(..., 0), o callback só roda depois que o código síncrono terminou, porque o event loop primeiro esvazia a pilha principal e só depois trata a fila de timers.

3. Módulos, NPM e package.json

3.1. Módulos em Node.js

Em Node.js organizamos o código em módulos, que são arquivos separados que exportam funções, objetos ou classes para serem reutilizados em outras partes da aplicação.


// arquivo: matematica.js
function soma(a, b) {
  return a + b;
}

module.exports = soma;

// arquivo: app.js
const soma = require("./matematica");

console.log(soma(2, 3)); // 5
        

Além de módulos próprios, o Node fornece módulos internos (como fs para arquivos, http para servidores) e permite instalar módulos de terceiros via NPM.

3.2. O que é o NPM?

O NPM (Node Package Manager) é o gerenciador de pacotes padrão do Node.js, usado para instalar bibliotecas, gerenciar versões e dependências de um projeto.

Comandos básicos:

  • npm init – cria um arquivo package.json interativamente.
  • npm init -y – cria um package.json com respostas padrão.
  • npm install express – instala o Express e adiciona em dependencies.
  • npm install nodemon --save-dev – instala o Nodemon como dependência de desenvolvimento.

3.3. Arquivo package.json

O package.json descreve o projeto Node: nome, versão, ponto de entrada, scripts de execução e lista de dependências.


{
  "name": "meu-projeto-node",
  "version": "1.0.0",
  "main": "server.js",
  "scripts": {
    "start": "node server.js",
    "dev": "nodemon server.js"
  },
  "dependencies": {
    "express": "^4.19.0"
  },
  "devDependencies": {
    "nodemon": "^3.1.0"
  }
}
        
Sempre que você instalar um pacote com npm install <nome>, verifique se o campo dependencies (ou devDependencies) foi atualizado no package.json.
Para estudar: crie uma pasta vazia, rode npm init -y, abra o package.json, instale express e nodemon, e teste os scripts npm start e npm run dev.
Passo a passo no laboratório do IFC:
  1. Ligue o computador, abra o editor de código disponível no laboratório (por exemplo, VS Code) e abra também o terminal integrado.
  2. Escolha ou crie uma pasta para salvar o projeto, por exemplo Documentos ou uma pasta da disciplina.
  3. No terminal, navegue até essa pasta com o comando cd. Exemplo: cd Documents ou cd Documentos.
  4. Crie uma pasta vazia para o projeto com mkdir projeto-node e entre nela com cd projeto-node.
  5. Confirme que você está na pasta correta com dir (Windows) ou ls. Nesse momento, ela deve estar vazia.
  6. Execute npm init -y para gerar automaticamente o arquivo package.json com a configuração inicial do projeto.
  7. Abra o arquivo package.json no editor e observe campos como name, version, main e scripts.
  8. Instale o Express com npm install express.
  9. Instale o Nodemon com npm install --save-dev nodemon, pois ele será usado durante o desenvolvimento para reiniciar o servidor automaticamente quando houver alterações nos arquivos.
  10. Edite o package.json e configure os scripts, por exemplo:
"scripts": {
          "start": "node server.js",
          "dev": "nodemon server.js"
        }
  1. Crie o arquivo server.js na raiz do projeto.
  2. No terminal, execute npm start para testar a execução normal do projeto pelo Node.
  3. Depois execute npm run dev para testar a execução com o Nodemon.
  4. Faça uma pequena alteração no arquivo server.js e salve. Observe se o Nodemon reinicia automaticamente o projeto no terminal.
  5. Se algum comando não funcionar, confira primeiro se o terminal está dentro da pasta do projeto e se os arquivos package.json e server.js realmente existem nela.

4. Organização básica de um projeto Node

Em projetos pequenos é comum começar com poucos arquivos, mas conforme a aplicação cresce, é importante separar responsabilidades em pastas como routes, controllers, models e views (padrão MVC).

Cenário “bagunçado”

Um único arquivo server.js contendo rotas, regras de negócio, acesso a banco e configurações de servidor misturados, difícil de testar e manter.

Com organização MVC

Arquivos separados: cada rota chama um controller, controllers usam models para dados, views cuidam da renderização, deixando o código mais modular e sustentável.


meu-projeto/
├── package.json
├── server.js
├── src/
│   ├── routes/
│   ├── controllers/
│   ├── models/
│   └── views/
└── node_modules/
        
Para estudar: desenhe em papel o fluxo: cliente → rota → controller → model → view → resposta e escreva em uma frase o papel de cada camada no seu próprio vocabulário.

5. Prática: Setup do projeto do semestre (Node + Express + MVC)

Agora vamos montar, passo a passo, o esqueleto do projeto do semestre usando Node.js, Express e uma estrutura básica em MVC.

Sugerido para ~3 horas de prática: faça com calma, rodando pequeno trecho por vez, sempre testando no navegador ou via linha de comando. A ideia é sair com o servidor rodando, uma rota simples e as pastas principais do projeto organizadas.

Passo 1 – Preparar o ambiente

  1. Verifique se o Node.js está instalado: no terminal, execute node -v e npm -v.
  2. Se não estiver, instale a versão LTS a partir do site oficial do Node.js e reinicie o terminal.
  3. Crie uma pasta para o projeto do semestre, por exemplo projeto-semestral-mvc.

Passo 2 – Iniciar o projeto Node

No terminal, dentro da pasta do projeto:


cd projeto-semestral-mvc

# cria o package.json com valores padrão
npm init -y
          

Abra o package.json e confira os campos gerados automaticamente, como name, version, main e scripts.

Passo 3 – Instalar Express e Nodemon

Ainda na pasta do projeto, rode:


# dependência de produção
npm install express

# dependência de desenvolvimento (reinicia servidor automaticamente)
npm install --save-dev nodemon
          

Depois disso, verifique que express aparece em dependencies e nodemon em devDependencies do package.json.

Passo 4 – Configurar scripts de execução

Edite o package.json e ajuste a seção scripts para algo como:


"scripts": {
  "start": "node server.js",
  "dev": "nodemon server.js"
}
          

Uso:

  • npm start – executa o servidor uma vez com Node.
  • npm run dev – executa o servidor com Nodemon, reiniciando a cada alteração de arquivo.

Passo 5 – Criar o servidor básico com Express

Na raiz do projeto, crie o arquivo server.js com o seguinte conteúdo:


// server.js
const express = require("express");
const path = require("path");

const app = express();
const port = 3000;

// middleware para servir arquivos estáticos (CSS, imagens, etc.)
app.use(express.static(path.join(__dirname, "public")));

// rota básica de teste
app.get("/", (req, res) => {
  res.send("Servidor Express funcionando!");
});

// inicia o servidor
app.listen(port, () => {
  console.log(`Servidor rodando em http://localhost:${port}`);
});
          

No terminal, rode npm run dev e acesse http://localhost:3000 no navegador para verificar se o texto “Servidor Express funcionando!” aparece.

Passo 6 – Criar a estrutura de pastas em MVC

Dentro da pasta do projeto, crie a seguinte estrutura:


projeto-semestral-mvc/
├── package.json
├── server.js
├── src/
│   ├── routes/
│   ├── controllers/
│   ├── models/
│   └── views/
└── public/
    └── css/
        └── style.css
          

Essa organização segue o padrão MVC, separando rotas, controllers, models e views, e deixando o CSS em uma pasta pública para o front-end.

Passo 7 – Criar uma rota, um controller e uma view simples

7.1. Criar a view inicial

Em src/views/, crie o arquivo home.html:


<!DOCTYPE html>
<html lang="pt-BR">
<head>
  <meta charset="UTF-8" />
  <title>Projeto do Semestre</title>
  <link rel="stylesheet" href="/css/style.css" />
</head>
<body>
  <h1>Bem-vindo(a) ao projeto do semestre</h1>
  <p>Esta é a página inicial renderizada pelo servidor Express.</p>
</body>
</html>
              
7.2. Criar o controller

Em src/controllers/, crie homeController.js:


// src/controllers/homeController.js
const path = require("path");

function getHome(req, res) {
  const filePath = path.join(__dirname, "..", "views", "home.html");
  res.sendFile(filePath);
}

module.exports = {
  getHome,
};
              
7.3. Criar a rota

Em src/routes/, crie homeRoutes.js:


// src/routes/homeRoutes.js
const express = require("express");
const router = express.Router();
const homeController = require("../controllers/homeController");

router.get("/", homeController.getHome);

module.exports = router;
              
7.4. Conectar as rotas no server.js

Atualize o server.js para usar as rotas:


// server.js
const express = require("express");
const path = require("path");
const homeRoutes = require("./src/routes/homeRoutes");

const app = express();
const port = 3000;

app.use(express.static(path.join(__dirname, "public")));

// usa o conjunto de rotas da home
app.use("/", homeRoutes);

app.listen(port, () => {
  console.log(`Servidor rodando em http://localhost:${port}`);
});
              

Recarregue http://localhost:3000. Você deve ver o HTML da view home.html, provando que o fluxo MVC básico está funcionando:

rota "/" → homeController.getHome → home.html → resposta ao navegador.

Passo 8 – Ligar com o CSS externo

Copie o conteúdo do seu style.css para public/css/style.css e garanta que o caminho no home.html é /css/style.css, já que estamos servindo a pasta public como estática com Express.

Assim você mantém separação clara entre back-end (Node/Express) e front-end (HTML/CSS), mas ainda dentro do mesmo projeto Node.
Para o projeto: 1) Identificar as rotas com seu próprio controller e view; 2) Definir o link de navegação entre as páginas; 3) Nomear, quais responsabilidades devem existir em cada camada (rota, controller, view) já pensando nas próximas iterações do projeto.
Introdução ao Node.js e setup de projeto MVC com Express.