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.