Skip to content

Gerenciamento de Pacotes com npm/Yarn ​

INFO

Criado por Kleber Galvão.

Bem-vindo à terceira aula do curso Node.js do Básico ao Avançado! Esta aula foca em um aspecto essencial do desenvolvimento com Node.js: o gerenciamento de pacotes usando npm (Node Package Manager) e Yarn. Vamos explorar como esses gerenciadores de pacotes facilitam a instalação, configuração e manutenção de dependências em projetos Node.js, com ênfase na estrutura do arquivo package.json, gerenciamento de dependências e criação de scripts personalizados. Além disso, você aprenderá a instalar e usar a biblioteca lodash em um exemplo prático, aplicando conceitos reais de desenvolvimento.

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.


Teoria: Estrutura do package.json, Dependências e Scripts npm/Yarn ​

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.

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.

2.1. Estrutura do package.json ​

Aqui está um exemplo típico de package.json:

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 com npm run <script> ou yarn <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.

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.

2.3. Criando o package.json ​

  • Com npm:

    bash
    npm init

    Responda às perguntas interativas (nome, versão, etc.) ou use:

    bash
    npm init -y

    para criar com valores padrão.

  • Com Yarn:

    bash
    yarn init

    ou:

    bash
    yarn init -y

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).

3.1. Instalando Dependências ​

  • Com npm:

    bash
    npm install lodash
    # Ou, abreviado:
    npm i lodash

    Para dependências de desenvolvimento:

    bash
    npm install --save-dev nodemon
    # Ou:
    npm i -D nodemon
  • Com Yarn:

    bash
    yarn add lodash

    Para dependências de desenvolvimento:

    bash
    yarn add --dev nodemon

Ao instalar, o pacote é baixado para a pasta node_modules, e a versão é registrada no package.json.

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.

3.3. Atualizando Dependências ​

  • Com npm:

    bash
    npm update

    Atualiza dependências dentro das faixas permitidas no package.json. Para verificar pacotes desatualizados:

    bash
    npm outdated
  • Com Yarn:

    bash
    yarn upgrade

    Para verificar pacotes desatualizados:

    bash
    yarn outdated

3.4. Removendo Dependências ​

  • Com npm:

    bash
    npm uninstall lodash
  • Com Yarn:

    bash
    yarn remove lodash

3.5. Dependências Globais ​

Pacotes globais são instalados no sistema e podem ser usados em qualquer projeto:

  • npm:

    bash
    npm install -g nodemon
  • Yarn:

    bash
    yarn global add nodemon

Nota: Evite dependências globais em projetos reproduzíveis, pois elas podem causar inconsistências. Prefira dependências locais.

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.

4.1. Exemplo de Scripts ​

json
"scripts": {
  "start": "node index.js",
  "dev": "nodemon index.js",
  "test": "jest",
  "lint": "eslint .",
  "build": "tsc"
}
  • start: Executado com npm start ou yarn start. Usado para iniciar a aplicação em produção.
  • dev: Executado com npm run dev ou yarn dev. Usado para desenvolvimento com ferramentas como nodemon.
  • test: Executado com npm test ou yarn test. Usado para rodar testes.
  • lint: Verifica a qualidade do código com ESLint.
  • build: Compila TypeScript (se aplicável).

4.2. Executando Scripts ​

  • npm:

    bash
    npm start
    npm run dev
  • Yarn:

    bash
    yarn start
    yarn dev

Nota: start e test não exigem run, mas outros scripts sim.

4.3. Scripts Pré e Pós ​

Você pode definir scripts que rodam automaticamente antes (pre) ou depois (post) de outro script:

json
"scripts": {
  "prestart": "npm run lint",
  "start": "node index.js",
  "poststart": "echo 'Servidor iniciado!'"
}

Executar npm start rodará prestart, start e poststart na ordem.

5. npm vs. Yarn: Diferenças e Quando Usar ​

Embora npm e Yarn sejam semelhantes, eles têm diferenças importantes:

CaracterísticanpmYarn
PerformanceMelhorou nas versões recentes (v10+)Geralmente mais rápido
Lockfilepackage-lock.jsonyarn.lock
Instalação OfflineSuporte parcialCache offline robusto
DeterminismoBom, mas Yarn é mais consistenteAltamente determinístico
Comandosnpm install, npm runyarn add, yarn
WorkspacesSuporte básicoSuporte avançado para monorepos
Popularidade em 2025Padrão, amplamente usadoPreferido em projetos grandes

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.

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.

