Olá pessoal! Tenho certeza que você já viu usando diferentes gerenciadores de pacotes, ou seja: projetos Node.js (o padrão) npm fio pnpm Eu mesmo vi isso e trabalhei com todos os itens acima, mas sempre tive uma pergunta em mente - o que leva as pessoas/equipes a usarem ou em vez de ? Quais são as vantagens? Há algum contra? yarn pnpm npm Bem… vamos descobrir! Regras de comparação de desempenho Decidi comparar , e em termos de “velocidade”… npm yarn pnpm Você verá três medidas abaixo: Gere um arquivo de bloqueio sem cache. Instale dependências de arquivos de bloqueio existentes sem nenhum cache. Instale dependências de arquivos de bloqueio existentes com cache global. Existem dois tipos de cache: Global. Geralmente armazenado no diretório inicial do usuário (fe, ). ~/.yarn/berry/cache Local. Armazenado no diretório do projeto (fe, ). <project-dir>/.yarn Embora e sejam os casos de uso mais comuns em minha experiência, também peguei por precaução (embora seja um caso muito raro). os números 2 3 o número 1 Usei um projeto de amostra do como exemplo de benchmarks. create-react-app npm É um gerenciador de pacotes padrão para o ecossistema – o que mais dizer? Ele vem com o pacote de instalação, portanto está basicamente pronto para uso quando você instala em sua máquina (ou em qualquer provedor se você configurar lá). Node.js o Node.js de CI o Node.js Na minha opinião, isso é um grande “profissional” - você não precisa instalá-lo separadamente! Nada excepcional aí - simplesmente… funciona! E não vi nenhum bug importante ao longo dos anos - parece bastante estável e dá conta do recado. Os recursos do que usei até agora: npm Gerenciar dependências (instalar, remover, atualizar) Publicar pacotes (privados, públicos) Pacotes de link local Gerenciar espaços de trabalho. Gerenciar dependências armazena dependências na pasta da raiz do seu projeto. Bem direto. O npm node_modules ℹ️ armazena informações sobre registros para os pacotes listados - é útil se você tiver pacotes de um único escopo, ou seja, em registros diferentes (por exemplo - pacotes e ): package-lock.json MUITO @example-company npm GitHub Agora, vamos ver como ele funciona em termos de velocidade de instalação… Gere package-lock.json sem nenhum cache Levou para gerar um e instalar dependências sem nenhum cache. 1 minuto o npm package-lock.json Comando usado: npm i Instale dependências de package-lock.json sem nenhum cache Levou para instalar dependências de sem nenhum cache. 18 segundos o npm package-lock.json Comando usado: npm ci Instale dependências de package-lock.json com cache global Levou para instalar dependências de com cache global. 8 segundos o npm package-lock.json Comando usado: npm ci Gerenciar espaços de trabalho Consegui criar e gerenciar dependências para todo o espaço de trabalho de uma só vez e para projetos específicos separadamente. um espaço de trabalho Em outras palavras - ele faz o trabalho sem bugs/problemas e a documentação oficial é bastante direta. Recursos do espaço de trabalho que usei até agora: Instale dependências para todos os projetos no espaço de trabalho. Instale dependências para um único projeto específico. Execute um único script para todos os projetos de uma só vez, de forma recursiva. fio Honestamente, não experimentei muito alguns dos recursos . Quer dizer, usei muito em termos de “instalação de dependências” enquanto trabalhava em alguns projetos, e é isso. do fio não vem com um instalador , então você terá que instalá-lo separadamente. Isso significa que haveria uma etapa adicional em seus pipelines - você teria que configurar antes de instalar as dependências do projeto. O yarn Node.js de CI o fio Gerenciar dependências tem duas abordagens para instalar dependências: O fio “ ” (padrão) - cria a pasta e lista os pacotes nos arquivos e . Zero instalações .yarn yarn.lock .pnp.cjs Um regular - semelhante ao , armazena dependências em e as lista no arquivo . npm node_modules yarn.lock ℹ️ Os arquivos lock armazenam informações sobre registros de todos os pacotes listados se você usar a abordagem de instalação antiga (regular). yarn SOMENTE ⚠️ Tenha em mente que “ ” parece armazenar pacotes no cache local e fornecer links para seus arquivos de bloqueio: Zero Installs Pode ser importante para você se você tiver um pipeline ou onde você instala dependências em um ambiente limpo e depois deseja movê-lo para outro (você terá que copiar a pasta e o cache local). Dockerfile CI .yarn Como a abordagem padrão para o Yarn agora é “ ” e tem melhor desempenho do que a abordagem antiga, registraremos benchmarks apenas com essa abordagem. Zero Instalações Gere arquivos de bloqueio sem qualquer cache Levou para gerar um arquivo e instalar dependências sem cache. 16,5 segundos o yarn yarn.lock Comando usado: yarn install Instale dependências de arquivos de bloqueio existentes sem qualquer cache Levou para instalar dependências com a abordagem “Zero Install” e sem nenhum cache. 11 segundos o Yarn Comando usado: yarn install --frozen-lockfile Instale dependências de arquivos de bloqueio existentes com cache global Levou para instalar dependências com a abordagem “Zero Install” e cache global. 8 segundos o Yarn Comando usado: yarn install --frozen-lockfile Gerenciar espaços de trabalho Consegui criar e gerenciar dependências para todos os projetos de uma vez e para projetos específicos separadamente. um espaço de trabalho Recursos do espaço de trabalho que usei até agora: Instale dependências para todos os projetos no espaço de trabalho. Instale dependências para um único projeto específico. Execute um único script para todos os projetos de uma só vez, de forma recursiva. A documentação está boa, mas os nomes e sinalizadores dos comandos são um tanto confusos. Por exemplo, devo executar isto para executar o script na ( ) e no projeto aninhado: test raiz . b2b yarn workspaces foreach -A --include '{.,b2b}' run test Em comparação com : npm npm run test --workspace=b2b --include-workspace-root pnpm está atualmente em alta - . O pnpm muitas empresas e projetos de código aberto o utilizam Assim como - não vem com um instalador , então você terá que instalá-lo separadamente. Isso significa que haverá uma etapa adicional em seus pipelines – você terá que configurar antes de instalar as dependências do seu projeto. o yarn pnpm Node.js de CI o pnpm Gerenciar dependências é considerado um … pnpm “ ” gerenciador de pacotes rápido e eficiente em espaço em disco Na verdade, concordo com a afirmação em termos de gerenciamento local de dependências. “eficiente de espaço em disco” Por padrão, elimina a duplicação de dependências compartilhadas. cria links simbólicos para os pacotes que são usados em múltiplas dependências. ou seja, se os pacotes e usarem o pacote como uma dependência - armazenará o pacote como uma única cópia e criará links simbólicos para os pacotes e . Dessa forma, o gerenciador de pacotes não cria cópias impressas e economiza memória no seu SSD/HDD. o pnpm pnpm a b c o pnpm c a b ℹ️ não armazena informações sobre registros dos pacotes listados. pnpm-lock.yaml ⚠️ Tenha em mente que às vezes armazena dependências no cache global, em vez de mantê-lo como um projeto. o pnpm Gere pnpm-lock.yaml sem nenhum cache Levou para que gere um e instale dependências sem nenhum cache. 31 segundos o pnpm pnpm-lock.yaml Comando usado: pnpm install Instale dependências de pnpm-lock.yaml sem cache global Levou para que instale dependências de sem cache. 16 segundos o pnpm pnpm-lock.yaml Comando usado: pnpm i --frozen-lockfile Instalar dependências de arquivo de bloqueio existente com cache global Levou para que instale dependências de com cache global. 5 segundos o pnpm pnpm-lock.yaml Comando usado: pnpm i --frozen-lockfile Gerenciar espaços de trabalho Agora, é aí que as coisas se tornam realmente interessantes… tem muitas opções de configuração, mas algumas funcionalidades básicas simplesmente não funcionam! O pnpm Vamos revisar alguns bugs que enfrentei: instalação pnpm --filtro É importante poder instalar dependências apenas para projetos específicos – é bastante útil para monorepos quando você cria pipelines relacionados a projetos específicos dentro do espaço de trabalho. ou seja, imagine que você tem em seu espaço de trabalho: um aplicativo da web, servidor back-end, projeto de teste (testes ponta a ponta). Todos esses são projetos separados, mas fazem parte do mesmo repositório ☝️ NPM Agora, você deseja que um pipeline execute apenas testes de ponta a ponta. Então, você precisa apenas de dependências de teste ponta a ponta, certo? Bem, você não conseguirá fazer isso - está forçando você a instalar dependências para todo o espaço de trabalho! o pnpm deveria instalar dependências apenas para projetos selecionados, mas não funciona. pnpm install --filter <project-name> Há um bug com um ano de idade e foi recentemente fechado com uma correção que não funcionava. instalação recursiva = falso por padrão instala dependências para todo o espaço de trabalho (todos os projetos) quando você executa O pnpm pnpm install Você pode alternar esse comportamento se definir em na raiz do seu espaço de trabalho. recursive-install=false .npmrc MAS . introduz outro bug que já tem quase 2 anos arquivo de bloqueio de espaço de trabalho compartilhado = falso Por padrão, armazena a lista de dependências em um único arquivo de bloqueio (igual a e ). pnpm npm yarn Você também pode alternar esse comportamento se definir em na raiz do seu espaço de trabalho. shared-workspace-lockfile=false .npmrc Isso nos permitiria manter o recurso de espaço de trabalho e usar o sinalizador para instalar dependências para um projeto específico. --ignore-workspace De qualquer forma, esta configuração apresenta mais alguns problemas: e geram um erro em meus pipelines . eslint tsc --noEmit “JavaScript Heap Out of Memory” de ações do GitHub Algumas das dependências são armazenadas no cache global e vinculadas simbolicamente em . node_modules/.pnpm Resultados de comparação de desempenho # npm fio pnpm Gere um arquivo de bloqueio 60 segundos 16,5 segundos 31 segundos Instale dependências sem nenhum cache 18 segundos 11 segundos 8 segundos Instale dependências com cache global 8 segundos 8 segundos 5 segundos De acordo com o benchmark acima, é o gerenciador de pacotes mais lento ☝️ npm De qualquer forma, vamos interpretar esses resultados… Gerar um arquivo de bloqueio É um caso raro. Normalmente, um arquivo de bloqueio é criado na inicialização do projeto e então se expande quando você instala/atualiza pacotes. Com isso em mente - não parece ser algo muito importante em que se confiar ao escolher um gerenciador de pacotes. Instalar dependências Na maioria dos casos, seus projetos mantêm uma lista específica de dependências e você raramente adiciona/remove algo. Provavelmente, você atualizará versões de seus pacotes de tempos em tempos - essas alterações são pequenas e você reutilizará o restante dos pacotes do cache. Em outras palavras, o caso de uso comum é -- buscar novos pacotes do registro de pacotes e pegar o restante do cache. (5-8 seg) é quase duas vezes mais rápido que (8-18 seg) com (8-11 seg) no meio. pnpm npm fio Conclusão Fatos é de fato - isso fica bem claro na análise atual! O pnpm um gerenciador de pacotes “rápido e eficiente em disco” O recurso de espaço de trabalho está com bugs e alguns dos bugs não foram resolvidos há anos. pnpm tanto quanto exigem uma configuração adicional em pipelines de CI, enquanto não. o pnpm o fio o npm tanto quanto não armazenam informações de registro de pacotes em seus arquivos de bloqueio, enquanto o faz. o pnpm o yarn o npm Pensamentos do autor Acho que faz o melhor trabalho se o seu requisito para o gerenciador de pacotes for tão simples quanto “instalar apenas dependências”. o pnpm Embora não venha com um instalador pronto para uso, é fácil configurá-lo em pipelines de CI com ou . o pnpm Node.js corepack action existente Eu prefiro , porque: npm é estável (especialmente em espaços de trabalho), vem com e não requer configuração adicional no pipeline de CI, Node.js armazena registros de pacotes em para que você possa instalar dependências com um único escopo de registros diferentes. package-lock.json Essas vantagens superam os segundos de velocidade e espaço em disco que eu economizaria com ou . yarn pnpm Quais são os seus critérios para escolher um gerenciador de pacotes? Não seja tímido e deixe-me saber sua opinião na seção de comentários abaixo! 👇😊