Criando sua própria lib de componentes em React e publicando no npm registry

Como criar um node package com componentes em React e publicá-lo no npm registry como um node module em poucas etapas, para reutilizá-lo em diversos projetos e contribuir com a comunidade!

Rafael Maruta
React Brasil
Published in
8 min readNov 21, 2018

--

imagem emprestada e editada de https://www.bleepingcomputer.com/news/security/52-percent-of-all-javascript-npm-packages-could-have-been-hacked-via-weak-credentials/

Olá pessoal! Tudo bem? Já faz um tempinho que não escrevo por aqui né? Mas vamos lá!

Este artigo é referente à palestra que dei junto com o no Meetup #16 Frontend SP no dia 26/10/2018 na sede do Nubank. É isso mesmo, agora sou Software Engineer no Nubank =D.

O interessante deste artigo é que apesar dele orientá-lo a criar uma dependência com React, ele pode ser seguido para qualquer módulo baseado em JavaScript.

Antes de tudo, é importante frisarmos alguns pontos:

  • Neste artigo vamos usar algumas aplicações, porém não é intenção se aprofundar sobre cada uma, apenas no que é mais relevante ao tema. No decorrer do artigo vou deixando links relevantes caso você queira se informar mais
  • Não é obrigatório mas facilita se você já tiver usado ou tiver um conhecimento extra sobre as aplicações que usamos aqui, como o npm, rollup.js ou Webpack. De qualquer forma deixarei um repositório funcional do GitHub no final do artigo contendo um arquivo readme com o passo-a-passo de como instalar e rodar o projeto

Agora, primeiramente, uma pergunta:

Qual a vantagem de se criar um módulo e publicar no npm registry?

Ao criar um módulo, como a própria definição do nome diz, ele se torna uma parte independente e reaproveitável em diversos lugares de um projeto, ou entre projetos. Publicando no npm registry, ele ficará disponível para a vasta comunidade que usa o JavaScript com o npm, e assim você poderá ajudar muita gente =). Hoje em dia a maioria dos JSDevs usam o npm, pois ele torna o projeto mais sustentável.

A seguir, é importante que você entenda alguns termos:

O que são Node Packages e Node Modules? E qual a diferença?

Node Packages, assim como é dito aqui, é um arquivo ou diretório que é descrito por um arquivo package.json (melhor descrito mais adiante) para ser publicado no npm registry. São módulos em JavaScript powered by Node.js

Node Modules, assim como dito aqui, é qualquer arquivo ou diretório dentro do diretório node_modules que pode ser carregado pela função do Node.js require() (ou importado via ESModules)

Para criar um node module, primeiramente você precisará criar um projeto, que é o node package. Não é obrigatório publicá-lo no npm registry, mas é uma enorme vantagem disponibilizá-lo à vasta comunidade, pois quem ajuda, fatalmente será ajudado. É possível publicar no npm registry de forma privada também, confira aqui os primeiros passos de como fazer. Pode também usar aplicações privadas de versionamento como o Nexus.

Para conectar o nosso projeto aos módulos do npm registry precisamos do auxílio de uma aplicação: o npm.

O que é o npm?

O npm (Node Pack Manager) é uma aplicação que gerencia um projeto baseado em node. Usa o arquivo package.json, que é a raiz de configuração, onde estão definidos os módulos que são dependências do projeto.

É algo parecido com isto:

exemplo simples de um arquivo package.json

O package.json principalmente diz quais os módulos que deverão ser baixados do npm registry (ou de outro lugar se for definido). Basta executar o comando npm install via terminal no mesmo diretório que está o package.json. Para saber mais sobre o package.json clique aqui.

Quando precisamos executar comandos referentes ao projeto, como rodá-lo, fazer build etc. usamos os:

npm scripts

São apenas comandos que serão executados via terminal e acionarão aplicações responsáveis por tarefas como:

  • Validação de código (lint ou Code Style)
  • Iniciar um servidor de desenvolvimento (geralmente feito em node)
  • Fazer build para produção
  • Execução de testes unitários, integração etc.
  • Dentre várias outras features

Como alternativa ao npm temos o Yarn, que é uma ferramenta do Facebook que faz quase as mesmas coisas que o npm, com algumas vantagens e desvantagens. Ele trouxe algumas inovações mas o npm também evoluiu com o tempo, sendo delicado distinguir qual deles é o melhor. Acredito que é melhor que você teste ambos e escolha o seu favorito.

Mas… Que aplicações são essas que são acionadas pelos npm scripts, que realmente iniciam o servidor local, geram o build para produção e outras features legais com mais facilidade?

São os…

Module Bundlers

imagem editada e emprestada de https://webpack.js.org/

Uma imagem vale mais do que mil palavras, e a imagem acima é o melhor exemplo disto. Os module bundlers são aplicações com um conjunto de features que mapeiam todos os módulos de um projeto partir de um arquivo de entrada, juntando, otimizando, minificando, convertendo, transpilando, batendo no liquidificador etc. para gerarem arquivos finais que são interpretáveis à plataforma que vai rodar a aplicação (tipo um navegador web). Usaremos eles para gerar os node modules e depois publicar no npm registry!

