Este guia orientará você no processo mais fácil de construção e lançamento de seu pacote NPM, do início ao fim, usando um microbundle .
Vamos falar um pouco sobre isso microbundle
. Acho que é particularmente eficaz para bibliotecas simples porque você não precisa se preocupar com configuração, permitindo que você se concentre no desenvolvimento do seu pacote.
Aqui está uma pequena lista de seus recursos:
- Configurações integradas; tudo que você precisa fazer é adicionar um campo “exportações” em
package.json
- Suporte TypeScript pronto para uso, sem
tsconfig.json
- Vários formatos de saída (CJS, UMD e ESM)
- Compressão Terser integrada
Basicamente, microbundle
é construído sobre rollup.js . Se você tiver bibliotecas mais complexas para construir do que as mencionadas neste artigo, considere usar uma configuração rollup.js
pura.
Inicializando seu pacote
Como exemplo, vamos criar uma biblioteca simples para somar dois números, que exportará apenas uma função sum
.
Crie uma pasta para o projeto e execute
npm init
com valores padrão para gerarpackage.json
Crie
index.ts
na pastasrc
// src/index.ts export function sum(a: number, b: number) { return a + b; }
Instalar
microbundle
npm i -D microbundle
Atualize
package.json
com os seguintes valores:// package.json ... "type": "module", "source": "src/index.ts", // your source code "exports": { "types": "./dist/index.d.ts", // TypeScript declaration file "require": "./dist/index.cjs", // CommonJS entry point "default": "./dist/index.esm.js" // ES Module entry point }, "main": "./dist/index.cjs", // where to generate the CommonJS bundle "module": "./dist/index.esm.js", // where to generate the ESM bundle "unpkg": "./dist/index.umd.js", // where to generate the UMD bundle "types": "./dist/index.d.ts", // TypeScript declaration file for the package "scripts": { "build": "microbundle", // compiles "source" to "main", "module", "unpkg" "dev": "microbundle watch" // re-build when source files change } ...
Execute o script de construção
npm run build
A saída deve conter exatamente os arquivos que declaramos em
package.json
E pronto, fizemos nosso primeiro pacote. Vamos dar uma olhada em cenários mais complexos.
Adicionando React à sua biblioteca
Se você quiser trazer o React para sua biblioteca, você ainda pode usá-lo microbundle
, mas agora seu comando de construção deve ficar assim:
microbundle --jsx React.createElement --jsxFragment React.Fragment --jsxImportSource react --globals react/jsx-runtime=jsx
Adicione o comando package.json
ao script build
para conveniência futura:
// package.json ... "scripts": { "build": "microbundle --jsx React.createElement --jsxFragment React.Fragment --jsxImportSource react --globals react/jsx-runtime=jsx" } ...
Usando o Storybook para componentes de UI
Ao construir uma biblioteca de UI, você pode precisar de um sandbox onde possa desenvolver, visualizar componentes e fornecer componentes de demonstração para sua documentação.
Aí vem o livro de histórias . É uma sandbox com sua própria interface e empacotador convenientes, onde você pode descrever facilmente vários estados de seus componentes. Cada captura do estado do seu componente é chamada de "história".
Esta imagem, tirada da documentação, mostra sua aparência:
Instalar o Storybook é bastante simples; basta executar o comando dentro da sua biblioteca:
npx storybook@latest init
Este comando instalará todas as dependências necessárias para o Storybook, adicionará scripts para execução e construirá o Storybook em package.json
, criará uma pasta .storybook
com configuração padrão e adicionará alguns exemplos de histórias à pasta src/stories
.
Integrando estilo em sua biblioteca
Você pode adicionar estilo de duas maneiras: arquivo CSS ou CSS-in-JS. O arquivo CSS permite fácil personalização, mas requer inclusão separada, enquanto o CSS-in-JS simplifica o estilo, mas aumenta o tamanho do pacote.
Arquivo CSS
Crie um arquivo CSS no diretório src e importe-o para o arquivo do componente root react:
// src/index.tsx import './styles.css'; export const MySuperComponent = () => { return ( <h1 className="title">Hi there!</h1> ) };
Então, vamos executar o comando build novamente.
npm run build
E seu arquivo
styles.css
importado será criado na pastadist
:Ótimo! Obtivemos um arquivo CSS com os estilos necessários. No entanto, há um pequeno inconveniente com esta solução. O arquivo CSS precisa ser adicionado separadamente após a instalação do pacote.
Portanto, os usuários da sua biblioteca precisarão usar um carregador CSS (por exemplo, um carregador CSS para o webpack) para lidar com seu arquivo CSS, e seu uso será semelhante a este:
import { MySuperComponent } from 'my-super-library'; import 'my-super-library/dist/styles.css'; export const App = () => { return ( <MySuperComponent /> ); }
CSS em JS
Você pode usar bibliotecas como componentes estilizados para essa finalidade. E ficará assim:
import styled from 'styled-components'; const Title = styled.h1` font-size: 30px; font-weight: bold; `; export const MySuperComponent = () => { return ( <Title>Hi there!</Title> ) };
Com esta solução, os usuários não precisarão importar um arquivo CSS e adicionar um carregador especial para seu projeto. Após a instalação da biblioteca, o componente virá com um estilo próprio. No entanto, isso aumentará o tamanho do pacote e tornará mais difícil para os usuários personalizarem elementos usando seletores CSS.
Escolha a opção que melhor lhe convier. Prefiro usar o arquivo CSS porque ele permite aos usuários personalizar qualquer elemento com seletores CSS, não afeta o tamanho do pacote e funciona mais rápido.
Desenvolvendo um arquivo README.md detalhado
Um arquivo README.md fornece informações sobre sua biblioteca, como instalá-la, seu uso básico e os recursos que possui. Geralmente, esse é o primeiro arquivo que os desenvolvedores leem quando encontram seu repositório ou pacote NPM, portanto, deve ser conciso e informativo.
Gosto de criar uma estrutura na seguinte ordem:
- Título
- Descrição super curta do pacote
- Emblemas estatísticos sofisticados ( shields.io )
- Se sua biblioteca for um componente de UI, inclua uma captura de tela ou forneça um link de demonstração no CodeSandbox
- Lista de recursos
- Guia de instalação
- Fragmentos de código com uso
- Opções e adereços que sua biblioteca aceita para configuração
Você pode consultar exemplos de arquivos README.md
de meus pacotes, como dot-path-value e react-nested-dropdown , para se inspirar.
Navegando no gerenciamento de dependências
Esta é uma parte importante porque se você fizer algo errado, os usuários poderão enfrentar conflitos de versão ou outros problemas e terão que remover sua biblioteca. Então, vamos dar uma olhada nas principais diferenças entre os tipos de dependência.
- “devDependencies” são apenas para desenvolvimento e não serão incluídos no seu pacote. Por exemplo, se você tiver o pacote
microbundle
instalado, que os usuários não precisam usar, mantenha-o em devDependencies e ele não aparecerá no pacote.
- "dependências" serão instaladas junto com o pacote. Inclua dependências que seu pacote precisa para funcionar nos projetos dos usuários. Observe que algumas dependências, como “react”, podem já estar instaladas no projeto do usuário. Ter uma “reação” duplicada em seu pacote pode aumentar o tamanho do pacote. É aqui que “peerDependencies” são úteis.
“peerDependencies” são dependências que seu pacote usa, mas não incluirá em seu pacote. Seu pacote utilizará a versão da dependência que o usuário possui em seu projeto.
Basicamente, devemos especificar uma dependência de pares se estivermos criando uma biblioteca para seu ecossistema. Por exemplo, se você estiver criando um componente React, defina React como uma dependência de mesmo nível. Se estiver desenvolvendo um componente React com um calendário, adicione React e uma biblioteca de cálculo de data (por exemplo, date-fns) como peerDependencies.
Se o usuário não tiver a dependência de mesmo nível especificada em seu projeto, o comando
npm install
exibirá um aviso, mas não instalará a dependência automaticamente.
Apenas um pequeno exemplo de como fica:
// package.json ... "dependencies": { // libraries which will be installed along with your library "clsx": "^1.2.1" // just library for className combining }, "peerDependencies": { // user should have these packages installed "react": "^16.8.0 || ^17.0.0 || ^18.0.0" // user should have react 16.8+ version }, "devDependencies": { // won't be in user's bundle, these libraries just for your developing needs "@types/react": "^18.2.33", "react": "^18.2.0", // in case if we are using storybook, we need actual react library to render our components there "microbundle": "^0.15.1", }, ...
Usando GitHub para seu pacote
Se você estiver publicando um pacote NPM, significa que ele estará acessível publicamente (se você tiver uma conta gratuita). Para coletar feedback dos usuários, você pode criar um repositório GitHub para seu código original. As pessoas podem criar problemas e se comunicar com você sobre seu pacote lá. Você também pode descrever seus lançamentos e ganhar algumas estrelas!
Você certamente pode pular esta etapa, mas é parte integrante da cultura do desenvolvedor e pode ser uma contribuição valiosa para o código aberto.
Publicando e mantendo o pacote
Antes de publicar seu pacote, é essencial garantir que seu arquivo package.json
esteja configurado corretamente. Aqui estão alguns passos importantes a seguir:
Nomeie e tente descrever a funcionalidade principal da sua biblioteca. Por exemplo:
"name": "react-color-picker"
Adicione informações do repositório GitHub (se existir):
... "homepage": "https://github.com/{your_repository}", "repository": { "type": "git", "url": "https://github.com/{your_repository}" }, "bugs": { "url": "https://github.com/{your_repository}/issues" }, ...
Configure os
files
:... "files": [ "dist", ], ...
Você deve especificar os arquivos que serão incluídos em
node_modules
, quando sua biblioteca for instalada. Normalmente, incluir a pastadist
é suficiente.
Adicione
keywords
:Palavras-chave são uma série de strings que descrevem seu pacote e são usadas pelo NPM para pesquisas e recomendações. Escolha palavras relevantes para o seu pacote que você prevê que as pessoas usarão durante a pesquisa. Vamos criar palavras-chave para nossa biblioteca
sum
:... "keywords": ["typescript", "math", "sum", "numbers", "arithmetic", "calculator", "calculation"] ...
É importante especificar suas tecnologias porque os usuários costumam pesquisar termos como “biblioteca digitada para matemática” ou “seletor de calendário react”.
Crie uma conta NPM , se ainda não o fez, e execute
npm login
em seu terminal; siga as instruções para autenticar sua conta. Por padrão, a versão do seu pacote será1.0.0
; você pode verificar isso no arquivopackage.json
. Eu recomendo alterá-lo para0.0.1
.
Execute
npm publish
e pronto! Para atualizar a versão no futuro, use o comandonpm version patch
para incrementar a versão e, em seguida, publique o pacote atualizado comnpm publish
.
Conclusão
Como você pode ver, criar sua própria biblioteca é muito fácil! Essencialmente, isso é tudo que você precisa para criar e manter o pacote. Se você tiver dificuldade em limitar sua biblioteca com microbundle
, recomendo usar rollup.js com uma configuração mais específica.
Criar pacotes NPM e contribuir com código aberto é uma experiência gratificante e valiosa para desenvolvedores de todos os níveis de habilidade. Ele permite que você compartilhe seu código com a comunidade, ganhe muita experiência e construa um portfólio de seu trabalho.