• Home

    Escolha seu Plano

    Carreiras Alura

    Evolua com profundidade técnica, direção clara e aplicação prática.

    Jornadas guiadas do básico ao avançado com checkpoints práticos, desenhadas para quem busca profundidade e protagonismo técnico.

    Iniciante

    Comece do zero com uma trilha clara e progressiva.

    Fundamentos práticos para dar os primeiros passos com segurança e construir uma base sólida.

    Intermediário

    Continue sua evolução com cursos que conectam fundamentos, ferramentas e prática profissional. Ganhe autonomia, e avance para projetos mais completos.

    Avançado

    Aprofunde temas técnicos e estratégicos para enfrentar desafios mais complexos. Explore boas práticas, arquitetura, performance com visão profissional.

    Cursos

    Ver mais cursos de Back-end
    • Pensamento computacional: fundamentos da computação e lógica de programação
    • Lógica de programação: mergulhe em programação com JavaScript
    • DDD: fundamentos do design orientado a domínio
    • ASP.NET: autenticação e autorização em APIs e aplicações web
    • Microsserviços: migração de monólitos e modularização

    Cursos

    Ver mais cursos de Dados
    • Python para Dados: primeiros passos
    • Excel: domine o editor de planilhas
    • Engenharia de Dados: Orquestração de Pipelines com Apache Airflow
    • Power BI Desktop: construindo meu primeiro dashboard
    • Governança e Arquitetura de Dados

    Cursos

    Ver mais cursos de Inteligência Artificial
    • IA: Explorando o Potencial da Inteligência Artificial Generativa
    • Engenharia de Prompt: Criando Prompts Eficazes para IA Generativa
    • Claude para Análise de Dados: prompts, integrações e automações
    • Agno: criando agentes e sistemas multiagente
    • Engenharia de software na era da IA: segurança de aplicações com agentes, MCPs e código gerado por IA

    Cursos

    Ver mais cursos de Front-end
    • HTML e CSS: ambiente, estrutura e estilo
    • React: realizando testes avançados com Jest e Testing Library
    • React: integrando TypeScript em projetos
    • JavaScript: aprendendo a programar
    • React: aplicando arquiteturas de Micro frontends

    Cursos

    Ver mais cursos de DevOps
    • Sistema Operacional Linux: fundamentos e administração prática
    • Containers e Docker: empacotamento, isolamento e gestão
    • Redes: dos conceitos iniciais à criação de uma intranet
    • Linux: gerenciando diretórios, arquivos, permissões e processos
    • Cibersegurança: Fundamentos e práticas integradas

    Cursos

    Ver mais cursos de UX & Design
    • UX Research: mapeando a experiência da pessoa usuária
    • UX/UI Design: Entregando produtos digitais com IA
    • UI Design: Prototipação e animações interativas
    • Figma: Conhecendo o programa
    • Product Design: métricas e ciclo de vida do produto

    Cursos

    Ver mais cursos de Gestão & Negócios
    • Canva: Criação de landing pages e e-mail marketing
    • Agilidade: como ela pode ajudar a criar um time de alta performance
    • Google Analytics 4: Extrair insights e configurar eventos
    • Management 3.0: gerencie o ambiente, não as pessoas
    • Automação de processos com n8n: Inteligência de dados para Marketing

    Cursos

    Ver mais cursos de Mobile
    • React Native: Estilização e Layouts com Flexbox e StyleSheet
    • Flutter: Graphql e suporte offline
    • Android com Gemini: Trabalhando com textos e imagens na IA
    • Dart: trabalhando com orientação a objetos
    • React Native: Dominando Listas com FlatList e ScrollView

    Carreiras

    Ver mais carreiras
    • Especialista em IA
    • Engenharia de IA
    • Ai native software engineering
    • Arquitetura de Soluções com IA
    • AI Product Design
    • Engenharia de Machine Learning
    • Desenvolvimento Front-End React
    • Engenharia de Dados
    • Cloud Security
    • Social Media Marketing
    • Engenharia de Agentes de IA

    Cursos

    • Engenharia de Prompt: Prompts Eficazes para IA Generativa
    • Claude Code: Criando sua Primeira Aplicação
    • Python: Crie sua Primeira Aplicação
    • Git e GitHub: Compartilhando e Colaborando
    • N8N: Fluxos de Trabalho Avançados

    Cursos

    • Copilot Studio: Solução Multiagentes
    • Padrões de API HTTP e Modelagem de APIs
    • Python para Análise de Dados com SQL
    • Docker: Criando e Gerenciando Containers
    • Design com IA: Otimizando o Processo Criativo

    Cursos

    • Model Context Protocol (MCP)
    • Spec-Driven Development: Dev Assistido por Agentes
    • Arquitetura de Sistemas Distribuídos com Java
    • Governança de Modelos e Reprodutibilidade
    • Pentest: Vulnerabilidades em Aplicações Web

    Escolha seu Plano

    Skills & Go

    O Skills & Go é para Tech Leads, Product Managers, estrategistas e early adopters que transformam ideias em soluções de alto impacto. Em cursos ao vivo e 100% online, você domina a nova era da IA em tempo real.

    Aulas ao vivo

    Saiba mais
    • Agentic Engineering: orquestre múltiplos agentes com confiabilidade
    • Building AI Products: transforme ideias em produtos reais com IA
    • AI Data Strategy: transforme dados em decisões estratégicas com IA

    Escolha seu Plano

    Eventos Alura

    Nossos eventos são pensados para quem quer estar à frente das mudanças em tecnologia, IA e inovação. Em experiências presenciais, você acompanha tendências e se conecta com especialistas que estão moldando o futuro.

    Próximos eventos

    • Imersão Engenharia de Software: Dev na Era da IA
    • IA Conference
    • Alura Signals
  • Talent Lab
  • IA

    Escolha seu Plano

    Conteúdos gratuitos

    Explore conteúdos gratuitos para aprender tecnologia no seu ritmo. Encontre artigos com conteúdos técnicos para aprender na prática, notícias para acompanhar as principais tendências do mercado e o Alura Labs, com análises e reflexões de especialistas sobre tecnologia, IA e carreira.

    Conteúdos gratuitos

    • Artigos
    • Notícias
    • Alura Labs
  • Para Empresas
