# Web Components – @govbr-ds/webcomponents

[![npm (next)](https://img.shields.io/npm/v/@govbr-ds/webcomponents/next.svg)](https://www.npmjs.com/package/@govbr-ds/webcomponents)

A biblioteca de Web Components do [GovBR-DS](https://gov.br/ds) é desenvolvida utilizando o [Stencil](https://stenciljs.com/), um compilador que cria Web Components (Custom Elements). O Stencil combina os melhores conceitos dos frameworks mais populares em uma ferramenta simples e eficiente. Para mais informações, visite o [site oficial do Stencil](https://stenciljs.com/).

## Demonstração 🚀

Confira nossos componentes em ação:

- [Versão 1.x](https://gov.br/ds/webcomponents/)
- [Versão 2.x (em desenvolvimento)](https://govbr-ds.gitlab.io/bibliotecas/wbc/govbr-ds-wbc/)

## Tecnologias 💻

Este projeto utiliza as seguintes tecnologias:

1. [GovBR-DS](https://gov.br/ds/ 'GovBR-DS')
1. [Stencil](https://stenciljs.com/ 'Stencil')
1. [Font Awesome](https://fontawesome.com/ 'Font Awesome')
1. [Fonte Rawline](https://www.cdnfonts.com/rawline.font/ 'Fonte Rawline')
1. [NX Monorepo](https://nx.dev/ 'NX Monorepo')

## O que são Web Components? ❓

Web Components são um conjunto de tecnologias que permitem criar novos elementos HTML personalizados, reutilizáveis e encapsulados para uso em páginas e aplicativos web. Baseados em padrões da web, são suportados por todos os navegadores modernos.

O diagrama abaixo ilustra os três principais componentes dos Web Components:

- **Elementos HTML personalizados**: Tags HTML definidas com JavaScript, usadas como qualquer outro elemento HTML.
- **Shadow DOM**: Um espaço de nome encapsulado para cada elemento HTML personalizado, garantindo que estilos e scripts não interfiram no restante da página.
- **Templates**: Fragmentos de HTML reutilizáveis em vários elementos.
- **Slots**: Áreas em um elemento HTML personalizado onde templates podem ser inseridos.

### Ciclo de Vida

Para entender melhor o ciclo de vida dos componentes, acesse a página [https://stenciljs.com/docs/component-lifecycle](https://stenciljs.com/docs/component-lifecycle).

## Integração com frameworks 🔗

Integrar Web Components com frameworks pode ser desafiador em algumas situações. Para facilitar, criamos bibliotecas de integração (wrappers), que encapsulam os Web Components em bibliotecas nativas de frameworks, simplificando a integração com funcionalidades como binding.

Para mais detalhes, consulte a [documentação do Stencil sobre integrações](https://stenciljs.com/docs/overview).

Vale lembrar que, em alguns casos, a integração pode não ser possível, dependendo da evolução da especificação de Web Components e do suporte dos frameworks.

## Instalação 📦

Instale o pacote e os estilos base do DS como dependências de produção:

```bash
npm install @govbr-ds/webcomponents @govbr-ds/core
# ou
pnpm add @govbr-ds/webcomponents @govbr-ds/core
# ou
yarn add @govbr-ds/webcomponents @govbr-ds/core
```

> [!NOTE]
> O pacote `@govbr-ds/core` fornece os tokens/estilos base que os componentes utilizam.

## Nota importante: pnpm e tree-shaking

Se ao consumir estes pacotes você notar que o bundler não está removendo código não utilizado (tree‑shaking), pode haver uma incompatibilidade com o layout padrão do pnpm.

Solução rápida (opcional, somente se precisar): crie um arquivo `.npmrc` na raiz do seu projeto com:

```properties
node-linker=hoisted
```

Por que isso ajuda: por padrão, o pnpm organiza as dependências em pastas isoladas com symlinks. Alguns bundlers/otimizadores se baseiam na estrutura de `node_modules` e no campo `sideEffects` para decidir o que pode ser eliminado. O layout hoisted aproxima o formato “achatado” (similar ao npm/yarn), facilitando essa análise e, em muitos casos, restaurando o tree‑shaking.

Observações:

- Use apenas se o tree‑shaking realmente não estiver funcionando.
- Pode aumentar o uso de disco e alterar a resolução de dependências do seu projeto.

## Uso 📚

### Font Awesome e Fonte Rawline

Nossos componentes utilizam a [Fonte Rawline](https://www.cdnfonts.com/rawline.font/ 'Fonte Rawline') e a [Font Awesome](https://fontawesome.com/ 'Font Awesome') padrão do DS. Ambas são essenciais para garantir a estética e funcionalidade dos componentes. Consulte a documentação no site do [GovBR-DS](https://www.gov.br/ds/como-comecar/instalacao 'GovBR-DS') para mais detalhes sobre como importá-las via CDN.

- **[Font Awesome](https://fontawesome.com/ 'Font Awesome')**: Biblioteca amplamente utilizada para adicionar ícones vetoriais e logotipos aos projetos, fácil de integrar e personalizar.
- **[Fonte Rawline](https://www.cdnfonts.com/rawline.font/ 'Fonte Rawline')**: Fonte moderna e elegante, alinhada à identidade visual do Design System do GovBR-DS.

### Passo-a-passo

Os Web Components GOVBR são elementos HTML regulares ou personalizados (Web Components). Em uma página HTML simples, podem ser usados como qualquer outro elemento.

```html
<html>
  <head>
    <script
      type="module"
      src="https://cdn.jsdelivr.net/npm/@govbr-ds/webcomponents/dist/webcomponents/webcomponents.esm.js"
    ></script>
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@govbr-ds/core/dist/core-tokens.min.css" />
  </head>
  <body>
    <br-button>Clique aqui</br-button>
  </body>
</html>
```

### Eventos

Você pode escutar eventos padrão, como clique e mouseover, da mesma forma que faria com elementos HTML normais. Muitos componentes também emitem eventos personalizados, que recomendamos fortemente utilizar. Esses eventos funcionam como os eventos padrão, mas possuem nomes específicos. Consulte a documentação de cada componente para obter detalhes sobre os nomes e dados dos eventos.

```html
<br-button>Label</br-button>

<script>
  const button = document.querySelector('br-button')
  button.addEventListener('click', (event) => {
    console.log('Botão foi clicado', event.detail.valor)
  })
</script>
```

### Exemplos de uso

Disponibilizamos exemplos de como usar este projeto com diferentes tecnologias. Consulte o [nosso grupo no GitLab](https://gitlab.com/govbr-ds/bibliotecas/wc 'GovBR-DS/WC') e procure pelos projetos de 'Quickstart' para mais detalhes.

## Desenvolvimento 👨‍💻

### Estrutura do Projeto

```plaintext
├── 📁 src
    ├── 📁  components
        ├── 📁  br-component
            ├── 📁  sections
                ├── 📄 migrate.md
            ├── 📁  _tests
                ├── 📄 br-component.e2e.ts
                ├── 📄 br-component.spec.tsx
                ├── 📄 readme.md
            ├── 📄 br-component.scss
            ├── 📄 br-component.tsx
    ├── 📁  pages
        ├── 📁  components
            ├── 📁  br-component
              ├── 📄 index.js
              ├── 📄 exemplo.html
        ├── 📁  scripts
        ├── 📄 index.html
    ├── 📁  value-accessors
├── 📄 stencil.config.ts
├── ...
```

- **src**: Contém o código-fonte do projeto.
  - **components**: Diretório com os componentes Web criados com Stencil. Cada componente possui sua própria pasta.
    - **br-component**: Pasta específica para o componente `br-component`.
      - **sections**: Contém arquivos markdown para inclusão no site.
        - **migrate.md**: Explica como migrar o componente da versão anterior para a nova.
      - **\_tests**: Contém os arquivos de teste.
        - **br-component.e2e.ts**: Testes end-to-end (E2E) do componente.
        - **br-component.spec.tsx**: Testes unitários (Unit) do componente.
      - **br-component.tsx**: Arquivo principal do componente, com lógica e estrutura.
      - **br-component.scss**: Arquivo de estilo do componente.
      - **readme.md**: Documentação gerada automaticamente durante o `build`.
  - **pages**: Contém exemplos dos componentes Web criados com Stencil.
    - **components**: Diretório com exemplos dos componentes.
      - **br-component**: Pasta específica para o componente `br-component`.
        - **index.js**: Arquivo para executar ações nos exemplos, como escutar eventos.
        - **exemplo.html**: Arquivo com o código de cada exemplo.
    - **scripts**: Scripts usados no ambiente de desenvolvimento.
  - **value-accessors**: Configurações para 2-way binding em Angular e Vue.
  - **index.html**: Página inicial do servidor de desenvolvimento.
- **stencil.config.ts**: Arquivo principal de configuração do projeto Stencil, onde são definidas opções como saída do build, plugins e scripts globais.

### Scripts Disponíveis

No arquivo `package.json` e `project.json`, você encontrará diversos scripts úteis. Abaixo está uma lista com a descrição de cada um deles:

- **`nx start webcomponents`**: Inicia o site localmente para desenvolvimento.
- **`nx build webcomponents`**: Realiza a compilação do projeto para produção.
- **`nx test:unit webcomponents`**: Executa os testes unitários.
- **`nx lint:tsx webcomponents`**: Realiza a análise estática nos arquivos TypeScript.
- **`nx lint:md webcomponents`**: Realiza a análise estática nos arquivos markdown.
- **`nx lint:styles webcomponents`**: Realiza a análise estática nos arquivos de estilo.

**Gerenciar baseline de tamanho:**

```bash
# Da raiz do monorepo:
pnpm run baseline:update:webcomponents    # Atualizar baseline
pnpm run baseline:compare:webcomponents   # Comparar com baseline atual
```

### Build

Ao gerar o `build` deste projeto Stencil, são automaticamente criados:

- O arquivo `readme.md` dentro da pasta de cada componente.
- Documentações dos componentes na pasta `apps/site/docs/stencil-generated-docs`, que podem ser utilizadas e versionadas pelo site.

```bash
nx build webcomponents
```

### Testes

Nossa estratégia de testes é dividida em duas abordagens principais: testes unitários e testes end-to-end (E2E).

#### Testes Unitários (\*.spec.tsx)

Os testes unitários são ideais para validar a lógica interna dos componentes de forma isolada e eficiente. Utilizamos o método `newSpecPage()` para verificar:

- Estado inicial: comportamento do componente sem propriedades.
- Propriedades: valores válidos, inválidos e alterações em tempo de execução.
- Classes CSS: presença e ausência de classes condicionais.
- Slots: renderização correta do conteúdo.
- Lógica interna: métodos, cálculos e transformações.
- Validações básicas: required, minLength, maxValue, entre outras.

```typescript
import { newSpecPage } from '@stencil/core/testing'
import { BrComponent } from '../component'

it('deve inicializar com o estado padrão', async () => {
  const page = await newSpecPage({
    components: [BrComponent],
    html: /*html*/ `<br-component></br-component>`,
  })
  expect(page.root).toEqualHtml(`<br-component>...</br-component>`)
})
```

### Testes E2E (\*.e2e.ts)

Os testes E2E são realizados em um navegador real utilizando o método `newE2EPage()`. Embora sejam mais lentos, são fundamentais para validar:

- Eventos do componente: clique, blur, change, entre outros.
- Interações do usuário: drag-drop, digitação, atalhos.
- Integrações DOM: forms, validação nativa, atributos aria-\*.
- Estilos visuais: dimensões, cores, transições.
- Shadow DOM: slots, parts, estilos encapsulados.

```typescript
import { newE2EPage } from '@stencil/core/testing'

describe('br-component', () => {
  it('deve renderizar', async () => {
    const page = await newE2EPage()
    await page.setContent(/*html*/ `<br-component></br-component>`)

    const element = await page.find('br-component')

    expect(element).toHaveClass('hydrated')
  })

  it('deve ter shadow root', async () => {
    const page = await newE2EPage()
    await page.setContent(/*html*/ `<br-component-component></br-component-component>`)

    const element = await page.find('br-component')

    expect(element.shadowRoot).not.toBeNull()
  })
})
```

Para mais informações sobre testes no Stencil, consulte a [documentação oficial](https://stenciljs.com/docs/testing-overview).

## Formatos do build 📦

A tarefa `nx build webcomponents` lê as definições de saída em [stencil.config.ts](stencil.config.ts) e gera múltiplos formatos dentro de `dist/webcomponents/dist`. Cada pasta/arquivo atende um cenário específico de consumo da biblioteca. O resumo abaixo ajuda a identificar qual artefato utilizar em cada contexto.

### Visão rápida

| Pasta/arquivo                                                  | Origem no build                                                   | Quando usar                                                                             | Observações                                                                                            |
| -------------------------------------------------------------- | ----------------------------------------------------------------- | --------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------ |
| `cjs/`                                                         | `outputTargets: { type: 'dist' }`                                 | Bundlers ou runtimes que ainda resolvem CommonJS (`require`)                            | Referenciado pelo campo `main` do [package.json](package.json) e inclui `loader.cjs.js`                |
| `esm/`                                                         | `outputTargets: { type: 'dist' }`                                 | Bundlers modernos/ESBuild/Vite/Rollup com suporte a ESM e tree-shaking                  | Referenciado pelo campo `module` do `package.json`                                                     |
| `components/`                                                  | `outputTargets: { type: 'dist-custom-elements' }`                 | Importações diretas de componentes individuais, geração de *wrappers* Angular/React/Vue | Gera `.js` + `.d.ts` por componente                                                                    |
| `collection/`                                                  | `outputTargets: { type: 'dist' }` (manifest Stencil)              | Projetos Stencil que desejam consumir os componentes como dependência                   | Descrito pelos campos `collection` e `collection:main` do `package.json`                               |
| `hydrate/`                                                     | `outputTargets: { type: 'dist-hydrate-script' }`                  | SSR/pré-renderização em Node, integrações como React SSR target                         | Exporta scripts CommonJS/ESM para `@govbr-ds/webcomponents/dist/hydrate`                               |
| `loader/`                                                      | `outputTargets: { type: 'dist' }`                                 | Registro manual dos componentes em apps vanilla, integrações legadas                    | Disponibiliza `defineCustomElements()` em múltiplos formatos                                           |
| `webcomponents/`                                               | `outputTargets: { type: 'dist' }`                                 | Consumo via CDN (ex.: `<script type="module" ...>`)                                     | Contém `webcomponents.esm.js` e os chunks dinâmicos `p-*.entry.js`; os estilos vêm de `@govbr-ds/core` |
| `types/`                                                       | `generateTypeDeclarations: true` (custom elements + d.ts globais) | Autocomplete/TypeScript/IDE hints                                                       | Referenciado por `types` em `package.json`                                                             |
| `custom-elements.json` e `webcomponents.html-custom-data.json` | Derivados do compilador                                           | IntelliSense e validação em IDEs/editores                                               | VS Code utiliza via `html.customData`                                                                  |
| `index.js` / `index.cjs.js`                                    | Entradas principais do pacote                                     | Re-exportam os módulos `esm`/`cjs` e definem side-effects                               | Apontados por `module`/`main`                                                                          |

### `cjs/` – bundles CommonJS

- Contém `index.cjs.js`, `webcomponents.cjs.js` e um arquivo `*.entry.js` por componente, acompanhados dos *source maps* (`.map`).
- É resolvido sempre que o consumidor faz `require('@govbr-ds/webcomponents')` ou quando o bundler privilegia o campo `main` definido em [package.json](package.json).
- Use este formato em toolchains legadas (Node 14/16, Webpack < 4, Jest sem suporte a ESM) ou quando precisar depurar módulos CommonJS. Inclui também `loader.cjs.js`, permitindo registrar os elementos manualmente com `require('@govbr-ds/webcomponents/dist/loader')`.

### `esm/` – bundles ES Modules

- Equivalente modular do `cjs/`, com chunks otimizados (`p-*.entry.js`) e `webcomponents.esm.js`.
- É o alvo do campo `module` do pacote e atende bundlers modernos (Vite, Webpack 5+, Rollup, ESBuild) que fazem tree-shaking. Como os chunks mantêm *imports* explícitos, apenas o necessário é incluído no bundle final.
- Prefira esta saída quando o projeto já executa em módulos nativos ou quando precisa de melhor performance em builds SPA/MPA modernos.

### `components/` – `dist-custom-elements`

- Resultado do `outputTargets: { type: 'dist-custom-elements', customElementsExportBehavior: 'single-export-module' }` definido em [stencil.config.ts](stencil.config.ts).
- Cada componente possui um arquivo isolado (`br-button.js`) e o respectivo `.d.ts`, permitindo importar diretamente `import { BrButton } from '@govbr-ds/webcomponents/dist/components/br-button'` sem puxar o bundle completo.
- Esta pasta também alimenta os geradores Angular/React/Vue configurados no mesmo arquivo (`customElementsDir` aponta para `dist/components`). Use-a para criar *wrappers* customizados ou testar componentes isoladamente em Storybook.

### `collection/` – manifest Stencil

- Inclui `collection-manifest.json`, cópias de assets/páginas e os *proxies* de acesso (`index.js`).
- Necessário apenas para quem desenvolve outra biblioteca Stencil e deseja usar `@govbr-ds/webcomponents` como dependência, preservando metadados como slots, eventos e estilos.
- Os campos `collection` e `collection:main` no [package.json](package.json) apontam para esses arquivos para que o compilador Stencil dos consumidores encontre as definições.

### `hydrate/` – script para SSR/pré-render

- Produzido pelo target `dist-hydrate-script` e exportado como módulo CommonJS/ESM (`index.js`, `index.mjs`).
- Permite renderizar componentes em ambientes sem DOM (Node.js) e hidratar o HTML no cliente. O React SSR output target e a configuração de Vue (`hydrateModule: '@govbr-ds/webcomponents/dist/hydrate'`) dependem desta pasta.
- Utilize quando precisar pré-renderizar páginas (Next.js, Astro, custom SSR) ou ao gerar imagens/relatórios estáticos com os componentes já resolvidos.

### `loader/` – helpers para registro manual

- Disponibiliza `defineCustomElements()` e `applyPolyfills()` em diferentes formatos (`index.js`, `index.cjs.js`, `index.es2017.js`, `cdn.js`).
- Ideal para projetos vanilla ou quando o bundle principal não deve executar automaticamente o `defineCustomElements`. Você importa apenas o loader, registra os componentes no momento oportuno e mantém controle fino sobre o Custom Elements Registry.
- Use `cdn.js` em páginas HTML estáticas (por exemplo, `<script src="https://cdn.jsdelivr.net/npm/@govbr-ds/webcomponents/dist/loader/cdn.js"></script>`) quando precisa apenas do registro.

### `webcomponents/` – pacote pronto para CDN

- É a forma mais simples de consumo: `webcomponents.esm.js` + chunks `p-*.entry.js`, prontos para serem servidos via CDN.
- Recomendada para páginas estáticas, protótipos, Storybook do Design System ou integrações que não passam por bundlers. Lembre-se de importar os estilos de `@govbr-ds/core` (tokens) separadamente.
- Inclui *chunks* nomeados resolvidos dinamicamente pelo loader gerado pelo Stencil, permitindo *lazy loading* automático.

### `types/` – declarações TypeScript

- Resultado da opção `generateTypeDeclarations: true` da saída `dist-custom-elements`.
- Contém `components.d.ts` com todas as interfaces de propriedades/eventos e uma pasta `components/` com os tipos específicos. O campo `types` do `package.json` aponta para `dist/types/index.d.ts`.
- Necessário para projetos TypeScript, IDEs e também para os wrappers Angular/React/Vue, que reexportam esses tipos.

### Metadados auxiliares

- `custom-elements.json`: arquivo padrão da especificação [Custom Elements Manifest](https://github.com/webcomponents/custom-elements-manifest). Importante para ferramentas de documentação e IDEs.
- `webcomponents.html-custom-data.json`: arquivo usado pelo VS Code via `html.customData` para habilitar autocomplete e validação nos editores.
- `index.js` / `index.cjs.js`: reexportam os bundles ESM/CJS e expõem `defineCustomElements()` / `setNonce()` gerados pelo Stencil; raramente precisam ser importados diretamente.
- Documentação Markdown: gerada automaticamente em `apps/site/docs/stencil-generated-docs` via `outputTargets.docs-custom`, mas não é distribuída dentro de `dist/webcomponents`.

### Como escolher o formato correto

1. **Aplicações modernas com bundler**: instale o pacote e deixe seu bundler resolver o campo `module` → carregará `esm/` automaticamente.
2. **SSR ou pré-render**: combine `esm/` no cliente com `hydrate/` no servidor para renderização isomórfica.
3. **Integrações framework-nativas**: use os pacotes `@govbr-ds/angular|react|vue`, gerados a partir de `components/` e com tipos em `types/`.
4. **Páginas estáticas/CDN**: carregue diretamente os arquivos em `webcomponents/` e use o `loader/` se precisar controlar o registro manualmente.
5. **Toolchains legadas**: force o campo `main` e consuma `cjs/` para manter compatibilidade com CommonJS.

Manter estes contextos claros evita duplicidade de código, falta de tree-shaking ou registros repetidos de Custom Elements.

## VS Code IntelliSense

Durante o desenvolvimento de nossos Web Components, utilizamos custom elements. O VS Code, por padrão, não reconhece esses componentes, o que impede sugestões inteligentes no autocomplete. Para resolver isso, geramos um arquivo com as definições dos componentes, disponibilizado junto ao pacote npm.

Para importar no seu VS Code, adicione o seguinte campo, ajustando o caminho para o local onde o `node_modules` está armazenado no seu projeto:

```json
{
  "html.customData": ["./node_modules/@govbr-ds/webcomponents/dist/webcomponents/webcomponents.html-custom-data.json"]
}
```

## Documentações Complementares 📖

Consulte a seção sobre Web Components na nossa [Wiki](https://gov.br/ds/wiki/desenvolvimento/web-components) para obter mais informações sobre este projeto.

Para mais detalhes sobre a especificação de Web Components, recomendamos a consulta ao [MDN](https://developer.mozilla.org/pt-BR/docs/Web/Web_Components 'Web Components | MDN').

## Contribuindo 🤝

Antes de abrir um Merge Request, considere as seguintes orientações:

- Este é um projeto open-source, e contribuições são sempre bem-vindas.
- Para facilitar a aprovação da sua contribuição, utilize um título claro e explicativo no MR e siga os padrões descritos em nossa [wiki](https://gov.br/ds/wiki/ 'Wiki').
- Deseja contribuir? Consulte o nosso guia [como contribuir](https://gov.br/ds/wiki/comunidade/contribuindo-com-o-ds/ 'Como contribuir?').

## Reportar Bugs/Problemas ou Sugestões 🐛

Caso encontre problemas ou tenha sugestões de melhorias, abra uma [issue](https://gitlab.com/govbr-ds/bibliotecas/wbc/govbr-ds-wbc/-/issues/new). Utilize o modelo apropriado e forneça o máximo de detalhes possível.

Nos comprometemos a responder a todas as issues.

## Commits 📝

Este projeto segue um padrão específico para branches e commits. Consulte a documentação em nossa [wiki](https://gov.br/ds/wiki/ 'Wiki') para entender mais sobre esses padrões.

## Precisa de ajuda? 🆘

Por favor, **não** crie issues para dúvidas gerais.

Utilize os canais abaixo para esclarecer suas dúvidas:

- Site do GovBR-DS [http://gov.br/ds](http://gov.br/ds)
- Web Components [https://gov.br/ds/webcomponents](https://gov.br/ds/webcomponents)
- Canal no Discord [https://discord.gg/U5GwPfqhUP](https://discord.gg/U5GwPfqhUP)

## Créditos 🎉

Os Web Components do [GovBR-DS](https://gov.br/ds/ 'GovBR-DS') foram desenvolvidos pelo [SERPRO](https://www.serpro.gov.br/ 'SERPRO | Serviço Federal de Processamento de Dados') em parceria com a comunidade.

## Nota sobre pnpm e tree-shaking

Em alguns cenários, para que o tree‑shaking funcione corretamente (especialmente em bundlers que dependem da estrutura de `node_modules` e da resolução de `sideEffects`), pode ser necessário configurar o pnpm para usar o layout de dependências "hoisted".

Crie um arquivo `.npmrc` na raiz do seu projeto (caso ainda não exista) com:

```properties
node-linker=hoisted
```

Por quê: o layout padrão do pnpm usa pastas isoladas com symlinks, o que pode confundir determinadas ferramentas de build/otimização ao analisar limites de módulos e `sideEffects`. O `node-linker=hoisted` aproxima o layout do de npm/yarn (flat/hoisted), facilitando a análise estática e, consequentemente, o tree‑shaking. Use essa opção apenas se perceber problemas de eliminação de código morto; ela pode aumentar o uso de disco e alterar a resolução de dependências.
