15 Gerenciamento de Pacotes com npm/Yarn
O objetivo é que você compreenda como gerenciar pacotes de forma eficiente, organize dependências e automatize tarefas com scripts, preparando-se para projetos escaláveis. O material é dividido em duas partes: uma teoria detalhada sobre npm, Yarn e package.json, seguida de um exemplo prático que demonstra a integração da biblioteca lodash em um projeto Node.js.
15.1 Teoria: Estrutura do package.json, Dependências e Scripts npm/Yarn
15.1.1 Introdução ao Gerenciamento de Pacotes
No desenvolvimento Node.js, pacotes são bibliotecas ou módulos reutilizáveis que adicionam funcionalidades ao seu projeto, como manipulação de dados, criação de APIs ou automação de tarefas. O npm (Node Package Manager) é a ferramenta padrão do Node.js para gerenciar esses pacotes, enquanto o Yarn é uma alternativa popular que oferece melhor performance e funcionalidades adicionais. Ambos permitem instalar, atualizar e remover pacotes, além de gerenciar dependências e executar scripts personalizados.
O npm é instalado automaticamente com o Node.js e dá acesso ao maior repositório de pacotes open-source do mundo, o npm registry (npmjs.com), com milhões de pacotes disponíveis, como lodash, express e jest. O Yarn, desenvolvido pelo Facebook, é compatível com o npm registry, mas introduz recursos como instalação offline e maior determinismo.
O coração do gerenciamento de pacotes é o arquivo package.json, que define as configurações do projeto, dependências e scripts. Vamos explorar cada aspecto em detalhes.
15.1.2 O Arquivo package.json
O package.json é um arquivo JSON que serve como o manifesto do seu projeto Node.js. Ele contém metadados, dependências e scripts, garantindo que o projeto seja portátil e reproduzível em diferentes ambientes. O arquivo é criado automaticamente ao executar npm init ou yarn init.
15.1.2.1 Estrutura do package.json
Aqui está um exemplo típico de package.json:
{
"name": "meu-projeto",
"version": "1.0.0",
"description": "Um projeto Node.js de exemplo",
"main": "index.js",
"type": "module",
"scripts": {
"start": "node index.js",
"dev": "nodemon index.js",
"test": "jest"
},
"keywords": ["node", "javascript"],
"author": "Seu Nome",
"license": "MIT",
"dependencies": {
"lodash": "^4.17.21",
"express": "^4.18.2"
},
"devDependencies": {
"nodemon": "^3.0.1",
"jest": "^29.7.0"
}
}Campos principais:
name: Nome do projeto ou pacote. Deve ser único se publicado no npm registry (ex.:"meu-projeto").version: Versão do projeto, seguindo o padrão SemVer (Semantic Versioning, ex.:1.0.0).description: Breve descrição do projeto, útil para documentação e publicação.main: Arquivo de entrada do projeto (ex.:index.js).type: Define o sistema de módulos ("module"para ES Modules ou"commonjs"para CommonJS).scripts: Comandos personalizados executados comnpm run <script>ouyarn <script>.keywords: Palavras-chave para facilitar a busca no npm registry.author: Nome do autor (ex.:"Seu Nome <seu.email@example.com>").license: Licença do projeto (ex.:"MIT","ISC").dependencies: Pacotes necessários para a execução do projeto.devDependencies: Pacotes usados apenas em desenvolvimento ou testes.
15.1.2.2 Semantic Versioning (SemVer)
As versões de pacotes no package.json seguem o padrão SemVer: MAJOR.MINOR.PATCH. Exemplos:
1.0.0: Versão inicial.1.1.0: Adiciona novas funcionalidades (MINOR), mas mantém compatibilidade.2.0.0: Introduz mudanças incompatíveis (MAJOR).1.0.1: Corrige bugs (PATCH) sem alterar funcionalidades.
Símbolos de versão: - ^4.17.21: Permite atualizações de MINOR e PATCH (ex.: 4.x.x). - ~4.17.21: Permite apenas atualizações de PATCH (ex.: 4.17.x). - 4.17.21: Versão exata, sem atualizações automáticas.
15.1.2.3 Criando o package.json
Com npm:
npm initResponda às perguntas interativas (nome, versão, etc.) ou use:
npm init -ypara criar com valores padrão.
Com Yarn:
yarn initou:
yarn init -y
15.1.3 Gerenciamento de Dependências
Dependências são pacotes externos listados no package.json. Elas são divididas em dois tipos:
dependencies: Pacotes necessários para a execução do projeto em produção (ex.:express,lodash).devDependencies: Pacotes usados apenas em desenvolvimento ou testes (ex.:nodemon,jest).
15.1.3.1 Instalando Dependências
Com npm:
npm install lodash # Ou, abreviado: npm i lodashPara dependências de desenvolvimento:
npm install --save-dev nodemon # Ou: npm i -D nodemonCom Yarn:
yarn add lodashPara dependências de desenvolvimento:
yarn add --dev nodemon
Ao instalar, o pacote é baixado para a pasta node_modules, e a versão é registrada no package.json.
15.1.3.2 O Arquivo package-lock.json (npm) ou yarn.lock (Yarn)
package-lock.json: Gerado pelo npm, ele trava as versões exatas de todas as dependências (incluindo subdependências), garantindo consistência entre ambientes.yarn.lock: Equivalente no Yarn, com o mesmo propósito.
Boas práticas: - Sempre versione esses arquivos no Git para garantir builds reproduzíveis. - Evite editar manualmente; use comandos como npm install ou yarn add.
15.1.3.3 Atualizando Dependências
Com npm:
npm updateAtualiza dependências dentro das faixas permitidas no
package.json. Para verificar pacotes desatualizados:npm outdatedCom Yarn:
yarn upgradePara verificar pacotes desatualizados:
yarn outdated
15.1.3.4 Removendo Dependências
Com npm:
npm uninstall lodashCom Yarn:
yarn remove lodash
15.1.3.5 Dependências Globais
Pacotes globais são instalados no sistema e podem ser usados em qualquer projeto:
npm:
npm install -g nodemonYarn:
yarn global add nodemon
Nota: Evite dependências globais em projetos reproduzíveis, pois elas podem causar inconsistências. Prefira dependências locais.
15.1.4 Scripts no package.json
O campo scripts no package.json permite definir comandos personalizados para automatizar tarefas, como iniciar o servidor, rodar testes ou formatar código.
15.1.4.1 Exemplo de Scripts
"scripts": {
"start": "node index.js",
"dev": "nodemon index.js",
"test": "jest",
"lint": "eslint .",
"build": "tsc"
}start: Executado comnpm startouyarn start. Usado para iniciar a aplicação em produção.dev: Executado comnpm run devouyarn dev. Usado para desenvolvimento com ferramentas comonodemon.test: Executado comnpm testouyarn test. Usado para rodar testes.lint: Verifica a qualidade do código com ESLint.build: Compila TypeScript (se aplicável).
15.1.4.2 4.2. Executando Scripts
npm:
npm start npm run devYarn:
yarn start yarn dev
Nota: start e test não exigem run, mas outros scripts sim.
15.1.4.3 4.3. Scripts Pré e Pós
Você pode definir scripts que rodam automaticamente antes (pre) ou depois (post) de outro script:
"scripts": {
"prestart": "npm run lint",
"start": "node index.js",
"poststart": "echo 'Servidor iniciado!'"
}Executar npm start rodará prestart, start e poststart na ordem.
15.1.5 5. npm vs. Yarn: Diferenças e Quando Usar
Embora npm e Yarn sejam semelhantes, eles têm diferenças importantes:
| Característica | npm | Yarn |
|---|---|---|
| Performance | Melhorou nas versões recentes (v10+) | Geralmente mais rápido |
| Lockfile | package-lock.json |
yarn.lock |
| Instalação Offline | Suporte parcial | Cache offline robusto |
| Determinismo | Bom, mas Yarn é mais consistente | Altamente determinístico |
| Comandos | npm install, npm run |
yarn add, yarn |
| Workspaces | Suporte básico | Suporte avançado para monorepos |
| Popularidade em 2025 | Padrão, amplamente usado | Preferido em projetos grandes |
15.1.5.1 5.1. Quando Usar npm?
- Projetos simples ou iniciantes, onde a simplicidade é prioridade.
- Quando você já usa o npm registry e não precisa de recursos avançados.
- Projetos que não requerem monorepos ou instalação offline.
15.1.5.2 5.2. Quando Usar Yarn?
- Projetos grandes ou monorepos (ex.: múltiplos pacotes em um repositório).
- Quando você precisa de instalação rápida e determinística.
- Projetos que exigem cache offline ou suporte avançado a workspaces.
- Equipes que preferem uma interface de comando mais amigável.
Em 2025, ambos são excelentes escolhas, mas npm é suficiente para a maioria dos projetos devido às melhorias recentes, enquanto Yarn é preferido em projetos complexos.
15.1.6 6. Boas Práticas para Gerenciamento de Pacotes
- Mantenha o
package.jsonLimpo:- Remova dependências não utilizadas com
npm pruneouyarn autoclean. - Use nomes descritivos e atualize metadados (ex.:
description,author).
- Remova dependências não utilizadas com
- Versione o Lockfile:
- Inclua
package-lock.jsonouyarn.lockno Git para builds consistentes.
- Inclua
- Evite Dependências Desnecessárias:
- Verifique se um pacote é realmente necessário antes de instalá-lo.
- Use ferramentas como
depcheckpara identificar dependências não usadas.
- Atualize Regularmente:
- Use
npm outdatedouyarn outdatedpara identificar pacotes desatualizados. - Teste atualizações em um ambiente de desenvolvimento antes de aplicar em produção.
- Use
- Use Scripts para Automação:
- Crie scripts para tarefas comuns (ex.: linting, testes, build).
- Combine ferramentas como
nodemon,eslintejestpara produtividade.
- Segurança:
Use
npm auditouyarn auditpara identificar vulnerabilidades:npm audit npm audit fixMonitore pacotes com ferramentas como Dependabot (GitHub).
15.2 Exemplo Prático: Instalar e Usar a Biblioteca lodash
Neste exemplo prático, vamos criar um projeto Node.js, instalar a biblioteca lodash (uma biblioteca utilitária popular para manipulação de arrays, objetos e strings), e usá-la para realizar operações comuns, como agrupamento e filtragem de dados. Implementaremos o exemplo com npm e mostraremos como replicar com Yarn.
15.2.1 Objetivo do Exemplo
- Configurar um projeto Node.js com
package.json. - Instalar a biblioteca
lodashcomo dependência. - Criar um script que usa funções do
lodashpara manipular uma lista de objetos. - Executar o projeto com scripts personalizados.
15.2.2 Passo 1: Configurar o Projeto
Crie uma nova pasta para o projeto:
mkdir lodash-exemplo cd lodash-exemplo npm init -yO
package.jsonserá criado:{ "name": "lodash-exemplo", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "keywords": [], "author": "", "license": "ISC" }(Opcional) Para usar ES Modules, adicione:
"type": "module"Instale o
nodemoncomo dependência de desenvolvimento:npm install --save-dev nodemonAtualize os scripts no
package.json:"scripts": { "start": "node index.js", "dev": "nodemon index.js" }
15.2.3 Passo 2: Instalar a Biblioteca lodash
Instale o
lodashcomo dependência de produção:npm install lodashVerifique o
package.jsonatualizado:{ "name": "lodash-exemplo", "version": "1.0.0", "description": "", "main": "index.js", "type": "module", "scripts": { "start": "node index.js", "dev": "nodemon index.js" }, "keywords": [], "author": "", "license": "ISC", "dependencies": { "lodash": "^4.17.21" }, "devDependencies": { "nodemon": "^3.0.1" } }O
package-lock.jsontambém será gerado, travando as versões exatas.
15.2.4 Passo 3: Criar o Script com lodash
Crie um arquivo
index.js(ouindex.mjspara ES Modules):// index.mjs (para ES Modules) import _ from 'lodash'; // Lista de exemplo: dados de usuários const usuarios = [ { id: 1, nome: 'Alice', idade: 25, cidade: 'São Paulo' }, { id: 2, nome: 'Bob', idade: 30, cidade: 'Rio de Janeiro' }, { id: 3, nome: 'Charlie', idade: 25, cidade: 'São Paulo' }, { id: 4, nome: 'David', idade: 35, cidade: 'Belo Horizonte' } ]; // Usando lodash para manipular dados // 1. Agrupar usuários por cidade const porCidade = _.groupBy(usuarios, 'cidade'); console.log('Usuários por cidade:', porCidade); // 2. Filtrar usuários com idade 25 const idade25 = _.filter(usuarios, { idade: 25 }); console.log('Usuários com 25 anos:', idade25); // 3. Mapear apenas os nomes const nomes = _.map(usuarios, 'nome'); console.log('Nomes dos usuários:', nomes); // 4. Encontrar usuário por ID const usuarioId2 = _.find(usuarios, { id: 2 }); console.log('Usuário com ID 2:', usuarioId2);Para CommonJS (se não usar
"type": "module"):// index.js const _ = require('lodash'); // Mesmo código acima, apenas com require em vez de import const usuarios = [ { id: 1, nome: 'Alice', idade: 25, cidade: 'São Paulo' }, { id: 2, nome: 'Bob', idade: 30, cidade: 'Rio de Janeiro' }, { id: 3, nome: 'Charlie', idade: 25, cidade: 'São Paulo' }, { id: 4, nome: 'David', idade: 35, cidade: 'Belo Horizonte' } ]; const porCidade = _.groupBy(usuarios, 'cidade'); console.log('Usuários por cidade:', porCidade); const idade25 = _.filter(usuarios, { idade: 25 }); console.log('Usuários com 25 anos:', idade25); const nomes = _.map(usuarios, 'nome'); console.log('Nomes dos usuários:', nomes); const usuarioId2 = _.find(usuarios, { id: 2 }); console.log('Usuário com ID 2:', usuarioId2);Explicação do Código:
- Importamos o
lodash(usando_por convenção). - Criamos uma lista de objetos
usuariospara simular dados reais. - Usamos funções do
lodash:_.groupBy: Agrupa objetos por uma propriedade (ex.:cidade)._.filter: Filtra objetos com base em critérios._.map: Extrai uma propriedade de cada objeto._.find: Busca o primeiro objeto que corresponde ao critério.
- Importamos o
15.2.5 Passo 4: Executar o Projeto
Execute o script:
npm startOu, para desenvolvimento com reinício automático:
npm run devSaída esperada:
Usuários por cidade: { 'São Paulo': [ { id: 1, nome: 'Alice', idade: 25, cidade: 'São Paulo' }, { id: 3, nome: 'Charlie', idade: 25, cidade: 'São Paulo' } ], 'Rio de Janeiro': [ { id: 2, nome: 'Bob', idade: 30, cidade: 'Rio de Janeiro' } ], 'Belo Horizonte': [ { id: 4, nome: 'David', idade: 35, cidade: 'Belo Horizonte' } ] } Usuários com 25 anos: [ { id: 1, nome: 'Alice', idade: 25, cidade: 'São Paulo' }, { id: 3, nome: 'Charlie', idade: 25, cidade: 'São Paulo' } ] Nomes dos usuários: ['Alice', 'Bob', 'Charlie', 'David'] Usuário com ID 2: { id: 2, nome: 'Bob', idade: 30, cidade: 'Rio de Janeiro' }
15.2.6 Passo 5: Replicando com Yarn
Remova o
node_modulesepackage-lock.json:rm -rf node_modules package-lock.jsonInstale o Yarn (se necessário):
npm install -g yarnInstale as dependências com Yarn:
yarn add lodash yarn add --dev nodemonVerifique o
yarn.lockgerado e execute:yarn startOu:
yarn devA saída será idêntica, mas o Yarn cria um
yarn.lockem vez depackage-lock.json.
15.2.7 Passo 6: Depuração e Boas Práticas
- Depuração:
- Use o VS Code para depurar:
Crie um
launch.json:{ "version": "0.2.0", "configurations": [ { "type": "node", "request": "launch", "name": "Launch Program", "program": "${workspaceFolder}/index.js" } ] }Adicione breakpoints e execute com
F5.
- Use o VS Code para depurar:
- Verifique Dependências:
Use
npm listouyarn listpara ver a árvore de dependências.Verifique vulnerabilidades:
npm audit yarn audit
- Versionamento:
Adicione os arquivos ao Git:
git init git add . git commit -m "Projeto com lodash usando npm/yarn"
- Evite
node_modulesno Git:Crie um
.gitignore:node_modules/
15.3 Conclusão
Nesta capítulo, você aprendeu: - Estrutura do package.json: Metadados, dependências, scripts e SemVer. - Gerenciamento de Dependências: Como instalar, atualizar e remover pacotes com npm e Yarn. - Scripts Personalizados: Automatização de tarefas com o campo scripts. - npm vs. Yarn: Diferenças, vantagens e casos de uso. - Exemplo Prático: Instalou e usou a biblioteca lodash para manipular dados em um projeto Node.js.
Esses conceitos são fundamentais para gerenciar projetos Node.js de forma eficiente e escalável. Nos próximos módulos, você aplicará esse conhecimento para construir APIs com Express e manipular arquivos com o módulo fs.
15.3.1 Próximos Passos
- Experimente instalar outras bibliotecas (ex.:
moment,axios) e criar scripts para usá-las. - Explore a documentação do npm: npmjs.com e Yarn: yarnpkg.com.
- Prepare-se para o próximo módulo, onde abordaremos o Projeto Prático: Servidor HTTP Simples.