Javascript

NPM: gerenciando pacotes e dependências Já leu

10 min de leitura

NPM: gerenciando pacotes e dependências
Uma das maiores vantagens do Node.js não é o que ele faz sozinho — é o que a comunidade construiu em cima dele. O NPM (Node Package Manager) é o maior repositório de código aberto do mundo, com mais de 2 milhões de pacot

Uma das maiores vantagens do Node.js não é o que ele faz sozinho — é o que a comunidade construiu em cima dele. O NPM (Node Package Manager) é o maior repositório de código aberto do mundo, com mais de 2 milhões de pacotes disponíveis. Autenticação, envio de email, validação de dados, geração de PDFs, conexão com bancos de dados — existe um pacote para tudo.

Neste artigo você vai aprender a gerenciar dependências com NPM, entender o package.json a fundo, trabalhar com scripts, e adotar boas práticas que fazem diferença em projetos reais.


O que é o NPM

O NPM tem três partes:

1. Registro (registry)
   Site: https://npmjs.com
   Repositório online com todos os pacotes publicados

2. CLI (command line interface)
   Ferramenta de linha de comando instalada com o Node
   Comando: npm

3. package.json
   Arquivo que descreve seu projeto e suas dependências

Iniciando um projeto

# Cria o package.json interativamente
npm init

# Cria com valores padrão (recomendado para começar rápido)
npm init -y

O package.json gerado:

{
  "name": "meu-projeto",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo "Error: no test specified" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC"
}

Instalando pacotes

# Instala e adiciona em "dependencies" (produção)
npm install express
npm install express mongoose dotenv

# Abreviação
npm i express

# Instala e adiciona em "devDependencies" (apenas desenvolvimento)
npm install --save-dev nodemon jest eslint
npm i -D nodemon jest

# Instala globalmente (disponível em qualquer projeto)
npm install -g nodemon
npm install -g typescript

# Instala versão específica
npm install express@4.18.2

# Instala a mais recente de uma versão maior
npm install express@4

# Instala de um repositório GitHub
npm install github:usuario/repositorio

O package.json em profundidade

{
  "name": "api-clientes",
  "version": "2.1.0",
  "description": "API REST para gerenciamento de clientes",
  "main": "src/index.js",
  "type": "module",

  "scripts": {
    "start": "node src/index.js",
    "dev": "nodemon src/index.js",
    "test": "jest --coverage",
    "test:watch": "jest --watch",
    "lint": "eslint src/",
    "lint:fix": "eslint src/ --fix",
    "build": "tsc",
    "db:migrate": "node src/db/migrate.js",
    "db:seed": "node src/db/seed.js"
  },

  "dependencies": {
    "express": "^4.18.2",
    "mongoose": "^7.6.0",
    "dotenv": "^16.3.1",
    "bcrypt": "^5.1.1",
    "jsonwebtoken": "^9.0.2",
    "zod": "^3.22.4"
  },

  "devDependencies": {
    "nodemon": "^3.0.2",
    "jest": "^29.7.0",
    "eslint": "^8.54.0",
    "@types/express": "^4.17.21"
  },

  "engines": {
    "node": ">=18.0.0",
    "npm": ">=9.0.0"
  },

  "keywords": ["api", "rest", "express", "mongodb"],
  "author": "Ricardo Matos <ricardo@email.com>",
  "license": "MIT",
  "repository": {
    "type": "git",
    "url": "https://github.com/usuario/api-clientes"
  }
}

Versionamento semântico — SemVer

Entender os números de versão é essencial para evitar quebras inesperadas:

MAJOR.MINOR.PATCH
  2  .  1  .  0

MAJOR → quebra compatibilidade com versões anteriores
MINOR → adiciona funcionalidade mantendo compatibilidade
PATCH → correção de bug, sem novas funcionalidades

Os prefixos no package.json:

