Saiba a diferença entre dependências de desenvolvimento vs. produção

Essa é uma distinção fundamental quando estamos desenvolvendo projetos, especialmente no ecossistema Node.js (que é o que usamos com o Cypress). Entender a diferença entre dependências de desenvolvimento e de produção nos ajuda a organizar melhor nosso projeto, otimizar o que vai para o “cliente final” (ou servidor de produção) e até mesmo melhorar a segurança.

Vamos usar uma analogia para facilitar: Construindo uma Casa.

Imagine que você está construindo uma casa (sua aplicação).

  1. Dependências de Produção (dependencies):
    • O que são: São os tijolos, cimento, telhas, fiação elétrica, canos, janelas, portas – tudo aquilo que precisa estar na casa para ela funcionar e ser habitável. Sem esses materiais, a casa não cumpre seu propósito.
    • No software: São os pacotes (bibliotecas, frameworks) que sua aplicação precisa para rodar em produção, ou seja, quando seus usuários finais estiverem interagindo com ela.
      • Exemplos: Um framework web como Express.js (se você estivesse construindo um backend), uma biblioteca para fazer chamadas HTTP como o axios, ou uma biblioteca de componentes de UI como React ou Vue (se a dependência fosse para o front-end que será “servido”).
    • Como são listadas: No arquivo package.json, elas aparecem sob a chave "dependencies".
    • Instalação: Quando você instala um pacote que sua aplicação precisa para funcionar em produção, você geralmente usa:
      • npm install nome-do-pacote (ou npm install nome-do-pacote --save ou npm i nome-do-pacote -S em versões mais antigas do npm que não salvavam por padrão)
      • yarn add nome-do-pacote
  2. Dependências de Desenvolvimento (devDependencies):
    • O que são: São as ferramentas que os construtores usam durante a construção da casa, mas que não fazem parte da casa final. Pense em andaimes, betoneiras, furadeiras, trenas, equipamentos de segurança dos trabalhadores, plantas da construção. Essas ferramentas são essenciais para construir a casa corretamente e com qualidade, mas você não as entrega para o morador quando a casa está pronta.
    • No software: São os pacotes que você, como desenvolvedor, usa durante o processo de desenvolvimento, teste, e construção (build) da sua aplicação. Eles não são necessários para a aplicação rodar em produção.
      • Exemplos:
        • Ferramentas de Teste: Cypress (como estamos vendo!), Jest, Mocha.
        • Linters e Formatadores de Código: ESLint, Prettier (para garantir a qualidade e o padrão do código).
        • Bundlers e Transpiladores: Webpack, Babel (para empacotar e converter código JavaScript moderno para versões mais compatíveis).
        • Nodemon: Para reiniciar o servidor automaticamente durante o desenvolvimento.
    • Como são listadas: No arquivo package.json, elas aparecem sob a chave "devDependencies".
    • Instalação: Quando você instala um pacote que é apenas para desenvolvimento, você usa:
      • npm install nome-do-pacote --save-dev (ou npm i nome-do-pacote -D)
      • yarn add nome-do-pacote --dev

Por que essa distinção é importante?

  1. Tamanho da Aplicação em Produção:
    • Quando você vai “entregar a casa” (fazer o deploy da sua aplicação para um servidor de produção), você não quer levar todas as ferramentas de construção junto. Isso deixaria a “entrega” muito mais pesada e lenta.
    • Ao separar as dependências, você pode instruir o sistema (por exemplo, em um ambiente de Integração Contínua/Entrega Contínua – CI/CD) a instalar apenas as dependencies no ambiente de produção. Isso resulta em:
      • Menor tamanho do build/pacote final: Menos arquivos para transferir e armazenar.
      • Deploy mais rápido.
      • Potencialmente menos custos de hospedagem.
  2. Segurança:
    • Algumas ferramentas de desenvolvimento podem ter vulnerabilidades que, embora não afetem sua aplicação em si, não deveriam estar presentes em um ambiente de produção. Reduzir o número de pacotes em produção minimiza a “superfície de ataque”.
  3. Performance (Menor Impacto, mas Relevante):
    • Ter menos pacotes carregados em produção pode levar a um tempo de inicialização ligeiramente mais rápido, embora para a maioria das aplicações Node.js no backend o impacto seja mínimo nesse quesito. Para front-end bundles, é crucial, pois o usuário baixa esses pacotes.
  4. Clareza e Organização do Projeto:
    • Fica claro para qualquer pessoa que olhe o package.json quais pacotes são essenciais para a aplicação funcionar e quais são ferramentas auxiliares para o desenvolvimento.

Como isso se aplica ao Cypress?

  • Cypress é uma ferramenta de teste. Você o usa para verificar se sua aplicação (a “casa”) está funcionando corretamente antes de entregá-la.
  • Os usuários finais da sua aplicação não executam os testes do Cypress. O Cypress não faz parte da funcionalidade principal que você oferece a eles.
  • Portanto, o Cypress é uma devDependency clássica. Você o instala com npm install cypress --save-dev.

E quando você executa npm install?

  • Se você clonar um projeto e rodar npm install (ou yarn install) na raiz do projeto, por padrão, o npm/yarn instalará ambas as dependencies e devDependencies. Isso ocorre porque ele assume que você provavelmente quer configurar um ambiente de desenvolvimento.
  • No entanto, em um ambiente de produção, você (ou seu script de deploy) pode rodar npm install --production. Este comando instrui o npm a ignorar as devDependencies e instalar apenas as dependencies.

Em resumo:

Característicadependencies (Produção)devDependencies (Desenvolvimento)
PropósitoNecessário para a aplicação rodarFerramentas para desenvolver e testar
Analogia da CasaTijolos, cimento, telhas (parte da casa)Andaimes, betoneira (ferramentas de construção)
Exemplo com Cypress(Não aplicável diretamente para Cypress)Cypress, ESLint, Webpack
Comando npmnpm install <pacote>npm install <pacote> --save-dev
No package.jsonSeção "dependencies"Seção "devDependencies"
Em Produção?Sim, instaladasNão, geralmente não instaladas

Exportar para as Planilhas

Entender essa separação é um passo importante para se tornar um desenvolvedor mais consciente e eficiente!