Ver planos
Links principais
  • Planos e Promoções
  • Links complementares do menu mobile
  • Talent lab
  • Inteligência Artificial
  • Pós Graduações
  • Para Empresas
  • Sobre a Alura
  • Grupo Alun
  • Entrar
    • Home
    • Carreiras
    • Skills & Go
    • Talent Lab
    • Inteligência Artificial
    • Pós Graduações
    • Artigos
    • Sobre a Alura
    • Grupo Alun
    LoginContato
    • LinkedIn
    • Instagram
    • YouTube
    1. Página inicial
    2. Front-end
    3. Como publicar uma biblioteca de hooks React no npm com Turborepo

    Como publicar uma biblioteca de hooks React no npm com Turborepo

    18 min18 minutos de leitura

    18 min18 minutos de leitura

    Publicado: 20/01/2025

    1. Como otimizar o desenvolvimento
    2. Conclusão
    3. Referências

    Se você já trabalhou em projetos grandes, sabe o quanto é comum precisar reutilizar código.

    Por isso, uma alternativa usada por grandes times é usar um monorepo.

    Monorepo é um único repositório para vários projetos ou dependências que faz com que seu time tenha algumas melhorias no desenvolvimento, como: centralização do código, compartilhamento fácil de dependências e pacotes, ferramentas, não precisar ficar pulando entre repositórios e muito mais.

    Quando você tem duas aplicações React diferentes no mesmo repositório, e elas reaproveitam algum tipo de lógica complexa como usar o serviço de geolocalização, adicionar scripts a página, armazenar dados no localStorage ou sessionStorage, como boa prática você abstrai essa lógica e cria hooks customizados. Certo?.

    Mas para não duplicar código nas duas aplicações, o que você faz? É isto que vamos descobrir neste artigo.

    Você vai aprender:

    • Criar um monorepo utilizando Turborepo.
    • Configurar e criar pacotes dentro do monorepo.
    • Consumir esses pacotes em diferentes aplicações.
    • Publicar os pacotes no npm para uso interno ou externo.

    E muito mais. Então vem comigo!

    Como otimizar o desenvolvimento

    Imagina que você trabalha em um e-commerce. Neste serviço, o usuário precisa preencher seu endereço em algum formulário para calcular a taxa de entrega. Este endereço é preenchido uma vez se o usuário tiver cadastro, mas se não terá que preencher o CEP para calcular a taxa de entrega na tela de produto e de finalização da compra.

    Então, como desenvolvedor(a) para facilitar o preenchimento dos dados de endereço do usuário, você cria um hook que a partir do CEP (código de endereçamento postal) ele retorna o endereço completo, preenchendo automaticamente os campos como bairro, município e estado, melhorando a usabilidade da aplicação e experiência do usuário.

    Este hook é tão útil nestes cenários que você resolveu compartilhar ele com sua equipe de desenvolvimento.

    E para não duplicar o código do hook nas diferentes aplicações desenvolvidas dentro do e-commerce, você decidiu criar um monorepo e compartilhar seu hook como um pacote.

    Mas como fazer isso? É o que iremos descobrir.

    Como criar o monorepo

    Bom, para trabalhar com um único repositório vamos precisar de uma ferramenta que seja confiável e facilite o fluxo de trabalho dentro dele.

    Por isso, a escolha óbvia foi o Turborepo. Com o Turborepo, você pode criar, consumir e publicar pacotes, com builds otimizados e uma estrutura modular que favorece a escalabilidade.

    E melhor ainda: você pode transformar o seu código em pacotes independentes que podem ser consumidos não apenas dentro do repositório, mas também por outros projetos.

    Abra um prompt de comando (cmd) na pasta de sua preferência. Lá você vai digitar o seguinte comando:

    npx create-turbo@latest
    

    Ao pressionar a tecla enter vai pedir para você diga qual gerenciador de pacotes irá usar (npm, yarn, pnpm, etc) e também um nome para o monorepo. Escolha um nome de sua preferência, eu vou escolher library-hooks-react.

    Você verá uma mensagem como abaixo:

    ? Where would you like to create your Turborepo? ./library-hooks-react
    ? Which package manager do you want to use? npm
    >>> Creating a new Turborepo with:
    Application packages
     - apps\docs
     - apps\web
    Library packages
     - packages\eslint-config
     - packages\typescript-config
     - packages\ui
    >>> Success! Created your Turborepo at library-hooks-react
    To get started:
    - Change to the directory: cd library-hooks-react
    - Enable Remote Caching (recommended): npx turbo login
       - Learn more: https://turbo.build/repo/remote-cache
    - Run commands with Turborepo:
       - npm run build: Build all apps and packages
       - npm run dev: Develop all apps and packages
       - npm run lint: Lint all apps and packages
    - Run a command twice to hit cache
    

    Agora você pode acessar a pasta que nomeou no passo anterior. E se preferir, pode até abrir ela no seu editor de código. Eu uso o VS Code, então a minha estrutura de arquivos é esta aqui:

    library-hook-react
    ├── apps
    │   ├── docs
    │   └── web
    ├── packages
    │   ├── eslint-config
    │   └── typescript-config
    │   └── ui
    ├── .gitignore
    ├── .npmrc
    ├── package-lock.json
    ├── package.json
    ├── README.md
    └── turbo.json
    

    O turborepo já cria para a gente uma aplicação com Next.js, ela está dentro da pasta apps.

    Na pasta packages são pacotes e dependências que podem ser compartilhados entre as aplicações do mesmo repositório, como componentes de UI, configurações do typescript de lint dos seus projetos.

    Duas coisas que podemos fazer neste momento é renomear a propriedade name no package.json para “root-monorepo”, para ficar claro que é da pasta raiz e diferenciar do nome do pacote que iremos publicar (shhh, spoilers…).

    Além disso, vamos deletar a pasta apps/docs pois não iremos usá-la aqui.

    //library-hooks-react/package.json
    {
      "name": "root-monorepo", //altere o name para root-monorepo
      "private": true,
      "scripts": {
        "build": "turbo build",
        "dev": "turbo dev",
        "lint": "turbo lint",
        "format": "prettier --write \"**/*.{ts,tsx,md}\""
      },
      // outras propriedades
    }
    

    Com isso, a primeira etapa que era configurar o monorepo foi concluída. Agora vamos tratar de criar o hook que queremos compartilhar. Vamos lá!

    Criando a biblioteca de hooks

    Precisamos criar um pacote/workspace com os hooks que queremos compartilhar. Para isso, você precisa criar uma pasta dentro da pasta ./packages com um nome de sua escolha. Eu escolhi “hooks-lib”.

    Pelo terminal:

    // a partir da raiz acesse a pasta packages
    cd packages
    // crie uma pasta com o nome de sua escolha
    mkdir hooks-lib
    // inicialize um novo pacote npm
    npm init -y
    // instale as dependências que iremos precisar para criar o hook
    npm install -D react react-dom @types/react @types/react-dom
    

    Como iremos utilizar o React com Typescript para criar nossa biblioteca de hooks, precisei instalar as dependências do react e os respectivos tipos.

    O resultado é uma pasta chamada hooks-lib contendo um package.json e uma pasta node_modules.

    Agora precisamos adicionar um tsconfig para criarmos o hook. Então, dentro de hooks-lib eu crio um arquivo tsconfig.json com o seguinte conteúdo:

    {
      "extends": "../typescript-config/base.json",
      "include": ["."],
      "exclude": ["dist", "node_modules"],
      "compilerOptions": {
        "lib": ["dom", "dom.iterable", "esnext"]
      }
    }
    

    Lembra que falei que dentro do monorepo conseguimos reutilizar dependências? No código acima temos um exemplo dessa reutilização.

    Como o turborepo já cria para a gente toda uma configuração do typescript que fica dentro da pasta ./packages/typescript-config/base.json, extendemos essa configuração no tsconfig.json do nosso pacote. Legal né?

    Agora você só precisa reinstalar as dependências para garantir que tudo irá funcionar direitinho. No diretório raiz do projeto, rode o comando: npm install. E prontinho.

    Agora precisamos criar o nosso hook. Então dentro de ./packages/hooks-lib eu crio um arquivo index.ts com o seguinte código:

    import { useState } from "react";
    type Address = {
      logradouro: string;
      bairro: string;
      localidade: string;
      uf: string;
    };
    export const useCep = () => {
      const [error, setError] = useState<string | null>(null);
      const fetchAddress = async (cep: string): Promise<Address | null> => {
        setError(null);
        try {
          const formattedCep = cep.replace(/\D/g, "");
          if (formattedCep.length !== 8) {
            throw new Error("CEP inválido");
          }
          const response = await fetch(
            `https://viacep.com.br/ws/${formattedCep}/json/`
          );
          const data = await response.json();
          if (data.erro) {
            throw new Error("CEP não encontrado");
          }
          return {
            logradouro: data.logradouro,
            bairro: data.bairro,
            localidade: data.localidade,
            uf: data.uf,
          };
        } catch (err: any) {
          setError(err.message || "Erro ao buscar o CEP");
          return null;
        }
      };
      return { fetchAddress, error };
    };
    

    Este arquivo é nosso hook useCep, que a partir de um número de CEP retorna o endereço completo, permitindo o autocomplete de campos de um formulário de endereço, por exemplo.

    E agora lá no ./packages/hooks-lib/package.json só precisamos alterar a propriedade main indicando o arquivo que será exportado, no caso o index.ts.

    {
      "name": "hooks-lib",
      "description": "",
      "main": "/index.ts",
      // outras propriedades
    }
    

    Agora nosso próximo passo será consumir este hook nas aplicações dentro do próprio repositório único. Então vamos fazer isso!

    Usando o hook nas aplicações do monorepo

    Como o turborepo já criou uma aplicação Next.js para a gente, só vamos fazer alguns ajustes para conseguir usar o hook useCep na aplicação.

    1. Vamos renomear a pasta apps/web para apps/next
    2. Dentro de ./apps/next/package.json vamos mudar a propriedade name para “next”
        {
          "name": "next",
          "version": "0.1.5",
          "type": "module",
          "private": true,
          // outras propriedades
        }
    

    Agora se formos no arquivo ./apps/next/app/page.tsx e tentarmos usar o hook useCep, vamos tomar um erro.

    Este erro acontece porque não importamos o hook do caminho correto, então precisamos dizer a nossa aplicação que a dependência que ela está procurando está dentro de um pacote, compartilhado do repositório.

    Para isso, vamos lá em ./apps/next/package.json nas dependências, vamos importar nosso pacote:

      "dependencies": {
        "hooks-lib": "workspace:*",
        "next": "^0.1.5",
        "react": "^19.0.0",
        "react-dom": "^19.0.0"
      },
    

    Feito isso, podemos rodar o comando npm install para instalar essa dependência no projeto next. Agora sim já podemos usar nosso hook. Para isso, em ./apps/next/app/page.tsx eu criei o seguinte código:

    //./apps/next/app/page.tsx
    "use client";
    import { useCep } from "hooks-lib";
    import styles from "./page.module.css";
    import { useState } from "react";
    export default function Home(): JSX.IntrinsicAttributes {
      const [formData, setFormData] = useState({
        cep: "",
        logradouro: "",
        bairro: "",
        localidade: "",
        uf: "",
      });
      const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
        const { name, value } = e.target;
        setFormData((prev) => ({ ...prev, [name]: value }));
      };
      const handleCepBlur = async () => {
        if (formData.cep) {
          const address = await fetchAddress(formData.cep);
          if (address) {
            setFormData((prev) => ({
              ...prev,
              logradouro: address.logradouro,
              bairro: address.bairro,
              localidade: address.localidade,
              uf: address.uf,
            }));
          }
        }
      };
      const { fetchAddress, error } = useCep();
      return (
        <div className={styles.page}>
          <input
            name="cep"
            value={formData.cep}
            onChange={handleChange}
            onBlur={handleCepBlur}
            maxLength={9}
          />
          {error && <p className={styles.error}>Erro: {error}</p>}
          <pre>{JSON.stringify(formData)}</pre>
        </div>
      );
    }
    

    Agora você tem duas opções:

    1. Ou você volta a pasta raiz do projeto e digita o comando npm run dev para subir sua aplicação
    2. Você permanece no diretório ./apps/next e digita npm run dev para rodar sua aplicação Next.js

    Ambas as opções vão subir sua aplicação Next, com a diferença de que o primeiro comando roda o turbo dev, que dispara um script em cada área de trabalho com um nome específico. É útil quando você quer executar todas as aplicações de uma vez só.

    A segunda opção só roda a aplicação Next.js.

    Ao subir a aplicação, ela exibe na url http://localhost:3000 um campo de input para digitarmos o CEP, e ao tirar o foco do campo automaticamente um JSON é exibido na página com as informações de endereço do usuário. Legal né?

    Você pode criar uma aplicação React com Vite também dentro de apps para usar o hook que criamos. Para isso, basta instalar as dependências:

    // navegue até o diretório ./apps
    // crie uma aplicação vite com o template react com typescript
    npm create vite vite-react --template react-ts
    // entre na pasta vite-react e instale as dependências
    npm install
    

    Em ./apps/vite-react/package.json precisamos adicionar a dependência do nosso workspace hooks-lib.

    "dependencies": {
        "hooks-lib": "workspace:*"
    }
    

    E agora rodar novamente o comando npm install para instalar essa nova dependência.

    Com isso, agora você pode usar o hook useCep dentro de sua aplicação com Vite também.

    Novamente você pode subir apenas uma aplicação digitando npm run dev do diretório da mesma, ou rodar o npm run dev no diretório raiz e subir ambas as aplicações com next e vite.

    E está prontinha a nossa biblioteca de hooks. Você pode criar mais hooks, dentro de uma pasta chamada hooks em ./packages/hooks-lib e exportar seus hooks do arquivo index.ts normalmente. Também irá funcionar.

    Só tome cuidado na exportação, busque seguir as melhores práticas como adotar o padrão Barrel Export.

    Se você não conhece esse padrão de exportação, leia este artigo do Klaus Kazlauskas acessando este link da plataforma Medium.

    Só que você não pode deixar que um hook tão interessante e usual fique apenas no seu monorepo, não é? Seu hook pode facilitar a vida de muitos desenvolvedores(as) pelo mundo afora, então o que você pode fazer?

    Você pode publicar sua biblioteca de hooks no npm, por exemplo. É isto que iremos fazer agora.

    Publicando no npm

    Antes de tudo, para você publicar algum pacote no npm você precisa ter uma conta. Se você não tiver uma conta, precisa criar uma. É bem rapidinho, só preencher alguns dados e verificar sua conta através do email.

    Outro detalhe super importante aqui é que antes de publicar o pacote você precisa confirmar se o nome que escolheu para o pacote está disponível. Você pode fazer isso digitando no terminal:

    npm view <nome-que-voce-escolheu>
    

    Se o nome estiver disponível, você receberá uma mensagem como essa:

    npm error code E404
    npm error 404 Not Found - GET https://registry.npmjs.org/library-hooks-react - Not found
    npm error 404
    npm error 404  '<nome-que-voce-escolheu>' is not in this registry.
    npm error 404
    …
    

    E aí você pode usar este nome para o seu pacote. Caso contrário, aparecerão informações sobre a biblioteca existente com o nome que você iria publicar.

    Não dá para publicar uma biblioteca com um nome já existente no npm. Então faça o processo anterior para garantir que o nome que você escolheu está disponível.

    Se você escolheu um nome não disponível, pode mudar o nome do seu pacote trocando a propriedade name em ./packages/hooks-lib/package.json para o nome disponível que você encontrar.

    Compilando o Typescript para JavaScript

    Nossa biblioteca funciona nas aplicações Vite e Next porque ambas compilam o código Typescript para Javascript.

    Mas como queremos publicar o pacote de hooks, precisamos compilar o TypeScript para o JavaScript.

    Antes de publicar precisamos fazer algumas etapas:

    1. Agrupar e compilar o código-fonte para esm e commonjs, para quem instalar o nosso package ser capaz de importá-lo;
    2. Configurar um script de desenvolvimento para desenvolvimento local;
    3. Publicar no NPM; 3.1. Realizar o controle de versionamento; 3.2. Realizar o controle de publicação.

    Para compilar nosso código TS para JS vamos utilizar o tsup.

    O tsup é uma ferramenta de empacotamento e compilação de TypeScript que gera bundles em formatos como CJS e ESM, além de criar arquivos de declaração de tipos (.d.ts).

    Ele oferece uma configuração simples e performance rápida, ideal para bibliotecas e projetos que compartilham um único repositório.

    Precisamos ir na pasta ./packages/hooks-lib e digitar no terminal

    npm install -D tsup
    

    Agora, precisamos criar uma pasta src e mover o arquivo index.ts para dentro dela. E como parte de criar um script de desenvolvimento local, vamos no package.json do hooks-lib (./packages/hooks-lib/package.json) e adicionamos este script:

    "build": "tsup src/index.ts --format esm,cjs --dts"
    

    Este script, vai usar tsup para agrupar e compilar nosso código, e também saídas de arquivos para o diretório dist.

    Por causa disso, você deve adicionar dist no .gitignore na raiz do seu projeto para evitar o envio dessa pasta para o github quando fizer o git push.

    Agora vamos ajustar o main no ./packages/hooks-lib/package.json, para quem instalar esses pacotes usar a versão empacotada e compilada do código.

    "main": "./dist/index.js",
    "types": "./dist/index.d.js",
    

    Um detalhe importante aqui, é: Não queremos injetar todo o react e as dependências do pacote quando alguém usar a biblioteca de hooks.

    Quem usar ela já estará usando o react, então podemos adicionar essas dependências nas dependências por pares, assim:

      "peerDependencies": {
        "react": ">=18.2.0",
        "react-dom": ">=18.2.0"
      }
    

    E antes, os apps importavam diretamente os arquivos .ts e refletiam as alterações que fazíamos na biblioteca automaticamente.

    Agora com o tsup, é necessário rodar o build manualmente ao atualizar o código. Esta etapa irá gerar o nosso hook compilado em Javascript, bem como seus tipos.

    Agora atualize o package.json em ./packages/hooks-lib/package.json para corrigir.

    "dev": "npm run build --watch"
    

    E o arquivo package.json completo tem essa cara:

    {
      "name": "library-hooks-react",
      "version": "1.0.0",
      "description": "",
      "main": "./dist/index.js",
      "types": "./dist/index.d.js",
      "scripts": {
        "build": "tsup src/index.ts --format esm,cjs --dts",
        "dev": "npm run build --watch"
      },
      "keywords": [],
      "author": "",
      "license": "ISC",
      "devDependencies": {
        "@types/react": "^19.0.1",
        "@types/react-dom": "^19.0.2",
        "react": "^19.0.0",
        "react-dom": "^19.0.0",
        "tsup": "^8.3.5"
      },
      "peerDependencies": {
        "react": ">=18.2.0",
        "react-dom": ">=18.2.0"
      }
    }
    

    Controlando as versões com changeset

    Já que estamos publicando no npm a nossa lib, é importante manter sempre um controle de versões conforme ela for crescendo e mudanças forem sendo realizadas, como a adição de novos hooks, melhorias de código, etc.

    Para fazer este controle de versão e publicação, vamos usar a biblioteca changesets.

    O Changesets é uma ferramenta que automatiza o versionamento e o changelog de pacotes, gerenciando as versões com base nas mudanças realizadas.

    Então vamos configurar o changesets no nosso projeto. Começando com a instalação. No terminal, do diretório raiz do projeto (./library-hooks-react) digite:

    // instalação
    npm i @changesets/cli
    

    E agora faça a inicialização do changesets

    // setup
    npx changeset init
    

    Você verá uma mensagem como esta:

    Thanks for choosing changesets to help manage your versioning and publishing
    🦋
    🦋  You should be set up to start using changesets now!
    🦋
    🦋  info We have added a `.changeset` folder, and a couple of files to help you out:
    🦋  info - .changeset/README.md contains information about using changesets
    🦋  info - .changeset/config.json is our default config
    

    Ao instalar e iniciar o changeset, você terá um novo diretório ./changeset na raiz do seu projeto. Este diretório contém um config.json e um README.md. Voltaremos nele mais tarde.

    Agora vamos criar nossas versões. Dentro de ./packages/hooks-lib/package.json mude a versão do seu pacote:

    "version": "0.0.1",
    

    E agora na raiz do monorepo vamos usar o changeset:

    npx changeset
    

    Vai aparecer uma sequência de mensagens. A primeira pergunta qual pacote você quer incluir:

    🦋  Which packages would you like to include? ...
    ( ) unchanged packages
      ( ) next
      ( ) vite-react
      ( ) @repo/eslint-config
      (*) library-hooks-react
      ( ) @repo/typescript-config
      ( ) @repo/ui
    

    Você deve selecionar o pacote em questão com a tecla “espaço” e depois pressionar “enter” para prosseguir.

    🦋  Which packages should have a major bump? ...
    (*) all packages
      (*) [email protected]
    

    Selecione o pacote com a versão específica. A sua deve ser também a 0.0.1. Cheque bem isso.

    Faça uma pequena descrição dessa primeira versão na etapa seguinte:

    🦋  Summary »  Primeiro release
    // Você verá esta mensagem após confirmar:
    🦋  
    🦋  === Summary of changesets ===
    🦋  major:  library-hooks-react
    🦋  
    🦋  Note: All dependents of these packages that will be incompatible with the new version will be patch bumped when this changeset is applied.
    

    Na última etapa você só precisa confirmar:

    🦋  Is this your desired changeset? (Y/n) » true
    

    Você pode rodar o comando npx changeset version para preparar sua versão. Note que após este comando a propriedade version em ./packages/hooks-lib/package.json muda para 1.0.0.

    Agora se certifique que dentro de cada workspace, onde tem um arquivo package.json, o valor da propriedade private esteja como true. Isso diz quais pacotes você NÃO QUER publicar.

    No nosso caso, não queremos publicar a aplicação next, a vite nem o monorepo inteiro. Então cheque o package.json desses diretórios.

    Agora lembra lá do diretório ./changeset? Precisamos fazer algumas mudanças no config.json dentro deste diretório. Na propriedade access, vamos alterar de restricted para public.

    // antes
    "access": "restricted",
    // depois
    "access": "public",
    

    E agora finalmente podemos publicar nossa biblioteca no npm. Rode os comandos abaixo na raiz do seu diretório:

    // faça login no npm. Se já estiver logado pule esta etapa
    npm login
    // publique sua biblioteca com o changeset
    npx changeset publish
    

    E se tudo correr bem você deve ser capaz de ler esta mensagem no console:

    info npm info library-hooks-react-turbopack
    //...
    info Publishing "library-hooks-react" at "1.0.0"
    success packages published successfully:
    library-hooks-react1.0.0
    Creating git tag...
    New tag: [email protected]
    

    E dessa forma você já tem sua biblioteca de hooks react publicada também no npm.

    Agora qualquer pessoa desenvolvedora pode instalar e usar o seu pacote de hooks. Bem maneiro né? Você pode acessar o npm e ver lá no seu perfil, na opção packages o novo pacote que você acabou de publicar.

    Banner do Guia Tático Alura sobre carreira em tecnologia, destacando o mapa da carreira tech. A imagem convida a explorar diferentes caminhos profissionais, comparar possibilidades e encontrar a próxima fase da carreira na área de tecnologia, com chamada “Explore o mapa”.

    Conclusão

    Compartilhar código por meio de uma biblioteca de hooks em um monorepo com Turborepo, traz benefícios, como reusabilidade e integração entre diferentes aplicações.

    Isso facilita a manutenção e acelera o desenvolvimento, permitindo que componentes e lógicas sejam reaproveitados.

    E ao publicar no npm esses recursos você colabora com a comunidade React, disponibilizando uma biblioteca que abstrai uma lógica muito usada em diferentes projetos, como o caso do useCep.

    Se você quiser se aprofundar em como trabalhar e desenvolver aplicações que compartilham um único repositório, pode acessar o link da formação Construa um Design System com React, Turborepo e Storybook e se você for do time Angular, pode também fazer a formação Angular: cursos para construir um Design System com Nx, Monorepo e Storybook.

    Referências

    • Publish a Typescript React library to NPM in a monorepo (gratuito, inglês, texto)
    • Do a barrel export (gratuito, inglês, texto)
    • Documentação do Turborepo (gratuito, inglês/português, texto)
    • Changeset repository (gratuito, inglês, texto)
    • Monorepo: como usá-lo para desenvolver e integrar grandes projetos (gratuito, português, texto)
    • React: desenvolvendo design systems modulares com Turborepo (pago, português, curso/vídeo)
    Banner do Guia Tático Alura sobre carreira em tecnologia, destacando o mapa da carreira tech. A imagem convida a explorar diferentes caminhos profissionais, comparar possibilidades e encontrar a próxima fase da carreira na área de tecnologia, com chamada “Explore o mapa”.

    Avalie este artigo

    • Foto de Neilton Seguins

      Autor(a)

      Neilton Seguins

      Bacharel em Ciência e Tecnologia e Pós Graduado em FullStack Development. Atualmente estou como Desenvolvedor de Software na Alura focado no front-end. Também amo ouvir e tocar música, ler livros e mangás e assistir séries.

    Explore por tópico

    • Back-end
    • Dados
    • DevOps
    • Front-end
    • Gestão & Negócios
    • Institucionais
    • Inteligência Artificial
    • Mobile
    • UX & Design

    Leia também

    • 20/05/2024

      Autenticação moderna com OAuth 2.0 e OpenID Connect: dicas para desenvolvedores frontend

      Ler mais
    • 30/01/2021

      Async/await no JavaScript: o que é e como usar

      Ler mais
    • 18/09/2024

      Cuidados com CSRF/XSRF ao utilizar a Push API

      Ler mais
    Ver mais conteúdos

    Inscreva-se em nossa Newsletter

    Fique por dentro de conteúdos, insights e oportunidades do universo tech. Receba novidades e lançamentos direto no seu e-mail.

    Institucional

    • Sobre nós
    • Trabalhe Conosco
    • Para Empresas
    • Para Escolas
    • Política de Privacidade
    • Compromisso de Integridade
    • Termos de Uso
    • Canal de Ética
    • Código de Ética
    • Fale Conosco
    • Documentos Institucionais
    • Status
    Institucional
    • Sobre nós
    • Trabalhe Conosco
    • Para Empresas
    • Para Escolas
    • Política de Privacidade
    • Compromisso de Integridade
    • Termos de Uso
    • Canal de Ética
    • Código de Ética
    • Fale Conosco
    • Documentos Institucionais
    • Status

    A Alura

    • Como Funciona
    • Inteligência Artificial
    • Plataforma
    • Depoimentos
    • Instrutores(as)
    • Dev em <T>
    • Luri, a Inteligência Artificial da Alura
    • IA Conference
    • Cursos Imersivos
    • Perguntas Frequentes
    A Alura
    • Como Funciona
    • Inteligência Artificial
    • Plataforma
    • Depoimentos
    • Instrutores(as)
    • Dev em <T>
    • Luri, a Inteligência Artificial da Alura
    • IA Conference
    • Cursos Imersivos
    • Perguntas Frequentes

    Conteúdos

    • Alura Cases
    • Imersão Engenharia de Software: Dev na Era da IA
    • Artigos
    • Podcasts
    • Artigos de educação corporativa
    Conteúdos
    • Alura Cases
    • Imersão Engenharia de Software: Dev na Era da IA
    • Artigos
    • Podcasts
    • Artigos de educação corporativa
    Uma Empresa do GrupoLogo Grupo Alun

    Outras empresas do Grupo Alun

    • FIAP
    • STARTSE
    • PM3
    • LUMINA

    Ao submeter seu e-mail, você concorda com a política de privacidade da Alura.

    Redes Sociais & Apps

    instagram
    youtube
    tiktok
    x
    appStore
    googlePlay
    Uma Empresa do GrupoLogo Grupo Alun

    Outras empresas do Grupo Alun

    • FIAP
    • STARTSE
    • PM3
    • LUMINA

    Ao submeter seu e-mail, você concorda com a política de privacidade da Alura.

    Redes Sociais & Apps

    instagram
    youtube
    tiktok
    x
    appStore
    googlePlay
    Alura