Como usar TypeScript em uma configuração Monorepo

Uma configuração monorepo permite que você gerencie vários pacotes ou projetos em um único repositório. Com TypeScript, essa configuração é especialmente poderosa para compartilhar tipos, interfaces e até mesmo utilitários entre diferentes pacotes. Este guia mostrará como configurar o TypeScript em um ambiente monorepo.

1. Configurando o Monorepo

Para configurar um monorepo, você pode usar ferramentas como npm workspaces ou yarn workspaces. Essas ferramentas permitem que você gerencie vários pacotes no mesmo repositório e facilitam o compartilhamento de código entre projetos.

1.1 Inicializando um Monorepo

Primeiro, crie uma nova pasta para seu monorepo e inicialize-a com npm ou yarn.

mkdir my-monorepo
cd my-monorepo
npm init -y

Em seguida, configure os espaços de trabalho em seu package.json:

{
  "name": "my-monorepo",
  "version": "1.0.0",
  "private": true,
  "workspaces": [
    "packages/*"
  ]
}

Esta configuração informa ao npm ou ao yarn que todos os pacotes ficarão dentro da pasta packages.

2. Adicionando Pacotes ao Monorepo

Crie dois pacotes no seu monorepo. Para este exemplo, criaremos um pacote shared para código reutilizável e um pacote web-app para um aplicativo frontend.

mkdir -p packages/shared
mkdir -p packages/web-app

Dentro de cada pacote, inicialize um package.json:

cd packages/shared
npm init -y

cd ../web-app
npm init -y

3. Adicionando TypeScript ao Monorepo

Em seguida, configuraremos o TypeScript. Instale o TypeScript e as dependências necessárias na raiz do seu monorepo:

npm install typescript --save-dev

Crie um tsconfig.json de nível raiz para definir a configuração TypeScript para todo o monorepo:

{
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "*": ["packages/*/src"]
    },
    "composite": true,
    "declaration": true,
    "outDir": "dist",
    "rootDir": ".",
    "skipLibCheck": true,
    "module": "ESNext",
    "target": "ES6",
    "moduleResolution": "node"
  },
  "include": ["packages/*"]
}

A chave aqui é a opção paths, que permite que o TypeScript entenda importações de diferentes pacotes no monorepo.

4. Configurando TypeScript em cada pacote

Cada pacote precisa de seu próprio tsconfig.json para funcionar corretamente no monorepo. Aqui está um exemplo de configuração para o pacote shared:

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

E para o pacote web-app:

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

Agora, o TypeScript pode ser usado em cada pacote, e as configurações são compartilhadas da raiz tsconfig.json.

5. Adicionando código TypeScript aos pacotes

Vamos adicionar algum código TypeScript de exemplo a ambos os pacotes. No pacote shared, crie uma pasta src e adicione um arquivo TypeScript:

mkdir -p packages/shared/src
touch packages/shared/src/index.ts

Em index.ts, exporte uma função simples:

export const greet = (name: string): string => {
  return `Hello, ${name}!`;
}

No pacote web-app, crie uma pasta src e um arquivo index.ts:

mkdir -p packages/web-app/src
touch packages/web-app/src/index.ts

Agora, importe a função compartilhada:

import { greet } from 'shared';

console.log(greet('TypeScript Monorepo'));

6. Construindo o Monorepo

Para compilar todo o código TypeScript no monorepo, precisamos usar o compilador TypeScript. Na raiz do monorepo, execute:

npx tsc --build

Este comando compilará todos os pacotes seguindo seus respectivos arquivos tsconfig.json.

Conclusão

Neste guia, abordamos como configurar e usar o TypeScript em um monorepo. Ao organizar seu código em uma estrutura monorepo, você pode facilmente compartilhar código entre vários pacotes, tornando seu processo de desenvolvimento mais eficiente. Com a tipagem forte e referências de projeto do TypeScript, essa configuração é perfeita para aplicativos de grande escala ou bibliotecas compartilhadas.