{
  "dependencies": {
    "express": "4.18.2",    // exatamente esta versão
    "express": "~4.18.2",   // >= 4.18.2, < 4.19.0 (só patches)
    "express": "^4.18.2",   // >= 4.18.2, < 5.0.0  (minor e patches)
    "express": "*",          // qualquer versão (perigoso!)
    "express": ">=4.0.0",   // qualquer versão >= 4
    "express": "4.x"        // qualquer 4.x.x
  }
}

Na prática, ^ (caret) é o padrão — permite updates de minor e patch, mas não de major.


O package-lock.json — reprodutibilidade garantida

# Quando você roda npm install pela primeira vez,
# o NPM cria o package-lock.json

# Este arquivo registra a versão EXATA de cada pacote
# e de cada dependência das dependências (árvore completa)
// package-lock.json (trecho)
{
  "name": "meu-projeto",
  "version": "1.0.0",
  "lockfileVersion": 3,
  "packages": {
    "node_modules/express": {
      "version": "4.18.2",
      "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz",
      "integrity": "sha512-...",
      "dependencies": {
        "accepts": "~1.3.8",
        "body-parser": "1.20.1"
      }
    }
  }
}
# Instala as versões EXATAS do package-lock.json
# Use em produção e CI/CD para garantir reprodutibilidade
npm ci

# vs npm install → pode atualizar dentro das regras do ^

Regra de ouro: sempre commite o package-lock.json no Git. Nunca commite node_modules.


O node_modules e o .gitignore

# O node_modules pode ter centenas de MB
# NUNCA commite no Git

# .gitignore
node_modules/
.env
.env.local
dist/
build/
*.log
# Para restaurar os node_modules em outro computador:
git clone https://github.com/usuario/projeto
cd projeto
npm install  # lê o package.json e restaura tudo

Scripts NPM — automatizando tarefas

Os scripts são um dos recursos mais poderosos do NPM:

{
  "scripts": {
    "start": "node src/index.js",
    "dev": "nodemon src/index.js --watch src",
    "test": "jest",
    "test:coverage": "jest --coverage",
    "lint": "eslint .",
    "format": "prettier --write .",
    "clean": "rm -rf dist node_modules",
    "build": "npm run lint && npm run test && node build.js",
    "prepublish": "npm run build",
    "postinstall": "node scripts/setup.js"
  }
}
# Rodar scripts
npm start           # convenção para produção
npm test            # convenção para testes
npm run dev         # scripts customizados precisam de "run"
npm run lint
npm run build

# Hooks automáticos — executam antes/depois
# pre[script] → executa ANTES do script
# post[script] → executa DEPOIS do script
# npm run build → executa: prebuild → build → postbuild

Pacotes essenciais — os que você vai usar sempre

Desenvolvimento:

# Reinicia o servidor automaticamente ao salvar arquivos
npm i -D nodemon

# Linter — encontra problemas no código
npm i -D eslint

# Formatador — padroniza estilo de código
npm i -D prettier

# Framework de testes
npm i -D jest

Produção:

# Framework web
npm i express

# Variáveis de ambiente
npm i dotenv

# Validação de dados
npm i zod

# Hash de senhas
npm i bcrypt

# JWT (autenticação)
npm i jsonwebtoken

# ORM para MongoDB
npm i mongoose

# ORM para SQL
npm i prisma

# Requisições HTTP (alternativa ao fetch nativo)
npm i axios

# Datas e horas
npm i date-fns

dotenv — variáveis de ambiente

Nunca coloque senhas, tokens ou URLs de banco de dados diretamente no código:

# Instalar
npm i dotenv
# .env (nunca commite este arquivo!)
PORT=3000
NODE_ENV=development
DATABASE_URL=mongodb://localhost:27017/meuapp
JWT_SECRET=uma-string-secreta-muito-longa-e-aleatoria
EMAIL_HOST=smtp.gmail.com
EMAIL_USER=meu@email.com
EMAIL_PASS=senha-do-email
// No início da aplicação — antes de tudo
require("dotenv").config();
// ou com ES Modules:
import "dotenv/config";

