O guia completo do package.json do Node.js

Node.js

O guia completo do package.json do Node.js

Luiz Duarte
Escrito por Luiz Duarte em 22/08/2019
Junte-se a mais de 34 mil devs

Entre para minha lista e receba conteúdos exclusivos e com prioridade

O package.json é um elemento-chave em muitas aplicações do ecossistema Node.js. Se você trabalha com JavaScript, ou se você já interagiu com um projeto JavaScript antes, Node.js ou front-end, você certamente já se deparou com um arquivo package.json.

Para quê ele serve?

O que você deveria saber sobre ele e que coisas legais pode fazer com ele?

O package.json é uma espécie de manifesto do seu projeto. Ele pode fazer várias coisas, completamente não relacionadas. Ele é um repositório central de configurações de ferramentas, por exemplo. Ele também é onde npm armazena os nomes e versões dos pacotes instalados.

Neste artigo você vai ver:

Caso prefira, o vídeo abaixo resume os principais pontos deste artigo.

Vamos lá!

A estrutura do arquivo

Aqui temos um exemplo de arquivo package.json válido:

Está vazio Não existem exigências fixas do que deve estar em um arquivo package.json para uma aplicação. O único requisito é que ele respeite o formato JSON, de outra maneira ele não poderá ser lido pelos programas que tentarem acessar suas propriedades programaticamente. Se você está construindo um pacote Node.js que você quer distribuir através do npm, as coisas mudam radicalmente e você deve ter um conjunto de propriedades que ajudem outras pessoas a usá-lo. Veremos mais sobre isso mais tarde. Este é outro package.json válido:

Ele define uma propriedade name, que diz o nome da aplicação ou pacote, que está contido na mesma pasta onde o arquivo vive. Aqui temos um exemplo mais complexo, o qual eu extraí de uma aplicação de exemplo:

Existem muitas coisas acontecendo aqui:

  • name define o nome da aplicação ou pacote;
  • version indica a versão atual;
  • description é um resumo da sua aplicação/pacote;
  • main define o ponto de entrada da aplicação (o que vai ser retornado se alguém der um require no nosso pacote);
  • private (true) previne a sua aplicação de ser publicada acidentalmente no npm;
  • scripts define um conjunto de scripts Node para você executar;
  • dependencies define uma lista de pacotes npm instalados como dependências de produção;
  • devDependencies define uma lista de pacotes npm instalados como dependências de desenvolvimento;
  • engines define quais versões de Node este pacote/aplicação funciona;

Todas estas propriedades são usadas tanto pelo npm quanto por outras ferramentas que podemos usar.

Detalhando as propriedades

Esta seção descreve as propriedades que você pode usar em detalhes. Eu refiro várias vezes a pacote, mas a mesma coisa se aplica a aplicações locais que você não use como pacote. A maioria destas propriedades são usadas somente no site do npm. Outras são usadas por scripts que interagem com seu código, como npm ou outros.

name define o nome do pacote, caso você venha a publicá-lo no NPM algum dia. Ex:

O nome deve ser menor que 214 caracteres, não pode ter espaços e somente pode conter letras minúsculas, hífens (-) ou underscore (_).

Isto tudo porque quando um pacote é publicado no npm, ele ganha sua URL baseado nesta propriedade. Se você publicou este pacote publicamente no GitHub, um bom valor para esta propriedade é o nome do repositório.

author exibe o nome do autor do pacote (útil para o NPM também). Ex:

Também pode ser usado neste formato:

contributors

Assim como o autor, o projeto pode ter um ou mais contribuidores. Esta propriedade é uma array que os lista:

Pode também ser usado neste formato:

bugs

Links para o issue tracker do pacote, geralmente uma página de issues no GitHub. Ex:

homepage

Define o site do pacote, geralmente onde tem a documentação do mesmo. Ex:

version

Indica a versão atual do pacote. Ex:

Esta propriedade segue a notação semântica de versionamento (semver), o que significa que a versão é sempre expressada com três números: x.x.x.

O primeiro número é a versão principal, o segundo é a versão secundária e o terceiro é a versão do patch.

