Uma nova visão sobre modularidade e componentes javascript
Tags: webcomponents, javascript, html, css
Published: 2023-03-14 13:01:12

Os componentes são uma das principais ferramentas utilizadas no desenvolvimento de interfaces de usuário modernas. Eles permitem que os desenvolvedores criem aplicativos modulares e escaláveis, com funcionalidades complexas que são divididas em partes menores e mais gerenciáveis.

Os componentes são amplamente utilizados em várias tecnologias e frameworks, como React, Vue e Angular, permitindo que os desenvolvedores criem interfaces de usuário com facilidade e flexibilidade, isolando o comportamento e a aparência de diferentes partes do aplicativo.

Neste post, vou apresentar minha abordagem de componentização, que se concentra em criar componentes independentes, reutilizáveis e escaláveis. Esses componentes foram projetados para serem usados em diferentes projetos e contextos, ajudando a criar aplicativos consistentes e de alta qualidade. Vamos explorar como essa abordagem pode ajudar a melhorar o processo de desenvolvimento e a qualidade do código, permitindo que os desenvolvedores criem aplicativos mais eficientes e robustos.

## O Modelo

O modelo descrito é baseado no conceito de Componentes, que são conjuntos de Unidades Construtivas que trabalham juntas para realizar uma tarefa específica. As Unidades Construtivas são projetadas para desempenhar funções específicas dentro do Componente e podem ser facilmente combinadas e reutilizadas em diferentes contextos.

O objetivo desse modelo é promover a modularidade e a reutilização de código, o que pode tornar o desenvolvimento de novos Componentes mais rápido e eficiente. Ao criar Componentes compostos por Unidades Construtivas, é possível garantir que cada parte do Componente tenha uma responsabilidade clara e limitada, facilitando a manutenção e o desenvolvimento futuro.

Além disso, a modularidade permite a criação de interfaces de usuário mais complexas e sofisticadas, combinando diferentes Componentes. Essa abordagem pode melhorar a experiência do usuário e reduzir o tempo de desenvolvimento de novas funcionalidades.

## A Estrutura

A abordagem de componentização consiste em três unidades construtivas principais: View, Root Aggregate e Advice.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hwjg0cylkg2n1a85bg82.png)

### View

A unidade View é responsável por apresentar a interface do usuário e receber a entrada de dados do usuário. Ela recebe os dados do Root Aggregate e exibe esses dados para o usuário, usando uma combinação de JSX e CSS in JS. A unidade View também envia as interações do usuário de volta para o Root Aggregate, para que as ações apropriadas possam ser tomadas.

A View é construída sem depender de nenhum framework ou biblioteca específica, o que garante que o Component seja facilmente portável para diferentes contextos e tecnologias. Essa abordagem de construção de View com JSX e CSS in JS também oferece a vantagem de ser altamente flexível e personalizável, permitindo que os desenvolvedores criem interfaces de usuário altamente dinâmicas e responsivas.

### Root Aggregate

O Root Aggregate é a unidade principal do Component, que controla o fluxo de dados e a lógica de negócios. Ele é responsável por gerenciar o estado do Component, processar as interações do usuário e gerar as atualizações de dados apropriadas para a camada View.

O Root Aggregate é dividido em duas partes principais: os métodos (Action) e os atributos (State). Os métodos são responsáveis por processar as interações do usuário, como cliques de botão ou entrada de texto, e atualizar o estado correspondente. Essas ações podem ser simples ou complexas, dependendo da lógica de negócios do Component.

Os atributos, por sua vez, representam o estado atual do Component e são atualizados pelos métodos do Root Aggregate. Eles armazenam informações relevantes para a interface do usuário, como texto digitado em um campo de formulário, seleções feitas em uma lista de opções, entre outros. É importante notar que o estado deve ser imutável, ou seja, não deve ser modificado diretamente, mas sim atualizado por meio de ações que criam um novo estado com as atualizações necessárias.

Ao separar claramente a lógica de negócios do estado e da interface do usuário, o Root Aggregate torna o Component mais fácil de entender, testar e modificar, contribuindo para a sua reutilização em diferentes contextos e projetos.

### Advice