// Agora process.env tem as variáveis do .env
const porta = process.env.PORT || 3000;
const dbUrl = process.env.DATABASE_URL;
const secret = process.env.JWT_SECRET;

if (!dbUrl) {
  console.error("❌ DATABASE_URL não definida!");
  process.exit(1);
}

console.log(`Rodando em modo: ${process.env.NODE_ENV}`);
# .env.example — versão sem valores reais, ESTE sim vai no Git
PORT=3000
NODE_ENV=development
DATABASE_URL=
JWT_SECRET=
EMAIL_HOST=
EMAIL_USER=
EMAIL_PASS=

nodemon — desenvolvimento ágil

Sem nodemon, você precisaria parar e reiniciar o servidor manualmente a cada mudança:

npm i -D nodemon
// package.json
{
  "scripts": {
    "dev": "nodemon src/index.js"
  }
}
// nodemon.json (configuração opcional)
{
  "watch": ["src"],
  "ext": "js,json",
  "ignore": ["src/tests/**"],
  "delay": 500,
  "env": {
    "NODE_ENV": "development"
  }
}
npm run dev
# [nodemon] watching path(s): src/**/*
# [nodemon] starting `node src/index.js`
# Servidor rodando na porta 3000
# (você salva um arquivo...)
# [nodemon] restarting due to changes...
# [nodemon] starting `node src/index.js`
# Servidor rodando na porta 3000

Comandos NPM essenciais

# ── Instalação ───────────────────────────────────
npm install                    # instala tudo do package.json
npm ci                         # instala versões exatas do lock
npm i pacote                   # instala e salva em dependencies
npm i -D pacote                # instala e salva em devDependencies
npm i -g pacote                # instala globalmente

# ── Remoção ──────────────────────────────────────
npm uninstall pacote           # remove e atualiza package.json
npm uninstall -g pacote        # remove global

# ── Atualização ──────────────────────────────────
npm update                     # atualiza tudo (dentro do semver)
npm update pacote              # atualiza pacote específico
npm outdated                   # lista pacotes desatualizados

# ── Informações ──────────────────────────────────
npm list                       # lista dependências instaladas
npm list --depth=0             # apenas nível 1 (sem transitivas)
npm info pacote                # informações do pacote no registry
npm search termo               # busca no registry

# ── Auditoria de segurança ────────────────────────
npm audit                      # verifica vulnerabilidades
npm audit fix                  # tenta corrigir automaticamente

# ── Cache ─────────────────────────────────────────
npm cache clean --force        # limpa o cache

# ── Publicação ───────────────────────────────────
npm login                      # autentica no registry
npm publish                    # publica o pacote
npm version patch              # incrementa patch (1.0.0 → 1.0.1)
npm version minor              # incrementa minor (1.0.0 → 1.1.0)
npm version major              # incrementa major (1.0.0 → 2.0.0)

Alternativas ao NPM

# Yarn — criado pelo Facebook, mais rápido no passado
npm i -g yarn
yarn add express
yarn add -D nodemon
yarn install

# pnpm — mais eficiente em espaço em disco
# usa links simbólicos para compartilhar pacotes entre projetos
npm i -g pnpm
pnpm add express
pnpm add -D nodemon
pnpm install

# bun — runtime e gerenciador de pacotes ultra-rápido (2023)
# compatível com NPM
bun add express
bun install

Para projetos novos em 2025, pnpm é uma excelente escolha pela eficiência. NPM ainda é o padrão da indústria e o mais universal.


Exemplo completo — estrutura de projeto profissional

meu-projeto/
├── src/
│   ├── index.js          # ponto de entrada
│   ├── config/
│   │   └── index.js      # configurações centralizadas
│   ├── routes/           # rotas da API
│   ├── controllers/      # lógica das rotas
│   ├── services/         # regras de negócio
│   ├── models/           # modelos de dados
│   └── utils/            # utilitários
├── tests/                # testes
├── .env                  # variáveis (não vai no Git)
├── .env.example          # modelo (vai no Git)
├── .gitignore
├── .eslintrc.json
├── nodemon.json
├── package.json
└── package-lock.json
// src/config/index.js — configuração centralizada
require("dotenv").config();

