# Gerenciamento de Dependências

Este documento define as práticas recomendadas para gerenciar dependências em projetos JavaScript/TypeScript em todo o ecossistema Decentraland. Aplica-se a front-end, back-end, SDKs, bibliotecas compartilhadas e qualquer pacote baseado em npm/yarn/pnpm.

> **Resumo**:
>
> * **Estratégia de versão** → Usar **versões exatas/fixas** para `dependencies` (segurança) e `devDependencies` (ambiente de desenvolvimento consistente). Usar **intervalos de versão** apenas para `peerDependencies` (flexibilidade).
> * **Exceção** → Pacotes Decentraland (`@dcl/*`, `decentraland-*`) podem usar intervalos de versão (`^`) pois são pacotes internos confiáveis.
> * **Bibliotecas/pacotes compartilhados** → Usar `peerDependencies` com intervalos de versão (^) para bibliotecas compartilhadas (React, @dcl/schemas, etc.). Usar `dependencies` com versões exatas apenas para utilitários seguros para duplicar.
> * **Apps/serviços finais** → Usar `dependencies` com versões exatas para pacotes em tempo de execução (React, ethers, etc.).

## 1. Justificativa

Muitas bibliotecas dependem de singletons globais, React Context, identidade de classe, caches compartilhados, enums de schema ou pools de BD compartilhados. Instalar múltiplas versões da mesma biblioteca pode causar:

* Context não compartilhado entre cópias
* Caches ou pools duplicados
* Falhas em verificações instanceof
* Incompatibilidades de enum/símbolo
* Aumento no tamanho do bundle
* Bugs em tempo de execução difíceis de diagnosticar

O gerenciamento correto de dependências previne esses problemas.

### Não-objetivos

Este padrão não **não** tenta:

* Impor um único gerenciador de pacotes (npm, yarn, pnpm são todos suportados)
* Garantir uma única cópia física em `node_modules` (o foco é na deduplicação em tempo de execução/bundle)

## 2. Definições

| Campo                  | Propósito                                                                     | Responsabilidade do consumidor                                  | Aplica-se a            |
| ---------------------- | ----------------------------------------------------------------------------- | --------------------------------------------------------------- | ---------------------- |
| `dependencies`         | Pacotes usados internamente pelo módulo                                       | Nenhum - o consumidor não é esperado para fornecê-los           | Apps e bibliotecas     |
| `peerDependencies`     | Pacotes que devem resolver para uma única versão efetiva em tempo de execução | Deve instalá-los (ou usar peerDependenciesMeta para opcionais)  | **Apenas bibliotecas** |
| `peerDependenciesMeta` | Metadados para peerDependencies, usado para marcar peers como opcionais       | Nenhum - afeta apenas o comportamento do gerenciador de pacotes | **Apenas bibliotecas** |
| `devDependencies`      | Ferramentas usadas somente durante o desenvolvimento                          | Nenhum                                                          | Apps e bibliotecas     |

### Sobre peerDependenciesMeta

`peerDependenciesMeta` é um campo que fornece metadados sobre suas `peerDependencies`. O caso de uso mais comum é marcar peers como **opcionais**:

* **Peers obrigatórios** (padrão): O gerenciador de pacotes avisará se não estiverem instalados
* **Peers opcionais**: O gerenciador de pacotes não avisará se estiverem ausentes; seu pacote deve tratar a ausência de forma graciosa

Isto é útil para pacotes que podem funcionar com ou sem certas dependências (por exemplo, um utilitário que funciona com ou sem React, ou uma biblioteca que suporta múltiplos provedores Web3).

### Apps vs Bibliotecas

**Bibliotecas / Pacotes Compartilhados:**

* Use `peerDependencies` para pacotes que devem resolver para uma única versão efetiva em tempo de execução (React, ethers, @dcl/schemas)
* O consumidor (app) fornece essas dependências
* Previne instalações duplicadas e conflitos de singleton

**Apps / Serviços Finais:**

* Frequentemente usam `dependencies` para pacotes em tempo de execução (React, ethers, etc.)
* Eles são o consumidor final, então duplicação não é uma preocupação
* `peerDependencies` ainda válido se o app puder ser consumido como uma dependência

## 3. Quando Usar Cada Campo