Para complementar, a unidade Advice pode ser útil para isolar e modularizar as funcionalidades adicionais do Component que não fazem parte da responsabilidade central do Root Aggregate e da View. Isso permite que o código seja organizado de forma mais clara e coesa, facilitando a manutenção e o desenvolvimento futuro.

Além disso, a unidade Advice também pode ser usada para implementar lógicas de negócios mais complexas, como validação de entrada de dados, cálculos e transformações de dados. Isso ajuda a manter o Root Aggregate e a View mais simples e focados em suas responsabilidades principais.

É importante destacar que o uso da unidade Advice deve ser cuidadoso, pois a adição de funcionalidades adicionais pode tornar o Component mais complexo e difícil de entender. Portanto, é importante avaliar cuidadosamente a necessidade e o impacto de adicionar ou remover a unidade Advice em cada projeto.

## Exemplo

O exemplo de código que vamos analisar é escrito em JavaScript e é do [kuba](https://github.com/deMGoncalves/kuba), um projeto open source pessoal que oferece uma série de ferramentas para o desenvolvimento web. O código define uma classe chamada "Auth", que representa um componente para autenticação de usuário. Esse componente possui métodos e propriedades que são usados para gerenciar o estado do usuário durante o processo de login.

```javascript
import * as filter from '@kuba/filter'
import { paint, repaint } from '@kuba/h'
import { urlFor } from '@kuba/router'
import cookie from './cookie'
import component from './component'
import user from './user'

@paint(component)
class Auth {
  #email
  #password
  #state

  get email () {
    return (this.#email ??= '')
  }

  get password () {
    return (this.#password ??= '')
  }

  get state () {
    return (this.#state ??= '')
  }

  @filter.prevent
  @filter.formData
  @user.authenticate
  logIn (data) {
    this.#email = data.email
    this.#password = data.password
    return this
  }

  @cookie.setUser
  [user.onAuthenticated] (_user) {
    location.assign(urlFor('home'))
    return this
  }

  @repaint
  [user.onInvalid] () {
    this.#password = ''
    this.#state = 'invalid'
    return this
  }
}

export default Auth
```

A classe Auth é decorada com o método @paint, que é fornecido pelo pacote `@kuba/h`. Esse adivice indica que a classe é um componente e que deve ser renderizado. O pacote `@kuba/filter` fornece os adivices `@filter.prevent` e `@filter.formData`, que são usados para prevenir a submissão do formulário e converter os dados do formulário em um objeto FormData, respectivamente. O pacote `@kuba/router` é usado para gerar a URL da página inicial após a autenticação bem-sucedida.

A classe Auth também faz uso de alguns módulos personalizados, como `cookie` e `user`. O módulo `cookie` fornece o método `setUser`, que é decorado com o adivice correspondente, e que é usado para armazenar o token de autenticação do usuário em um cookie. O módulo `user` fornece os métodos `authenticate`, `onAuthenticated` e `onInvalid`. O método `authenticate` é decorado com o adivice `@user.authenticate` e é usado para enviar as credenciais do usuário para o servidor e verificar se são válidas.

Se a autenticação for bem-sucedida, o método `onAuthenticated` é chamado e a página é redirecionada para a página inicial. Caso contrário, o método `onInvalid` é chamado e a interface do usuário é atualizada para exibir uma mensagem de erro.

O exemplo apresenta um componente de autenticação simples, mas eficiente, que utiliza os pacotes do [kuba](https://github.com/deMGoncalves/kuba) e outros módulos personalizados para fornecer uma experiência de login segura e confiável.

## Resumo

A estrutura de Component descrita acima é projetada para garantir a modularidade, reutilização de código e facilidade de manutenção. Ao separar claramente as diferentes unidades do Component, é possível garantir que cada parte do Component tenha uma responsabilidade clara e limitada, o que torna o desenvolvimento e a manutenção do Component mais fáceis e eficientes.

Gostou do que viu neste post? Então, conheça o Kuba - um projeto código aberto para desenvolvimento front-end. Com o Kuba, você pode criar aplicativos modulares, reutilizáveis e escaláveis com facilidade. Ele possui pacotes para gerenciamento de estado, roteamento, validação de formulários e muito mais. Além disso, o Kuba é altamente personalizável e oferece uma experiência de desenvolvimento mais ágil. Saiba mais em [link para o Github do Kuba](https://github.com/deMGoncalves/kuba).