Existe um significado nestes números: uma release que somente corrija bugs é uma release patch, uma release que introduza mudanças na compatibilidade retroativa é uma release secundária e uma release principal é aquela que pode quebrar compatibilidade.

Curso FullStack

license Indica a licença do pacote. Ex:

keywords Esta propriedade contém um array ou palavras-chave associados com o que seu pacote faz. Ex:

Isto ajuda as pessoas a encontrar o seu pacote quando estiverem procurando pacotes similares ou quando navegam pelo site do npm.

description

Esta propriedade contém um resumo do pacote. Ex:

Isto é especialmente útil se você decidir publicar seu pacote para o npm, visando que outras pessoas possam descobrir o que este pacote faz.

repository Esta propriedade especifica onde o repositório do pacote está localizado. Ex:

Note o prefixo github. Existem outros serviços populares também:

Você pode explicitamente definir o controle de versão do sistema:

Você também pode usar diferentes sistemas de controle de versão:

main Define o ponto de entrada do pacote. Quando você importa este pacote em uma aplicação, é essa aplicação que a aplicação irá buscar pelo module.exports. Ex:

private Se definido como true, previne que a aplicação/pacote seja acidentalmente publicada no npm. Ex:

scripts Define um conjunto de scripts node que você pode executar. Ex:

Estes scripts são aplicações de linha de comando. Você pode rodá-los usando npm run XXXX, onde XXXX é o nome do comando. Ex:

Você pode usar qualquer nome que você quiser para um comando, e os scripts podem ser literalmente qualquer coisa que você quiser.

dependencies

Define uma lista de pacotes npm instalados como dependências. Quando você instalar um pacote usando npm:

o pacote será automaticamente inserido nesta lista. Exemplo:

devDependencies

Define uma lista de pacotes npm instalados como dependências de desenvolvimento. Eles diferem de dependencies porque eles serão instalados somente em máquinas de desenvolvimento, não necessárias para executar o código em produção.

Quando você instalar um pacote usando npm:

o pacote será automaticamente inserido nessa lista. Exemplo:

engines

Define quais versões de Node.js e outros comandos que este pacote ou aplicação suporta. Exemplo:

browserslist

É usado para dizer quais browsers (e suas versões) você quer suportar. Ele é referenciado pelo Babel, Autoprefixer, e outras ferramentas, para somente adicionar os polyfills e fallbacks necessários aos navegadores-alvo. Exemplo:

Esta configuração significa que você quer suportar ao menos as duas versões principais de todos os browsers com ao menos 1% de uso no mercado (as estatísticas são do CanIUse.com ), exceto IE8 e inferiores (saiba mais no browserslist do NPM).

Comandos específicos de propriedades

O arquivo package.json também pode hospedar configurações de comandos específicos, por exemplo Babel, ESLint, e muito mais.

Cada um possui uma propriedade específica, como eslintConfigbabel e outros. Estes são comandos específicos e você pode encontrar como usá-los na documentação do respectivo comando ou projeto.

Versões de Pacote

Então você abre o packages.json e rapidamente entende que as dependencies são os pacotes que sua aplicação usa, mas onde deveriam estar listadas as versões dos pacotes tem um monte de símbolos que não lhe dizem muita coisa…Por exemplo, qual a diferença entre o til (˜) e o circunflexo (^) no package.json?

  • O til garante que o pacote seja sempre carregado  respeitando o número do meio da versão. Ex: ˜1.2.3 pega o pacote mais recente da versão 1.2.x, mas não vai atualizar para 1.3. Geralmente garante que correções de bugs sejam atualizados no seu pacote.
  • O circunflexo garante que o pacote seja sempre carregado respeitando o primeiro número da versão. Ex: ˆ1.2.3 pega o pacote mais recente da versão 1.x, mas não vai atualizar para 2.0. Garante que bugs e novas funcionalidades do seu pacote sejam atualizados, mas não novas versões “major” dele.

A imagem abaixo ajuda a entender o template de versões dos pacotes do NPM, que aliás usa um padrão bem comum da indústria de software:

Outros símbolos incluem:

  • >, >=, <, <=1.0: a versão deve ser superior, superior ou igual, inferior, inferior ou igual à 1.0, respectivamente.
  • 1.2.x: equivalente a ˜1.2.0
  • *: qualquer versão do pacote
  • latest: a versão mais recente do pacote