> **Referência rápida**: Ver [Seção 4](#4-examples) para pacotes comuns e seu posicionamento recomendado.

### Usar peerDependencies para (Apenas Bibliotecas):

**Em bibliotecas/pacotes compartilhados**, usar `peerDependencies` para pacotes que devem resolver para uma única versão efetiva em tempo de execução:

* React, Redux, wagmi, ethers, viem
* @dcl/schemas e bibliotecas semelhantes de cruzamento de ecossistema
* decentraland/connect
* Drivers de BD ao compartilhar pools
* Qualquer biblioteca que dependa de singletons ou context

✅ Correto (Biblioteca):

```json
{
  "peerDependencies": {
    "react": "^18.0.0",
    "@dcl/schemas": "^20.0.0"
  }
}
```

❌ Incorreto (Biblioteca usando dependencies para libs compartilhadas):

```json
{
  "dependencies": {
    "react": "^18.0.0"
  }
}
```

### Usar dependencies para:

* Utilitários seguros para duplicar (lodash-es, date-fns)
* **Em apps**: Pacotes em tempo de execução como React, ethers (quando o app é o consumidor final)

> **Importante**: Sempre usar **versões exatas/fixas** em `dependencies` para segurança.

✅ Correto (Biblioteca):

```json
{
  "dependencies": {
    "lodash-es": "4.17.21",
    "date-fns": "3.6.0"
  }
}
```

✅ Correto (App):

```json
{
  "dependencies": {
    "react": "18.3.1",
    "ethers": "6.13.0",
    "lodash-es": "4.17.21"
  }
}
```

### peerDependencies opcionais (peerDependenciesMeta)

Para pacotes reutilizáveis que funcionam com ou sem certas dependências, usar `peerDependenciesMeta` para marcar peers como opcionais:

✅ Correto:

```json
{
  "peerDependencies": {
    "react": "^18.0.0",
    "ethers": "^6.0.0"
  },
  "peerDependenciesMeta": {
    "ethers": {
      "optional": true
    }
  }
}
```

**O que isso significa:**

* `react` estiver **obrigatório**: O consumidor deve instalá-lo ou o gerenciador de pacotes avisará
* `ethers` estiver **opcionais**: O consumidor não precisa instalá-lo; seu pacote deve verificar sua presença antes de usá-lo

**Casos de uso:**

* Pacotes que funcionam tanto em ambientes React quanto não-React
* Bibliotecas que suportam múltiplos provedores Web3 (ethers, viem, etc.)
* Utilitários que aumentam outras bibliotecas mas não são obrigatórios

### Usar devDependencies para:

* Ferramentas (TypeScript, ESLint, testadores, bundlers)

> **Importante**: Sempre usar **versões exatas/fixas** em `devDependencies` para garantir um ambiente de desenvolvimento consistente na equipe.

✅ Correto:

```json
{
  "devDependencies": {
    "typescript": "5.4.5",
    "eslint": "8.57.0",
    "vitest": "1.6.0"
  }
}
```

## 4. Exemplos

### Pacotes que DEVEM ser peerDependencies (contexto compartilhado / singletons)

* `react`, `react-dom`, `react-redux`, `react-router-dom`
* `redux`, `@reduxjs/toolkit`
* `ethers`, `viem`, `wagmi`
* `@dcl/schemas`, `@dcl/ui-env`, `@dcl/crypto`
* `decentraland-dapps`, `decentraland-ui`, `decentraland-ui2`, `decentraland-connect`
* `pg`, `pg-pool`

### Pacotes que DEVERIAM ser dependencies (seguros para duplicar)

* `lodash-es`, `date-fns`
* `uuid`, `nanoid`
* `zod`, `ajv`
* `ms`, `mitt`, `fp-future`

## 5. Padrões Relacionados

* [Padrões de Teste](https://docs.decentraland.org/contributor/contributor-pt/guias-para-contribuidores/testing-standards)
* [Padrões de UI](https://github.com/decentraland/docs/blob/main/contributor/contributor-guides/ui-standards/README.md)
* [Padrões de Web UI](https://github.com/decentraland/docs/blob/main/contributor/contributor-guides/web-ui-standards/README.md)
* [Arquitetura WKC](https://github.com/decentraland/docs/blob/main/contributor/contributor-guides/well-known-components/README.md)
* [Diretrizes de Documentação de API](https://docs.decentraland.org/contributor/contributor-pt/guias-para-contribuidores/api-documentation)