const config = {
  porta: Number(process.env.PORT) || 3000,
  nodeEnv: process.env.NODE_ENV || "development",
  dbUrl: process.env.DATABASE_URL,
  jwtSecret: process.env.JWT_SECRET,

  isDev: process.env.NODE_ENV === "development",
  isProd: process.env.NODE_ENV === "production",
  isTest: process.env.NODE_ENV === "test",
};

// Valida variáveis obrigatórias
const obrigatorias = ["DATABASE_URL", "JWT_SECRET"];
const faltando = obrigatorias.filter(v => !process.env[v]);

if (faltando.length > 0) {
  console.error(`❌ Variáveis de ambiente faltando: ${faltando.join(", ")}`);
  process.exit(1);
}

module.exports = config;

Tarefa para você

Crie um projeto Node.js do zero com a seguinte estrutura:

# 1. Inicie o projeto com npm init -y
# 2. Instale as dependências:
#    - dotenv (produção)
#    - nodemon (dev)
#    - date-fns (produção)

# 3. Configure os scripts:
#    - start: node src/index.js
#    - dev: nodemon src/index.js
#    - info: node src/info.js

# 4. Crie src/info.js que imprime:
#    - Nome e versão do projeto (lidos do package.json)
#    - Data e hora atual formatada com date-fns
#    - Variáveis de ambiente: PORT e NODE_ENV
#    - Informações do sistema: OS, Node version, memória

# 5. Crie um .env com PORT=3000 e NODE_ENV=development
# 6. Crie um .gitignore adequado
# 7. Crie um .env.example documentado

# Bônus: use o package.json como fonte de verdade
// src/info.js
const pkg = require("../package.json");
console.log(`${pkg.name} v${pkg.version}`);

Conclusão

Neste artigo você aprendeu:

  • O que é o NPM e suas três partes — registry, CLI e package.json
  • Como iniciar um projeto e instalar pacotes
  • O package.json em profundidade — campos, scripts e metadados
  • Versionamento semântico e os prefixos ^, ~ e *
  • A importância do package-lock.json para reprodutibilidade
  • Por que nunca commitar node_modules e como usar .gitignore
  • Scripts NPM e hooks automáticos
  • Os pacotes essenciais do ecossistema Node.js
  • Como usar dotenv para variáveis de ambiente de forma segura
  • nodemon para desenvolvimento ágil
  • Todos os comandos NPM que você vai usar no dia a dia
  • Alternativas ao NPM: Yarn, pnpm e bun
  • Como estruturar um projeto profissional

 

📚 Fontes e Referências

  • NPM Docs: https://docs.npmjs.com
  • NPM Registry: https://npmjs.com
  • Semantic Versioning — SemVer: https://semver.org
  • dotenv — Documentação: https://github.com/motdotla/dotenv
  • nodemon — Documentação: https://nodemon.io
  • pnpm — Documentação: https://pnpm.io
  • Node.js — package.json fields: https://nodejs.org/en/learn/getting-started/the-package-json-guide
  • Node.js Design Patterns — Mario Casciaro (Packt Publishing)
  • roadmap.sh — Node.js: https://roadmap.sh/nodejs
Comentários

Mais em Javascript

Revisão + Projeto: API tipada e testada
Revisão + Projeto: API tipada e testada

Chegamos ao fim do Módulo 5. Quatro artigos densos — testes com Jest, padroni...

Mini Projeto: Quiz Interativo
Mini Projeto: Quiz Interativo

Chegamos ao fim do M&oacute;dulo 2. Em sete artigos voc&ecirc; aprendeu a man...

Deploy: do código ao ar
Deploy: do código ao ar

Você sabe construir aplicações. Mas construir é apenas metade do trabalho — a...