Fundamentos de Scripts Node.js
11 exemplos para você começar com Node.js Scripts -- 8 básicos e 3 intermediários.
Busque em todas as páginas da documentação
11 exemplos para você começar com Node.js Scripts -- 8 básicos e 3 intermediários.
🤖 Read the SystemsArchitect.io Blog for over 100+ cloud architecture articles 🔥
Você precisa do Node.js 22 LTS ou mais recente. Verifique com node --version; instale via nvm, fnm ou Volta se você ainda não o tiver.
# Instale ou mude para o LTS atual com nvm
nvm install --lts
nvm use --lts
node --version # deve exibir v22.x ou superiorConvenções para cada exemplo abaixo:
package.json. Execute npm init -y uma vez para criar um.import/export). Defina "type": "module" em package.json.tsx -- sem etapa de compilação necessária durante o desenvolvimento.Uma linha para confirmar sua toolchain antes de escrever quaisquer scripts.
node --version # v22.15.0 ou similar
npm --version # 10.x ou similar
node -e "console.log('hello from node', process.version)"node -e "<code>" executa um trecho inline -- perfeito para testes de fumaça sem criar um arquivo.process.version relata a versão do Node em execução, para que você pegue problemas de versão incorreta imediatamente (por exemplo, um PATH antigo pegando um binário antigo).node estiver faltando, instale via nvm (macOS/Linux) ou fnm/Volta (multiplataforma) -- evite a instalação global do Homebrew em máquinas compartilhadas..nvmrc (ou .node-version) para que cada contribuidor execute o mesmo runtime.Relacionado: Instalando Node.js e npm -- nvm, fnm, Volta e a cadência LTS
O menor arquivo .js útil que você pode executar com node.
// hello.js
const greeting = "Hello, Node.js!";
console.log(greeting);Execute-o:
node hello.js.js com código válido é executado diretamente sob node -- sem bundler, sem configuração."type": "module" em package.json, os arquivos .js são tratados como ES Modules (import/export). Sem isso, eles são CommonJS (require/module.exports).node --watch hello.js durante o desenvolvimento para reexecutar ao salvar (nativo no Node 18+).process.argv contém argumentos da CLI; process.env contém variáveis de ambiente -- ambos estão sempre disponíveis.Relacionado: Executando Scripts JavaScript -- pontos de entrada, modo watch, linhas shebang | ESM vs CommonJS -- escolhendo o sistema de módulos
Pule a etapa de compilação em desenvolvimento -- tsx executa arquivos .ts diretamente.
npm install --save-dev tsx typescript @types/node// sum.ts
function sum(a: number, b: number): number {
return a + b;
}
console.log(sum(2, 3));Execute-o:
npx tsx sum.tstsx usa esbuild internamente -- inicialização rápida e o mesmo comportamento de remoção de tipos de compilações de produção.tsx watch sum.ts para um loop de desenvolvimento com live-reload; use npx tsc apenas quando quiser produzir saída .js para implantação.@types/node para que os built-ins como fs, path e process sejam tipados.node --experimental-strip-types sum.ts) -- um bom fallback quando você não pode adicionar tsx.Relacionado: Executando Scripts TypeScript -- tsx vs ts-node vs remoção nativa | ESLint para Scripts Node.js -- conectando lint a um projeto de script TS
Ambas as ferramentas usam o mesmo package.json; pnpm é mais rápido e eficiente em disco.
# npm
npm install zod
npm install --save-dev tsx
# pnpm (habilite via Corepack, nenhuma instalação global necessária)
corepack enable
pnpm add zod
pnpm add -D tsxpackage.json é a fonte da verdade -- ambas as ferramentas o leem/escrevem. Mudar entre elas é seguro se sua equipe concordar em usar uma de cada vez.package-lock.json para npm, pnpm-lock.yaml para pnpm. Exclua o outro.corepack para fixar a versão exata do gerenciador de pacotes em packageManager para que CI e laptops permaneçam alinhados.Relacionado: pnpm vs npm -- workspaces, hoisting e comparação de desempenho
Use o sistema de módulos moderno -- imports estáticos, await de nível superior, exports nomeados.
// package.json
{
"type": "module"
}// math.ts
export function sum(a: number, b: number) {
return a + b;
}// app.ts
import { sum } from "./math.js";
console.log(sum(2, 3));"type": "module" em package.json para que arquivos .js/.ts sejam ESM por padrão../math.js mesmo quando a fonte é math.ts.await de nível superior é permitido em ESM: const data = await fetch(...) no topo de um arquivo funciona.Relacionado: ESM vs CommonJS -- regras de interoperabilidade,
createRequiree quando CJS ainda faz sentido
Leia e escreva arquivos assincronamente -- a API recomendada desde o Node 14.
// read-config.js
import { readFile, writeFile } from "node:fs/promises";
const text = await readFile("config.json", "utf8");
const config = JSON.parse(text);
config.apiUrl = config.apiUrl.replace("http:", "https:");
await writeFile("config.json", JSON.stringify(config, null, 2));// read-config.ts
import { readFile, writeFile } from "node:fs/promises";
const text = await readFile("config.json", "utf8");
const config = JSON.parse(text) as { apiUrl: string };
config.apiUrl = config.apiUrl.replace("http:", "https:");
await writeFile("config.json", JSON.stringify(config, null, 2));fs/promises retorna Promises -- combine com await de nível superior para scripts limpos."utf8"); omita-a apenas se você quiser um Buffer.node: (node:fs, node:path, node:url) -- não ambíguo e funciona em ESM e CJS.createReadStream) ou readline em vez de bufferizar o arquivo inteiro na memória.Relacionado: Scripts Utilitários -- E/S de arquivos, caminhos, globs e receitas de script
Use parseArgs do node:util -- built-in, tipado, sem dependência extra.
// greet.ts
import { parseArgs } from "node:util";
const { values } = parseArgs({
options: {
name: { type: "string", short: "n", default: "world" },
shout: { type: "boolean", short: "s", default: false },
},
});
const greeting = `Hello, ${values.name}!`;
console.log(values.shout ? greeting.toUpperCase() : greeting);Execute:
npx tsx greet.ts --name Ada --shout
# HELLO, ADA!parseArgs é built-in no Node 18+ -- não há necessidade de yargs ou commander para a maioria dos scripts.short: "n" permite que os chamadores passem -n Ada em vez de --name Ada.values (flags analisadas) e positionals (argumentos restantes) -- ambos totalmente tipados a partir do esquema.commander ou oclif.Relacionado: Scripts Utilitários -- padrões de CLI, prompts, códigos de saída
Pub/sub dentro de um único processo -- a base para streams, servidores HTTP e eventos personalizados.
// pubsub.js
import { EventEmitter } from "node:events";
const bus = new EventEmitter();
bus.on("login", (userId) => {
console.log(`User ${userId} logged in`);
});
bus.emit("login", "u_123");
bus.emit("login", "u_456");// pubsub.ts
import { EventEmitter } from "node:events";
interface Events {
login: [userId: string];
logout: [userId: string];
}
const bus = new EventEmitter<Events>();
bus.on("login", (userId) => {
console.log(`User ${userId} logged in`);
});
bus.emit("login", "u_123");
bus.emit("login", "u_456");emit(name, ...args) chama cada listener registrado com on(name, handler) na ordem de registro.EventEmitter<T> tipado (Node 22+) para obter verificação em tempo de compilação de nomes e payloads de eventos.off(name, handler) em processos de longa duração -- listeners esquecidos vazam memória.on adiciona um listener persistente; once dispara e depois se remove -- escolha o certo para evitar manipuladores duplicados.Relacionado: Padrões EventEmitter -- eventos tipados, vazamentos, iteração assíncrona
Zero dependências -- sirva JSON do módulo http embutido.
// server.ts
import { createServer } from "node:http";
const server = createServer((req, res) => {
if (req.url === "/health") {
res.writeHead(200, { "content-type": "application/json" });
res.end(JSON.stringify({ ok: true, uptime: process.uptime() }));
return;
}
res.writeHead(404).end("Not Found");
});
const port = Number(process.env.PORT ?? 3000);
server.listen(port, () => {
console.log(`http://localhost:${port}`);
});createServer retorna um EventEmitter -- você também pode escutar "request", "connection", "close" diretamente.res.writeHead antes de res.end; res.end fecha a conexão.process.on("SIGTERM", () => server.close(...)) para que orquestradores de contêineres possam desligá-lo graciosamente.Relacionado: Criando Servidores HTTP -- node:http, Express e Fastify lado a lado
API familiar, ecossistema enorme -- a escolha padrão para a maioria dos serviços Node.js.
npm install express
npm install --save-dev @types/express// app.js
import express from "express";
const app = express();
app.use(express.json());
app.post("/users", (req, res) => {
const { email } = req.body;
if (!email?.includes("@")) {
return res.status(400).json({ error: "Invalid email" });
}
res.status(201).json({ id: crypto.randomUUID(), email });
});
app.listen(3000, () => console.log("http://localhost:3000"));// app.ts
import express, { type Request, type Response } from "express";
const app = express();
app.use(express.json());
interface CreateUserBody {
email: string;
}
app.post("/users", (req: Request<{}, unknown, CreateUserBody>, res: Response) => {
const { email } = req.body;
if (!email?.includes("@")) {
return res.status(400).json({ error: "Invalid email" });
}
res.status(201).json({ id: crypto.randomUUID(), email });
});
app.listen(3000, () => console.log("http://localhost:3000"));express.json() analisa corpos de requisição application/json -- sem ele, req.body é undefined.Request (Params, ResBody, ReqBody, Query) para que os manipuladores sejam totalmente tipados de ponta a ponta.zod ou valibot dentro do manipulador para validar corpos em vez de confiar no cliente.Relacionado: Criando Servidores HTTP -- Express vs Fastify vs node:http tradeoffs | ESLint para Scripts Node.js -- regras recomendadas para código de servidor
ESLint 9+ moderno usa eslint.config.js (flat config) -- mais enxuto, mais rápido, ciente de tipos.
npm install --save-dev \
eslint typescript-eslint @eslint/js globals// eslint.config.js
import js from "@eslint/js";
import tseslint from "typescript-eslint";
import globals from "globals";
export default tseslint.config(
js.configs.recommended,
...tseslint.configs.recommendedTypeChecked,
{
languageOptions: {
parserOptions: { projectService: true },
globals: { ...globals.node },
},
rules: {
"no-console": ["warn", { allow: ["warn", "error"] }],
},
},
);Execute:
npx eslint .
npx eslint . --fix.eslintrc.* e .eslintignore -- muito menos para aprender.recommendedTypeChecked ativa regras cientes de tipos (requer projectService: true), que detectam any inseguro e uso incorreto de promessas.globals.node ensina ESLint sobre process, Buffer, __dirname, etc., para que eles não acionem "no-undef".lint do npm para que a CI possa falhar rapidamente em erros de estilo e tipo.Relacionado: ESLint para Scripts Node.js -- recomendações de regras, configuração ciente de tipos, padrões de ignore | Configuração ESLint (Linting & Formatação) -- referência mais ampla do ESLint
Revisado por Chris St. John·Última atualização: 16 de jul. de 2026
🤖 Read the SystemsArchitect.io Blog for over 100+ cloud architecture articles 🔥