Agora se você não tiver símbolo algum, aí o pacote deve ser sempre carregado usando a versão especificada.

Uma dica bem valiosa aqui (quem não gosta de um bônus?) para quando se quer atualizar todos pacotes é colocar * na versão de todos e rodar o comando “npm update –save” sobre a pasta do projeto.

O arquivo package-lock.json

Na versão 5 o NPM introduziu o arquivo package-lock.json, que é automaticamente gerado quando você instala pacotes Node.

O que ele faz? Você provavelmente sabe tudo sobre o arquivo package.json a essa altura, o que é bem mais comum e está aí há bem mais tempo.

O objetivo deste arquivo é manter registro das versões exatas de cada pacote que é instalado para que um produto possa ser 100% reproduzível da mesma maneira mesmo se os pacotes forem atualizados por seus mantenedores.

Isto soluciona um problema bem específico que o package.json não resolvia. No package.json você pode definir quais versões você quer atualizar, usando a notação semver, por exemplo:

  • se você escrever ~0.13.0, você quer somente atualizar patch releases: 0.13.1 está ok, mas 0.14.0 não.
  • se você escrever ^0.13.0, você quer atualizar patches e minor releases: 0.13.10.14.0 e assim por diante.
  • se você escrevere 0.13.0, você somente usará esta versão exata do pacote.

Você não commita no Git a sua pasta node_modules, uma vez que ela é geralmente muito grande, e quando você tenta replicar o projeto em outra máquina usando o comando npm install, se você especificar a sintaxe ~ e uma patch release de um pacote tiver sido lançada, ela será instalada. O mesmo para  ^ e minor releases.

Se você especificar as versões exatas, como 0.13.0 neste exemplo, você não sofre desse problema.

Além poder ser um problema para você, pode ser um problema para outra pessoa qualquer querendo rodar o seu projeto com npm install, podendo acontecer do seu projeto original ficar diferente da nova instalação. Isto implica obviamente em possíveis bugs, mesmo que seja um patch ou minor release.

O arquivo package-lock.json define as versões instaladas de cada pacote de maneira irreversível e o npm usará exatamente estas versões quando você rodar npm install.

Este conceito não é novo e outros gerenciadores de pacotes de linguagens de programação (como o Composer do PHP) usam um sistema semelhante por anos.

O arquivo package-lock.json precisa ser commitado no Git para que possa ser baixado por outras pessoas. E se precisar atualizar as versões das dependências no package-lock.json, basta rodar npm update.

Espero que este artigo tenha sido útil para você que está aprendendo Node.js Para conteúdo mais aprofundado, recomendo meus livros. Para videoaulas, recomendo o meu curso online (abaixo).

Curso Node.js e MongoDB

TAGS: nodejs

Olá, tudo bem?

O que você achou deste conteúdo? Conte nos comentários.

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *

9 Replies to “O guia completo do package.json do Node.js”

API Gateway em Arquitetura de Microservices com Node.js - LuizTools

[…] O guia completo do package.json do Node.js […]

Arquitetura de micro serviços em Node.js + MongoDB: Parte 4 - LuizTools

[…] O guia completo do package.json do Node.js […]

TDD: Como criar unit tests em Node.js com Tape - LuizTools

[…] O guia completo do package.json do Node.js […]

Criando um chat com Node.js e Socket.io - LuizTools

[…] O guia completo do package.json do Node.js […]

Tutorial Node.js com MS SQL Server - LuizTools

[…] O guia completo do package.json do Node.js […]

Tutorial CRUD em Node.js com driver nativo do MongoDB - LuizTools

[…] O guia completo do package.json do Node.js […]

Tutorial NodeJS com MongoDB (Express + EJS + Mongoose) - LuizTools

[…] O guia completo do package.json do Node.js […]

Como criar uma API com Node.js (com Express, MongoDB e Mongoose) - LuizTools

[…] O guia completo do package.json do Node.js […]

Arquitetura de micro serviços em Node.js + MongoDB: Parte 2 - LuizTools

[…] O guia completo do package.json do Node.js […]