Yarn, primeiras impressões | Lambda3
por Victor Cavalcante | out 24, 2016 | Desenvolvimento | 7 Comentários
No dia 11/10 o Facebook anunciou o lançamento do Yarn, um novo gestor de pacotes para o NodeJS. Até então utilizávamos o NPM para esse trabalho, mas se já temos o NPM por que precisamos do Yarn? Por que ele foi criado? Devo parar de usar o NPM para usar o Yarn? Vou tentar responder essas perguntas.
Primeiro vamos entender o que ele é: o Yarn substitui o cliente do NPM, mas pode ser usado junto com ele. Se você trabalha em uma equipe e seu colega usa o NPM ele pode continuar usando e você pode ir para o Yarn, pois ambos usam o arquivo package.json. A principal diferença é que o Yarn gera um arquivo chamado yarn.lock que iremos analisar logo mais.
A ideia do Yarn é melhorar o tempo de download dos pacotes, pois o NPM é conhecido por ser lento nas restaurações das dependências e inclusive sendo possível resolver dependências sem o uso da internet usando o cache local.
Como exemplo semana passada baixei o código do site do setup.loopinfinito.com.br que é um site estático que usa o docpad para a geração dos HTMLs, uma coisa bem simples, quando rodei um npm install demorou 5 minutos para realizar todo o trabalho, muito tempo na minha opinião. Acredito que esse é um desafio que o Yarn puxou para melhorar, mas que ele ainda não resolve, apenas melhora.
No site do Yarn tem alguns números mostrando como ele é rápido, mas como eu não costumo acreditar nesses números, preferi fazer o meu teste.
Como estou no Mac fiz um script bash (não conheço muito, por isso foi o escolhido queria para aprender um pouco, está bem básico), para realizar os testes utilizei um pacote do node chamado gnomon, ele me ajuda na coleta do tempo, você pode ver o script aqui, fico feliz se você mandar um pull-request melhorando ele :).
Cenários usando o node version 6.7.0
1 – Sem cache, sem node_modules e sem o arquivo Lockfile/Shrinkwrap 110s 47s
2 – Sem cache, sem node_modules com o arquivo Lockfile/Shrinkwrap 108s 46s
3 – Sem cache, com node_modules e sem o arquivo Lockfile/Shrinkwrap 2s 51s
4 – Sem cache, com node_modules com o arquivo Lockfile/Shrinkwrap 81s 0.2s
Como podemos ver acima, o Yarn é mais rápido em quase todos os cenários, o único em que ele perde é um cenário que não acontece se o utilizarmos corretamente, pois sempre o yarn.lock será gerado e por isso o cenário 3 não acontece de fato, sendo mais real a comparação do resultado do cenário 3 do npm com o cenário 4 do Yarn, o que faria o Yarn ganhar também.
Vamos começar pela instalação, veja nessa página como instalar no seu sistema, eu instalei pelo NPM: npm install -g yarn
Preferi instalar pelo npm porque uso o nvm no mac, portanto quando tento instalar com o brew ele irá verificar se tenho a formula do node instalado, ele não vai achar e vai querer instalar o node pelo brew, o que não quero.
Para facilitar vou criar uma tabelinha para ajudar na migração do NPM para o Yarn, a maioria dos comandos são os mesmos, só listei os principais comandos para o dia a dia de desenvolvimento.
npm install jquery –save yarn add jquery
npm shrinkwrap yarn generate-lock-entry (por padrão ele já gera o yarn.lock)
Existem algumas diferenças, vamos ver quais são elas:
Esse comando até agora não tem nenhum equivalente no NPM, a ideia dele é bem interessante, o yarn licenses ls lista todas as licenças dos pacotes que estão instalados, enquanto o yarn licenses generate-disclaimer gerará um "disclaimer" contendo todos os "disclaimers" de todos os pacotes instalados.
Esse comando seria o equivalente a fazer rm -rf node_modules && npm install, ele irá atualizar os pacotes para a última versão conforme as regras estabelecidas no package.json. Não confunda com o npm update que irá atualizar o pacote para a última versão, alterando inclusive o package.json.
Esse comando serve para sabermos o porque uma dependência está instalada, é uma mão na roda para saber porque aquele pacotes está no seu projeto.
Usando o yarn why
O yarn.lock file
A estratégia do Yarn é diferente do NPM, a cada adição de um pacote ele cria ou altera o arquivo yarn.lock que guarda a versão exata que esta sendo utilizada, e esse arquivo é usado para fazer a instalação do pacote de acordo com a versão específica utilizada no projeto, garantindo assim que quando você rodar o instalador de pacotes a versão correta seja instalada. A equipe do Yarn (e eu) recomenda que você coloque esse arquivo no seu source control, isso garantirá que todos os membros do time usem a mesma versão.
Da forma que o NPM faz atualmente podemos ter o mesmo package.json em duas máquinas diferentes e ao executarmos o npm install obter pacotes com versões diferentes entre essas máquinas, isso pode introduzir bugs no sistema.
O NPM tem uma função que faz a mesma coisa, o npm shrinkwrap cria o arquivo npm-shrinkwrap.json que é o equivalente ao yarn.lock, só que diferente do Yarn no NPM isso não é automático, você precisa explicitamente rodar o comando.
Vamos entender como o Yarn trabalha internamente, ele tem 3 fases de processamento:
Resolution: onde ele realiza a resolução de dependências fazendo requisições para o registro e recursivamente navegando por elas
Fetching: Yarn procura no seu cache para verificar se o pacote já não foi baixado, se não existir lá ele vai fazer o download do pacote (tarball file) e colocar no cache, dessa forma ele só usara a internet se o pacote não existir no cache,
Linking: Yarn copia os arquivos dos pacotes do global cache para o diretório node_modules local.
Devo parar de usar o NPM para usar o Yarn?
Eu estou usando no meu dia a dia, nesse pequeno período de tempo não tive nenhum problema, ele é mais rápido, então sendo curto e grosso a resposta é: sim.
Mas fica uma pergunta no ar: será que é bom para o ecossistema do node ter mais um cliente de gerenciamento de pacotes?
Essa pergunta vou deixar para outro post, mas gostaria de saber a opinião de vocês. O que vocês acham?