Frontend → Caminho Node
Uma rampa de cinco estágios para engenheiros frontend se tornarem SMEs de Node: event loop, streams, primeira API com testes e um PR de capstone na segunda semana.
Busque em todas as páginas da documentação
Uma rampa de cinco estágios para engenheiros frontend se tornarem SMEs de Node: event loop, streams, primeira API com testes e um PR de capstone na segunda semana.
Cartão de receita de referência rápida - pronto para copiar e colar.
Caminho de aprendizado da Semana 1 (frontend → Node)
Dia 1-2 Event loop + IO não bloqueante ([Como o Node.js Funciona](../node-fundamentals/how-node-js-works.md))
Dia 3 Primeira rota Fastify + Zod + smoke test com curl
Dia 4 Teste de integração node:test com inject()
Dia 5 Capstone: POST /items com Postgres + migraçãoQuando usar isso:
Desenvolvedores frontend conhecem a thread única do navegador. Node é semelhante com uma reviravolta: pool de threads libuv para algumas operações de IO.
// RUIM: bloqueia o event loop ~2s em trabalho síncrono grande
import fs from "node:fs";
const data = fs.readFileSync("./huge.json", "utf8");
JSON.parse(data);
// BOM: async + stream ou worker
import fs from "node:fs/promises";
const data = await fs.readFile("./huge.json", "utf8");| Navegador | Servidor Node |
|---|---|
fetch no componente | await fetch ou consulta DB no manipulador |
| UI congela com trabalho síncrono longo | Todos os clientes travam com bloqueio do loop |
| Web Workers | Processo worker BullMQ |
bcrypt.hashSync síncrono vs bcrypt.hash assíncrono sob curl concorrenteRelacionado: Como o Node.js Funciona
import { createReadStream, createWriteStream } from "node:fs";
import { pipeline } from "node:stream/promises";
import { createGzip } from "node:zlib";
await pipeline(
createReadStream("export.csv"),
createGzip(),
createWriteStream("export.csv.gz")
);FileReader do frontend carrega na memória; streams do Node limitam o RSS em uploads/downloadsbufferizar o arquivo inteiro// test/items.test.ts
import { test } from "node:test";
import assert from "node:assert/strict";
import { buildApp } from "../src/app.js";
test("GET /items retorna array", async () => {
const app = await buildApp();
const res = await app.inject({ method: "GET", url: "/items" });
assert.equal(res.statusCode, 200);
assert.ok(Array.isArray(res.json()));
await app.close();
});inject() é como Testing Library para HTTP - sem navegador, sem porta abertanode:test + assertRelacionado: Fastify Basics | Testing Fastify Apps
// ERRADO: promessa flutuante em fire-and-forget
sendWelcomeEmail(user.id);
// CERTO: await ou fila explícita
await emailQueue.add("welcome", { userId: user.id });await db.transaction(async (tx) => {
await tx.order.create({ data: order });
await tx.inventory.decrement({ where: { sku }, data: { qty: 1 } });
});transaction()## Capstone: Fatia da API de Itens
- [ ] Migração: tabela items
- [ ] GET /items, POST /items com Zod
- [ ] Cobertura de node:test para 400 e 201
- [ ] Smoke test com curl na descrição do PR
- [ ] Sem segredos no diff| Hábito Frontend | Ajuste Node |
|---|---|
| Feedback instantâneo no navegador | Ler logs e curl, não apenas hot reload |
| Validação no lado do cliente é suficiente | Servidor deve validar com Zod |
| Estado no contexto React | Estado no Postgres + invalidação de cache |
| Implantar assets estáticos | Implantar API + ordem de migração importa |
Fastify 5 para novas contratações: schema-first, testes com inject(), Pino integrado. Express se o padrão de produção da equipe for Express - alinhe-se com o ADR.
CRUD + uma migração + exemplo de transação é o suficiente. A profundidade do ORM vem na semana 2-3 com pareamento de mentor.
Versões do Stack: Esta página foi escrita para Node.js 24.18.0 (Active LTS), npm 10+, TypeScript 5.6+, Express 5, Fastify 5 e NestJS 11.
Revisado por Chris St. John·Última atualização: 16 de jul. de 2026