Introdução:
Neste artigo aborda a criação de um monorepo para desenvolvimento de projetos, com destaque para a configuração de um workspace e a publicação de um pacote no GitHub Package Registry. Demonstramos também como utilizar esse pacote em um novo projeto externo ao monorepo, fornecendo uma visão abrangente do desenvolvimento modular e colaborativo.
Passo 1: Configurando o Ambiente Inicial
Vamos começar criando o diretório do projeto e inicializando nosso workspace monorepo usando pnpm. Primeiro, crie uma nova pasta para o projeto no local de sua preferência. No exemplo abaixo, criaremos a pasta no diretório home:
mkdir ~/monorepo-project
Essa pasta servirá como o workspace do nosso monorepo. Em seguida, navegue até essa pasta e inicialize um novo projeto Node.js com pnpm:
cd ~/monorepo-project
pnpm init
Após inicializar o projeto, vamos configurar o controle de versão com Git e criar um arquivo .gitignore para ignorar a pasta node_modules:
git init
echo -e "node_modules" > .gitignore
O comando git init inicializa um novo repositório Git no diretório atual, e o comando echo -e "node_modules" > .gitignore cria um arquivo .gitignore com a entrada node_modules, que informa ao Git para ignorar essa pasta, evitando que ela seja incluída nos commits.
Finalmente, vamos configurar o projeto para usar módulos ES6 alterando o tipo de módulo no arquivo package.json:
npm pkg set type="module"
Isso adiciona a seguinte linha ao seu package.json:
{
....
"type": "module"
}
A configuração "type": "module" permite que você use a sintaxe de módulos ES6 (import/export) no seu projeto Node.js.
Passo 2: Estruturando o Projeto
Agora que temos o ambiente inicial configurado, vamos estruturar nosso monorepo criando as pastas necessárias e inicializando um projeto de biblioteca de componentes.
Primeiro, crie duas pastas chamadas packages
e apps
:
mkdir packages apps
A pasta packages será usada para armazenar pacotes reutilizáveis, como nossa biblioteca de componentes, e a pasta apps conterá nossos aplicativos.
Criando o Projeto de Biblioteca de Componentes (UI Kit)
Dentro da pasta packages, vamos criar um projeto de biblioteca de componentes chamado uikit usando o Vite. Para isso, execute os seguintes comandos:
cd packages
pnpm create vite
Durante a criação do projeto com o Vite, você será solicitado a fornecer algumas informações, como o nome do projeto e o template a ser usado. Siga as instruções e escolha as opções apropriadas para o seu projeto de biblioteca de componentes.
Depois de concluir a criação do projeto, sua estrutura de diretórios deverá se parecer com isto:
monorepo-project/
├── packages/
│ └── uikit/
├── apps/
├── package.json
├── .gitignore
├── pnpm-lock.yaml
Passo 3: Criando o Componente de UI
Agora que temos nosso projeto de biblioteca de componentes configurado, vamos criar um simples componente de botão dentro do uikit
.
Primeiro, navegue até a pasta uikit
:
cd uikit
pnpm install
Em seguida, dentro da pasta src do projeto uikit, crie a estrutura de diretórios components/Button:
mkdir -p src/components/Button
Dentro dessa pasta Button, crie um arquivo chamado index.tsx e adicione o seguinte código:
// src/components/Button/index.tsx
export default function ButtonTeste() {
return <div style={{ backgroundColor: 'green', borderRadius: '25px', padding: '10px' }}>Button</div>
}
Este código define um componente React simples chamado ButtonTeste
que renderiza um botão estilizado com uma cor de fundo verde, bordas arredondadas e padding.
Após criar o componente, sua estrutura de diretórios deve se parecer com isto:
cssCopiar código
monorepo-project/
├── packages/
│ └── uikit/
│ └── src/
│ └── components/
│ └── Button/
│ └── index.tsx
├── apps/
├── package.json
├── .gitignore
├── pnpm-lock.yaml
Passo 4: Configurando o Vite para Modo Biblioteca
Para que nosso projeto uikit funcione como uma biblioteca, precisamos ajustar a configuração do Vite. Por padrão, o Vite busca um arquivo index.html como ponto de entrada no modo de aplicação. No entanto, queremos que ele procure main.ts para exportar nossos componentes.
Instalando o Plugin DTS
Primeiro, vamos instalar o plugin DTS, que gera arquivos de declaração (*.d.ts) a partir de arquivos .ts(x) quando o Vite está configurado no modo biblioteca. Execute o seguinte comando dentro da pasta uikit:
pnpm add -D vite-plugin-dts
Configurando o Vite
Se o arquivo vite.config.ts não existir, crie-o na raiz do projeto uikit e adicione o seguinte código:
// vite.config.ts
import { defineConfig } from 'vite';
import { resolve } from 'path';
import dts from 'vite-plugin-dts';
export default defineConfig({
build: {
lib: {
entry: resolve(__dirname, 'src/main.ts'),
formats: ['es', 'cjs'],
fileName: (format) => `main.${format}.js`,
},
rollupOptions: {
external: ['react', 'react-dom'],
output: {
globals: {
react: 'React',
'react-dom': 'ReactDOM',
},
},
},
},
resolve: {
alias: {
src: resolve(__dirname, 'src/'),
},
},
plugins: [
dts({
tsconfigPath: './tsconfig.json', // Caminho para o arquivo tsconfig.json
outDir: 'dist', // Diretório de saída dos arquivos de definição de tipos
}),
],
});
- Se der erro na importação do resolve do pacote ‘path’ basta dar o seguinte comando dentro da pasta uikit: pnpm install --save-dev @types/node
Criando o Arquivo main.ts
Agora, crie o arquivo main.ts dentro da pasta src que será o responsável exportar nossos componentes:
touch src/main.ts
Adicione o seguinte conteúdo ao arquivo main.ts para exportar o componente ButtonTeste:
// src/main.ts
import ButtonTeste from './components/Button';
export { ButtonTeste }
Após essas configurações, sua estrutura de diretórios deve se parecer com isto:
monorepo-project/
├── packages/
│ └── uikit/
│ ├── src/
│ │ ├── components/
│ │ │ └── Button/
│ │ │ └── index.tsx
│ │ └── main.ts
│ └── vite.config.ts
├── apps/
├── package.json
├── .gitignore
├── pnpm-lock.yaml
Passo 5: Configurando o package.json para Suporte a CommonJS e ES Modules
Para garantir que nossa biblioteca uikit suporte tanto CommonJS quanto ES Modules, precisamos atualizar o package.json com as entradas apropriadas para os pontos de entrada do módulo e as declarações de tipos.
Atualizando o package.json
Abra o arquivo package.json do projeto uikit e adicione as seguintes configurações:
{
...
"main": "./dist/main.es.js",
"module": "./dist/main.es.js",
"types": "./dist/main.d.ts",
"exports": {
".": {
"import": "./dist/main.es.js",
"require": "./dist/main.es.js",
"types": "./dist/main.d.ts"
}
},
"files": [
"dist"
],
...
}
Detalhes do arquivo package.json:
-
"main": "./dist/main.cjs.js"
: Especifica o ponto de entrada para consumidores CommonJS. -
"module": "./dist/main.js"
: Especifica o ponto de entrada para consumidores ES Modules. -
"types": "./dist/main.d.ts"
: Especifica o arquivo de declarações de tipos TypeScript. -
"exports"
: Define como os diferentes módulos podem ser importados.-
"import"
: Usado por ES Modules. -
"require"
: Usado por CommonJS. -
"types"
: Define o caminho para os arquivos de declarações de tipos.
-
-
"files"
: Especifica quais arquivos devem ser incluídos no pacote publicado. Neste caso, apenas a pastadist
será incluída. -
"scripts"
: Adiciona um script de build para compilar a biblioteca usando Vite.
Passo 6: Criando o Projeto Web App e Configurando o Workspace
Agora vamos criar o projeto web-app, que fará uso da nossa biblioteca de componentes uikit, dentro do mesmo repositório.
Criando o Projeto Web App
Navegue até a pasta apps dentro da raiz do projeto monorepo-project e crie o projeto web-app usando o Vite:
# dentro de monorepo-project/apps execute:
pnpm create vite
entre dentro da pasta web-app execute pnpm install
para instalar as dependências.
Configurando o Workspace
Após criar o projeto web-app, precisamos configurar um workspace para gerenciar todos os projetos dentro do mesmo repositório.
Volte para a pasta raiz do monorepo-project e crie um arquivo chamado pnpm-workspace.yaml:
cd ..
touch pnpm-workspace.yaml
Dentro desse arquivo, insira o seguinte conteúdo:
packages:
- 'apps/*'
- 'packages/*'
Essa configuração informa ao pnpm para reconhecer os diretórios apps e packages como parte do workspace, permitindo que eles sejam gerenciados em conjunto.
Após realizar essas etapas, sua estrutura de diretórios deve se parecer com isto:
monorepo-project/
├── packages/
│ └── uikit/
│ ├── src/
│ │ ├── components/
│ │ │ └── Button/
│ │ │ └── index.tsx
│ │ └── main.ts
│ ├── tsup.config.ts
│ └── package.json
├── apps/
│ └── web-app/
│ ├── src/
│ ├── package.json
├── package.json
├── pnpm-lock.yaml
├── pnpm-workspace.yaml
├── .gitignore
Com isso, temos o projeto web-app criado e o workspace configurado para gerenciar todos os projetos dentro do mesmo repositório.
Passo 7: Instalando e Configurando o tsup
O tsup é uma ferramenta rápida para transpilar arquivos TypeScript em JavaScript. Ele simplifica o processo de configuração e execução, facilitando a compilação de código TypeScript para uso em projetos JavaScript.
Instalando o tsup
Para instalar o tsup, execute o seguinte comando dentro da pasta uikit:
pnpm add tsup -D
Criando o Arquivo de Configuração tsup.config.ts
Agora, crie o arquivo tsup.config.ts na raiz do projeto uikit e adicione o seguinte código:
// tsup.config.ts
import { defineConfig } from 'tsup';
export default defineConfig({
entry: ['src/main.ts'],
format: ['cjs', 'esm'],
dts: true,
sourcemap: true,
clean: true,
outDir: 'dist',
external: ['react', 'react-dom'],
});
detalhes o tsup.config.ts
-
entry
: Especifica o arquivo de entrada ou uma lista de arquivos de entrada para transpilação. -
format
: Define os formatos de saída desejados, neste caso, CommonJS (cjs
) e ES Module (esm
). -
dts
: Habilita a geração de arquivos de definição de tipos TypeScript. -
sourcemap
: Habilita a geração de sourcemaps para depuração. -
clean
: Limpa o diretório de saída antes de compilar. -
outDir
: Especifica o diretório de saída dos arquivos transpilados. -
external
: Lista de módulos que serão considerados externos e não incluídos no pacote.
Após essas configurações, sua estrutura de diretórios deve se parecer com isto:
cssCopiar código
monorepo-project/
├── packages/
│ └── uikit/
│ ├── src/
│ │ ├── components/
│ │ │ └── Button/
│ │ │ └── index.tsx
│ │ └── main.ts
│ ├── tsup.config.ts
│ └── package.json
├── apps/
├── package.json
├── .gitignore
├── pnpm-lock.yaml
Passo 8: Configurando o Web App para Usar o UI Kit
Agora vamos configurar o projeto web-app para utilizar o uikit que criamos anteriormente.
Adicionando o UI Kit como Dependência
Abra o arquivo package.json do projeto web-app e adicione o uikit como uma dependência:
{
"name": "web-app",
"version": "1.0.0",
"dependencies": {
"uikit": "workspace:*"
}
}
Execute o comando pnpm install na pasta web-app para que as dependências sejam instaladas e o uikit seja reconhecido pelo projeto.
Atualizando o App.tsx
Atualize o arquivo App.tsx do projeto web-app para importar e utilizar o componente ButtonTeste do uikit:
// web-app/src/App.tsx
import { ButtonTeste } from "uikit";
function App() {
return (
<>
<ButtonTeste />
</>
);
}
export default App;
Compilando o UI Kit
Antes de iniciar o servidor de desenvolvimento, certifique-se de compilar o uikit. Navegue até a pasta uikit e execute o comando pnpm build.
Iniciando o Servidor de Desenvolvimento
Por fim, execute o comando pnpm run dev dentro da pasta web-app para iniciar o servidor de desenvolvimento e visualizar o botão na tela.
cd monorepo-project/apps/web-app
pnpm run dev
Isso iniciará o servidor de desenvolvimento e você poderá acessar o projeto web-app em seu navegador para visualizar o botão do UI Kit.
Passo 9: Publicando o UI Kit no GitHub Package Registry
Agora vamos publicar nosso pacote uikit no GitHub Package Registry.
Configurando o Arquivo .npmrc
Crie um arquivo chamado .npmrc na raiz do projeto uikit e adicione o seguinte conteúdo, substituindo seuNomeDeUsuario pelo seu nome de usuário do GitHub e SeuToken pelo seu token de acesso (certifique-se de que seu token tenha permissões para criar pacotes no GitHub):
@seuNomeDeUsuario:registry=https://npm.pkg.github.com/
//npm.pkg.github.com/:_authToken=SeuToken
Criando o Arquivo .npmignore
Também na raiz do projeto uikit, crie um arquivo chamado .npmignore com o seguinte conteúdo:
# Ignore everything
*
# Mas não ignore a pasta dist
!dist
# Você também pode querer incluir o package.json e outros arquivos importantes
!package.json
!README.md
Modificando o package.json
Abra o arquivo package.json do projeto uikit e modifique o nome do pacote e o atributo private. Seu package.json deve ficar semelhante a isso:
{
"name": "@seuNomeDeUsuario/nomeDoPacote",
"private": false,
...
}
Substitua seuNomeDeUsuario pelo seu nome de usuário do GitHub e nomeDoPacote pelor exemplo o meu projeto fica da seguinte forma:
{
"name": "@romulospl/uikit",
"private": false,
...
}
Publicando o Pacote
Agora estamos prontos para publicar nosso pacote. Execute o seguinte comando na raiz do projeto uikit:
npm publish --registry=https://npm.pkg.github.com
Isso irá publicar o pacote uikit no GitHub Package Registry.
Após publicar o pacote uikit no GitHub Package Registry, é importante verificar se a publicação foi realizada com sucesso.
Acessando o GitHub Package Registry
Acesse o seguinte link em seu navegador, substituindo seuNomeDeUsuario
pelo seu nome de usuário do GitHub:
https://github.com/seuNomeDeUsuario?tab=packages
Verificando o Pacote Publicado
Na página dos pacotes do seu perfil do GitHub, você deve ser capaz de ver o pacote uikit listado. Isso confirma que o pacote foi publicado com sucesso no GitHub Package Registry.
Verifique se todas as informações estão corretas e se o pacote está disponível para uso.
Passo 10: Criando o Projeto use-component e Utilizando o UI Kit
Agora vamos criar um novo projeto chamado use-component fora do monorepo-project e utilizá-lo para demonstrar o uso do nosso pacote uikit do GitHub Package Registry.
Criando o Projeto use-component
Na pasta de sua preferência (por exemplo, na sua pasta pessoal), execute o seguinte comando para criar o projeto use-component
usando Vite:
pnpm create vite use-component
Em seguida, entre na pasta do projeto e execute pnpm install para instalar as dependências:
cd use-component
pnpm install
Instalando o Pacote uikit
do GitHub Package Registry
Acesse o GitHub e vá para a página dos seus pacotes, substituindo seuNomeDeUsuario pelo seu nome de usuário do GitHub:
https://github.com/seuNomeDeUsuario?tab=packages
Clique no pacote uikit
para acessar sua página. Lá você encontrará o comando para instalar o pacote.
Copie o comando, substituindo @romulospl/uikit pelo nome do seu pacote e 0.0.0 pela versão desejada.
Em seguida, crie um arquivo chamado .npmrc
na raiz do projeto use-component
e adicione a seguinte linha, substituindo seuNomeDeUsuario pelo seu nome de usuário do GitHub:
@seuNomeDeUsuario:registry = https://npm.pkg.github.com
Depois disso, cole o comando que você copiou anteriormente para instalar o pacote uikit, substituindo as informações necessárias.
pnpm install @seuNomeDeUsuario/uikit@0.0.0
Utilizando o Componente do UI Kit
Agora que o pacote uikit
está instalado, vamos utilizá-lo no arquivo App.tsx
dentro da pasta src do projeto use-component.
Modifique o arquivo App.tsx para importar e utilizar o componente ButtonTeste do pacote uikit:
// use-component/src/App.tsx
import './App.css';
import { ButtonTeste } from '@seuNomeDeUsuario/uikit';
function App() {
return (
<>
<ButtonTeste />
</>
);
}
export default App;
Executando a Aplicação
Agora execute a aplicação com o comando pnpm run dev e você verá o botão do UI Kit em funcionamento na tela.
Se você verificar a pasta node_modules dentro do projeto use-component, verá uma pasta @seuNomeDeUsuario
(por exemplo, @romulospl). Dentro dessa pasta, há uma pasta uikit, contendo apenas a pasta dist do projeto e o arquivo package.json com as configurações de entrada e exportação.
Top comments (3)
Incrível
Excelente tutorial. Muito útil!
Arrasooou !