6. Boas Práticas para Gerenciamento de Pacotes ​

  1. Mantenha o package.json Limpo:

    • Remova dependências não utilizadas com npm prune ou yarn autoclean.
    • Use nomes descritivos e atualize metadados (ex.: description, author).
  2. Versione o Lockfile:

    • Inclua package-lock.json ou yarn.lock no Git para builds consistentes.
  3. Evite Dependências Desnecessárias:

    • Verifique se um pacote é realmente necessário antes de instalá-lo.
    • Use ferramentas como depcheck para identificar dependências não usadas.
  4. Atualize Regularmente:

    • Use npm outdated ou yarn outdated para identificar pacotes desatualizados.
    • Teste atualizações em um ambiente de desenvolvimento antes de aplicar em produção.
  5. Use Scripts para Automação:

    • Crie scripts para tarefas comuns (ex.: linting, testes, build).
    • Combine ferramentas como nodemon, eslint e jest para produtividade.
  6. Segurança:

    • Use npm audit ou yarn audit para identificar vulnerabilidades:
      bash
      npm audit
      npm audit fix
    • Monitore pacotes com ferramentas como Dependabot (GitHub).

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.

Objetivo do Exemplo ​

  • Configurar um projeto Node.js com package.json.
  • Instalar a biblioteca lodash como dependência.
  • Criar um script que usa funções do lodash para manipular uma lista de objetos.
  • Executar o projeto com scripts personalizados.

Passo 1: Configurar o Projeto ​

  1. Crie uma nova pasta para o projeto:

    bash
    mkdir lodash-exemplo
    cd lodash-exemplo
    npm init -y
  2. O package.json será criado:

    json
    {
      "name": "lodash-exemplo",
      "version": "1.0.0",
      "description": "",
      "main": "index.js",
      "scripts": {
        "test": "echo \"Error: no test specified\" && exit 1"
      },
      "keywords": [],
      "author": "",
      "license": "ISC"
    }
  3. (Opcional) Para usar ES Modules, adicione:

    json
    "type": "module"
  4. Instale o nodemon como dependência de desenvolvimento:

    bash
    npm install --save-dev nodemon

    Atualize os scripts no package.json:

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

Passo 2: Instalar a Biblioteca lodash ​

  1. Instale o lodash como dependência de produção:

    bash
    npm install lodash
  2. Verifique o package.json atualizado:

    json
    {
      "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"
      }
    }
  3. O package-lock.json também será gerado, travando as versões exatas.

Passo 3: Criar o Script com lodash ​

  1. Crie um arquivo index.js (ou index.mjs para ES Modules):

    javascript
    // 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"):

    javascript
    // 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);
  2. Explicação do Código:

    • Importamos o lodash (usando _ por convenção).
    • Criamos uma lista de objetos usuarios para 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.

Passo 4: Executar o Projeto ​

  1. Execute o script:

    bash
    npm start

    Ou, para desenvolvimento com reinício automático:

    bash
    npm run dev
  2. Saída esperada:

    json
    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' }

Passo 5: Replicando com Yarn ​

  1. Remova o node_modules e package-lock.json:

    bash
    rm -rf node_modules package-lock.json
  2. Instale o Yarn (se necessário):

    bash
    npm install -g yarn
  3. Instale as dependências com Yarn:

    bash
    yarn add lodash
    yarn add --dev nodemon
  4. Verifique o yarn.lock gerado e execute:

    bash
    yarn start

    Ou:

    bash
    yarn dev
  5. A saída será idêntica, mas o Yarn cria um yarn.lock em vez de package-lock.json.

Passo 6: Depuração e Boas Práticas ​

  1. Depuração:

    • Use o VS Code para depurar:
      • Crie um launch.json:
        json
        {
          "version": "0.2.0",
          "configurations": [
            {
              "type": "node",
              "request": "launch",
              "name": "Launch Program",
              "program": "${workspaceFolder}/index.js"
            }
          ]
        }
      • Adicione breakpoints e execute com F5.
  2. Verifique Dependências:

    • Use npm list ou yarn list para ver a árvore de dependências.
    • Verifique vulnerabilidades:
      bash
      npm audit
      yarn audit
  3. Versionamento:

    • Adicione os arquivos ao Git:
      bash
      git init
      git add .
      git commit -m "Projeto com lodash usando npm/yarn"
  4. Evite node_modules no Git:

    • Crie um .gitignore:
      node_modules/

Conclusão ​

Nesta aula, 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.

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.

Se tiver dúvidas ou quiser mais exemplos, é só pedir! 🚀

Todos os direitos reservados.