A ideia aqui é usarmos duas das mais usadas aplicações para compararmos e entendermos as suas diferenças, mas antes veremos algumas configurações importantes a serem feitas no package.json do node package:

Configurações no arquivo package.json

  • name: nome do pacote no npm registry e que serve como ID. É o nome que será inserido nas dependências de quem quiser usar o seu módulo
  • description: ajuda na search do pacote no npm registry. Pense numa boa descrição para que outros devs encontrem o seu módulo no npm registry!
  • version: define a versão e informa o npm registry quando o pacote sofreu alterações
  • main: aponta para o arquivo de entrada de leitura quando ele se tornar um node module
  • files: arquivos/pastas que fazem parte do package

O campo peerDependencies

ainda no package.json

No campo peerDependencies você coloca as dependências necessárias do seu node package que, se o projeto que o utiliza como node module as tiver em comum, elas serão reaproveitadas, não precisando serem baixadas ou instaladas novamente. A variável x significa que pode ser qualquer release, que no caso no print, qualquer minor release (subentendendo-se qualquer patch release também). Para saber mais sobre software versioning, clique aqui.

Usando o rollup.js

O rollup.js é um module bundler simples e que exige pouca configuração. É notável que foi desenvolvido pensado para a criação de node packages. Abaixo um trecho importante na sua configuração para se gerar um node module:

config.js do rollup
  • format: formato do output que será gerado
  • external: as dependências externas que deverão ser removidas do bundle do node module, pois serão baixadas via peerDependencies

Alguns formatos aceitos:

  • cjs: CommonJS, formato do node, que usa require e module.exports
  • esm: EcmaScript Modules, com imports e exports
  • umd: Universal Module Definition, funciona em praticamente todos os ambientes e pode ser usado via tag script

Para entender melhor estes formatos de módulos de JavaScript, recomendo este excelente artigo.

Não é objetivo deste artigo se aprofundar no rollup.js. Para conhecer mais, veja a documentação oficial.

Usando o Webpack

O Webpack é um module bundler robusto bem conhecido pela comunidade e é capaz de lidar com praticamente todos os tipos e tamanhos de aplicações, porém ao custo de uma configuração mais complexa. Mesmo que a versão 4 seja #0CJS (zero config JavaScript), para casos específicos ainda há a necessidade de configuração, como é o caso:

config.js do Webpack
  • libraryTarget: formato do output que será gerado
  • externals: as dependências externas que deverão ser removidas do bundle do node module, pois serão baixadas via peerDependencies

Alguns formatos aceitos:

  • var: módulo fica disponível em uma variável global via tag <script>
  • this: via objeto this
  • window: através do objeto window do navegador
  • umd: AMD ou CommonJS (node)

Para obter mais detalhes sobre como configurar um módulo com Webpack, confira aqui.

Não é objetivo deste artigo se aprofundar no Webpack. Para conhecer mais, e inclusive eu recomendo que você faça isso, veja a documentação oficial.

Em quais casos usar um ou outro?

rollup.js
  • Use rollup.js caso queira gastar menos tempo com configurações
  • Ele é recomendado para módulos pequenos e mais simples
  • Ele exporta para o formato ESM (EcmaScript Modules, ou seja, com imports e exports)
  • Use o Webpack caso vá precisar de uma alta necessidade de customização
  • Ele é recomendado para módulos mais complexos, com diversas funcionalidades
  • Diferentemente do rollup.js, não exporta para o formato ESM

O Webpack possui melhor compatibilidade com módulos carregados via SSR (Server Side Rendering), pois é possível utilizar alguns truques como substituir a variável global window por this colocando a seguinte linha no campo output do arquivo de configuração:

globalObject: "(typeof window !== 'undefined' ? window : this)"

Outra diferença entre eles é que o formato:

UMD do rollup.js !== UMD do Webpack

Se você quiser usar o CJS do rollup.js no Webpack, terá que usar o formato UMD (!!!)

E o repositório no GitHub que eu prometi no início do artigo?

Fiquem tranquilos pessoal, segue abaixo o link do repositório conforme eu prometi, com tudo o que vimos e funcionando:

O readme explica como instalar, como estão separadas as pastas de cada node package e tem até um sample que importa os node modules do npm registry. Tudo bem simples mas lhe proporcionando um grande poder!

Publicando o pacote no npm registry

Agora o último passo a entender é a publicação. Para publicar o seu node package no npm registry, e assim torná-lo um node module, é bem simples, é só seguir os passos a seguir:

  1. Crie uma conta no https://www.npmjs.com/
  2. Execute no terminal npm login e logar com as credenciais criadas no npmjs
  3. Execute npm publish na pasta do projeto
  4. E então use em outros projetos!

Há alguns comandos que podem ser executados caso você queira fazer bump (update) de versão, que aí o package.json será atualizado. Clique aqui para conferir.

Para saber quando, o que e porque atualizar a versão, fazendo isto semânticamente, clique aqui.

Conclusão

Através deste artigo cobrimos os pontos chaves para se criar um node package e, a partir dele, gerar um node module publicando no npm registry!

Qualquer dúvida ou comentários, fiquem a vontade aqui abaixo!

Muito obrigado!

--

--