Monorepositório com TypeScript: organização de código na prática

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course

Monorepositório com TypeScript: organização de código na prática

\n\n

No desenvolvimento web moderno, especialmente ao trabalhar com TypeScript, os desenvolvedores frequentemente enfrentam um dilema: armazenar todo o código em um único repositório (monorepositório) ou dividi-lo em vários repositórios pequenos (polirepositório). Para projetos de médio e grande porte, onde a reutilização de código e uma configuração unificada são importantes, o monorepositório se torna o padrão de fato. Neste artigo, vamos analisar como organizar corretamente um monorepositório em TypeScript, desde a estrutura básica até técnicas avançadas.

\n\n

O que é um monorepositório e por que ele é necessário?

\n\n

Monorepositório é uma abordagem onde o código de vários projetos (pacotes, bibliotecas, aplicações) é armazenado em um único repositório. No contexto do TypeScript, isso é especialmente conveniente, pois permite:

\n\n
    \n
  • Reutilizar tipos e interfaces entre diferentes partes do sistema sem publicar no npm.
  • \n
  • Simplificar a refatoração: uma alteração em um pacote é automaticamente validada em todos os dependentes.
  • \n
  • Ter uma configuração unificada para linter, formatador e bundler.
  • \n
  • Simplificar o CI/CD: um repositório — um pipeline.
  • \n
\n\n

Entre as ferramentas populares para trabalhar com monorepositórios em TypeScript, destacam-se Nx, Turborepo e npm/yarn/pnpm workspaces. Abordaremos o uso de pnpm workspaces e TypeScript Project References, pois é um conjunto mínimo e flexível.

\n\n

Estrutura do monorepositório: configuração básica

\n\n

Vamos criar uma estrutura típica de monorepositório para um projeto TypeScript. Suponha que temos três pacotes: core (tipos e utilitários comuns), server (backend) e web (frontend).

\n\n

1. Configuração raiz

\n\n

Começaremos pela raiz do projeto. Crie o arquivo package.json com workspace:

\n\n
{\n  "name": "my-monorepo",\n  "private": true,\n  "workspaces": [\n    "packages/*"\n  ],\n  "scripts": {\n    "build": "tsc -b",\n    "clean": "tsc -b --clean",\n    "lint": "eslint packages/*/src"\n  }\n}\n
\n\n

Em seguida, configure o tsconfig.json raiz. Use Project References — um recurso chave do TypeScript para monorepositórios:

\n\n
{\n  "compilerOptions": {\n    "target": "ES2020",\n    "module": "commonjs",\n    "strict": true,\n    "composite": true,\n    "declaration": true,\n    "declarationMap": true,\n    "sourceMap": true,\n    "outDir": "./dist",\n    "rootDir": ".",\n    "skipLibCheck": true\n  },\n  "references": [\n    { "path": "./packages/core" },\n    { "path": "./packages/server" },\n    { "path": "./packages/web" }\n  ]\n}\n
\n\n

Importante: a opção composite: true é obrigatória para pacotes referenciados por outros pacotes. Ela ativa a compilação incremental e a geração de arquivos .d.ts.

\n\n

2. Configuração do pacote core

\n\n

Vá para packages/core. Crie o package.json:

\n\n
{\n  "name": "@my/core",\n  "version": "1.0.0",\n  "main": "dist/index.js",\n  "types": "dist/index.d.ts",\n  "scripts": {\n    "build": "tsc -b"\n  }\n}\n
\n\n

E o tsconfig.json para este pacote:

\n\n
{\n  "extends": "../../tsconfig.json",\n  "compilerOptions": {\n    "outDir": "./dist",\n    "rootDir": "./src"\n  },\n  "include": ["src"]\n}\n
\n\n

Crie um módulo simples src/index.ts:

\n\n
export interface User {\n  id: string;\n  name: string;\n  email: string;\n}\n\nexport function greet(user: User): string {\n  return `Hello, ${user.name}!`;\n}\n
\n\n

Agora o pacote

Blogs

Book Recommendations