Como manter as dependências npm do seu projeto
José Pérez Rivas
11 de junho de 2020
0 minutos de leituraÉ muito comum encontrarmos projetos que funcionam corretamente em produção, mas já não recebem manutenção ativa: estão em produção, funcionam e o cliente considera o projeto concluído.
Infelizmente, isso não é totalmente verdade. Costumamos esquecer que, quando um projeto está concluído e em produção, isso não significa que ele não precise de manutenção. A maioria dos projetos ainda precisa ser revisada, e os incidentes devem ser resolvidos quando ocorrem. Se fizéssemos uma comparação com a compra de um veículo, seria mais ou menos assim: vamos à concessionária, escolhemos o modelo certo, pagamos e aproveitamos o veículo enquanto ele for útil, sem fazer nenhuma manutenção periódica, certo? Claro que não — e o mesmo vale para o software.
Ao desenvolver projetos de API REST ou aplicações de linha de comando com Node.js, é muito comum usar o gerenciador de pacotes de dependências de código aberto npm para incluir frameworks e ferramentas nesses projetos.
Até certo ponto, isso é vantajoso, pois pode ajudar a reduzir o tempo de desenvolvimento. Incluir pacotes estáveis, bem testados e mantidos pela comunidade atende a algumas necessidades do projeto. No entanto, isso também pode acabar se voltando contra nós e se tornar um problema.
A seguir, discutimos um cenário comum em um projeto Node.js. Alguns desses problemas surgem quando deixamos um projeto sem acompanhamento e sem manutenção evolutiva e preventiva.
Caso específico
Imagine um projeto de API REST com Node.js que está em produção há 2 anos ou mais. Durante esses dois anos, ninguém tomou nenhuma medida para atualizar ou adaptar as dependências às novas versões. No desenvolvimento, o pacote express foi usado como framework base para a funcionalidade CRUD. Além disso, a biblioteca jsonwebtoken foi usada para gerar tokens de segurança, e o moment, para internacionalizar datas.
Possíveis problemas
O uso de bibliotecas de dependência relativamente novas pode ser considerado o primeiro problema, pois baseamos parte da nossa solução em um software que não foi testado pela comunidade e que, possivelmente, não tem uma evolução constante.
Em segundo lugar, basear parte da nossa solução em bibliotecas com “um único contribuidor”, como eu as chamo. Essas dependências são desenvolvidas por uma única pessoa, responsável por lançar melhorias, fazer a manutenção e resolver incidentes e, por fim, decidir unilateralmente o rumo desse software. Essas dependências nos limitam bastante.
Como terceiro problema, temos as dependências que contêm outras dependências. No entanto, isso não é visível à primeira vista, no que costumamos chamar de “Node Module Hole”.

Fonte: https://github.com/JoseJPR/tutorial-nodejs-snyk-vuln-cost/blob/master/assets/video.gif
Veja aqui mais dicas sobre o assunto.
Algumas soluções
1. Eu realmente preciso dessa dependência?
Em um projeto Node.js, o primeiro lugar onde devemos buscar informações é a própria documentação. A documentação da API do Node.js traz vários exemplos práticos do que podemos fazer por conta própria, usando a API do Node.js de forma “nativa”, sem dependências externas.
2. Use microdependências
Depois de confirmar que precisamos de um recurso para atender às necessidades do projeto, precisamos encontrar a opção certa. À primeira vista, muitas vezes pensamos que a primeira opção exibida nos resultados de uma busca no Google (ou no mecanismo de busca do npm) será a mais adequada, mas, em muitos casos, não é. Precisamos parar, pensar e analisar quanto do que essa biblioteca faz realmente precisamos. Talvez ela faça muito mais do que precisamos, trazendo para o projeto uma biblioteca que, em grande parte, ficará sem uso.
Análise de mercado
Precisamos pesquisar um pouco e buscar alternativas: o ecossistema npm é muito amplo e podemos encontrar diferentes bibliotecas que fazem praticamente a mesma coisa. Mas qual escolher? Nesse caso, podemos usar ferramentas online como Bundlephobia, que compara o tamanho de cada pacote, ou npmtrends, que compara informações como volume de downloads e contribuições da comunidade, entre outros parâmetros.
Essas ferramentas podem ajudar a escolher a dependência certa. Informações como o tamanho da dependência, o volume da comunidade que a mantém, o número de versões lançadas nos últimos meses ou a quantidade de downloads podem ser indicadores importantes.
4. Use ferramentas preventivas
A Snyk lançou a extensão de código aberto Vuln Cost para o Visual Studio Code, que permite visualizar de forma simples e rápida quantas vulnerabilidades há no nosso software a partir do arquivo package.json e até mesmo de cada arquivo que contém a importação de uma biblioteca.
Atualmente, em um projeto Node.js, podemos injetar dependências por meio de require e import, adicionando-as por completo ou parcialmente, se isso for permitido. Na imagem a seguir, você pode ver um exemplo claro de como isso funciona usando o projeto descrito anteriormente (express + jsonwebtoken + moment):

Fonte: https://github.com/JoseJPR/tutorial-nodejs-snyk-vuln-cost/blob/master/assets/video.gif
Se você quer mais recursos sobre como usar o Vuln Cost, confira os três vídeos abaixo:
Como usar "require" em bibliotecas JavaScript e verificar vulnerabilidades
Como usar import em bibliotecas JavaScript e verificar vulnerabilidades
Conclusões
Um dos desafios que o setor de software sempre enfrentou é explicar e fazer o usuário final entender que o software tem uma necessidade básica: receber manutenção e evoluir, buscando, por exemplo, adaptar-se às atualizações do sistema operacional, melhorar o desempenho ou eliminar possíveis pontos vulneráveis.
Outro desafio é conseguir tempo para que as equipes de desenvolvimento possam refletir, atualizar conhecimentos e se capacitar para encontrar as alternativas mais adequadas ao desenvolver software — a primeira opção que aparece nem sempre é a certa.
As quatro soluções que exploramos acima podem ajudar você a desenvolver uma base de código sustentável, de alta qualidade, escalável e mais segura.
Comece a jogar Capture the Flag
Aprenda a resolver desafios de Capture the Flag assistindo sob demanda ao nosso workshop virtual introdutório.



