BemtvJS - Visão geral
Tags: webdev, javascript, opensource, showdev
Published: 2022-11-27 16:46:20

> BemtvJS: 
Reatividade baseada em template,
Brackethtml, 
CSS-In-Template, 
SuperComponent, 
CSS-In-JS, 
Hooks, 
DOM events, 
CompVars, 
Funções de transformação, 
Roteamento automático, 
e Divisão de código.

BemtvJS é uma biblioteca de UI que adota uma abordagem contrária à maioria das bibliotecas e estruturas. Normalmente as ferramentas de UI observam o estado (variáveis ​​e propriedades) e quando ele muda, atualiza o template e aplica o resultado ao DOM, a Bemtv faz o próprio template verificar se o estado mudou e se atualizar.


## Brackethtml

Brackethtml é uma linguagem de marcação incorporada ao Bemtv que permite reduzir a redundância do HTML, suportá-lo e se parecer com ele:

```js
const btn = `button[Click me!]`;
```
Brackethtml também permite a inserção de CSS-In-Template, que  simplesmente é CSS-In-JS inserido diretamente no template:

```js
const btn = `button[color:blue; ~ Click me!]`;
```
## SuperComponent

Criando um componente: 

```js
import { _ } from "bemtv";

_`App`();
```
O valor retornado é chamado de SuperComponent. Internamente, cada vez que o componente é usado, é criada uma instância leve que gerencia essa nova renderização do componente.

Essas instâncias assumem o “controle”, sempre que ocorre uma ação nelas, onde a reação é a execução de um callback passado anteriormente, normalmente em Hooks e eventos do DOM.

### CSS-In-JS

Além do estilo que pode ser aplicado diretamente no template, uma ótima opção é utilizar o método css():

```js
import { _ } from "bemtv";

const { css, template } = _`App`();

css`
  color: blue;
  font-size: 20px;
`;

template`h1[Hello world!]`;
```

### Hooks

Cada instância do componente passa por uma série de etapas, podemos executar funções chamadas hooks em cada uma dessas etapas:

```js
import { _ } from "bemtv";

const { onInit, onMount, onUpdate, onUnmount } = _`App`();

onInit(() => {
  // Chamada(apenas uma vez) quando a instância é inicializada.
});
onMount(() => {
  // Chamada(apenas uma vez) depois que o template do componente foi montado no DOM.
});
onUpdate(() => {
  // Chamada após a atualização do template ser aplicada ao DOM.
});
onUnmount(() => {
  // Chamado(apenas uma vez) depois que o componente é removido/desmontado do template em que estava.
});
```
### Eventos do DOM

Podemos usar eventos DOM diretamente do SuperComponent:

```js
import { _ } from "bemtv";

const { click$, mouseover$ } = _`App`();

click$(() => {}, { capture: true });

mouseover$(() => console.log("Hey!"));
```

## Variáveis de ​​componentes(compVars)

Podemos passar um objeto como argumento para o componente, este objeto é chamado `compVars` e todas as propriedades adicionadas a ele são isoladas a cada renderização do componente, incluindo estruturas de dados como Array, Set, Map e Object.

Conhecendo nossas “variáveis”, a Bemtv consegue fornecer açúcares sintáticos realmente doces. 

Um exemplo é que podemos adicionar o caminho para a propriedade diretamente no template usando o símbolo `$`:

```js 
import { _ } from "bemtv";

const { template, render } = _`Message`({ message: "Hey!" });

template`button[Clicked: $message ]`;

render();
```

Se tivermos uma propriedade com o mesmo nome de um atributo HTML podemos usar o símbolo `@` para informar a Bemtv para tratar a propriedade como chave e valor:

```js 
import { _ } from "bemtv";

const { template, render } = _`Img`({
  src: "avatar.png",
  alt: "My avatar",
});

template`img[ @src @alt ]`;

render();
```

## Funções de transformação

As funções de transformação nos permitem adicionar uma “marca” a uma estrutura de dados e informa ao Bemtv para transformar a estrutura de dados somente quando necessário, isso nos permite focar apenas na estrutura de dados.

```js 
import { tFn } from "bemtv";

const tListJoin = tFn((list) => list.join(" br[] "));
```
O exemplo acima cria uma função de transformação que pode ser usada com listas, e quando a lista é solicitada pelo template ele executa essa função e adiciona o resultado ao template:

```js 
import { _, tFn} from "bemtv";

const tListJoin = tFn((list) => list.join(" br[] "));

const { template } = _`List`({
  list: tListJoin(["user1", "user2", "user3"]),
});

template`div[Users: $list ]
```

Sempre que esta lista for alterada (ex: `$.list.push(item)`), A Bemtv detectará e usará a função de transformação novamente e renderizará a alteração.

## Roteamento automático

A Bemtv utiliza um inovador sistema de criação automática de rotas, isso é possível porque os componentes podem se comportar como rotas/páginas.

O Bemtv é capaz de descobrir automaticamente quando um componente “normal” também deve ser tratado como uma rota:

Um componente normal:

```js
import { _ } from "bemtv";

const { template } = _`AboutUs`();

template`We are cool!`;
```
O componente responsável por rendrizar o App:

```js
import { _ } from "bemtv";

const { template, render } = _`App`();

template`
      Welcome!  br[]br[]

      #[] br[]br[]
      
      #AboutUs[ Link to about us ]`;

render();
```

O segundo componente apresenta a utilização do simbolo `#[]`, é dentro dele que as rotas são renderizadas.

Observe o `#AboutUs[...]`, é aqui que a mágica acontece.
Primeiro, a Bemtv lerá o template de componente `App` e descobrirá que o componente `AboutUs`
também é uma rota (graças ao `#` antes dele), e quando o template for renderizado, tudo dentro do componente `#AboutUs[...]` será envolvido em uma tag `a` com o atributo `href` apontando para a rota.

O endereço da rota será o nome do componente em kebab-case: `/about-us`.

Quando o usuário clicar no link, o componente `AboutUs` será renderizado em `#[]`.

A Bemtv também descobrirá que o componente é uma rota sempre que acessarmos algum método do componente que se destine a rotas, mesmo que não seja chamado(graças a Proxies).


## Dividindo o Código (Code-Splitting)

Para automatizar o processo de importação de componentes, a Bemtv oferece a função `autoImportComponents()` que aceita um objeto onde o nome das propriedades deve ser o nome dos componentes e seus valores devem ser uma função que importa o componente usando [importações dinâmicas](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/import)(dynamic import):

```javascript
import { autoImportComponents } from "bemtv";

autoImportComponents({
  Counter() {
    import("./components/Counter");
  },
});
```

A Bemtv fará a importação do componente assim que componente for utilizado em um template, porém, irá ignorar o componente até o momento em que estiver disponível.


## Fechamento

Essas não são todas as funcionalidades oferecidas pela Bemtv, por exemplo, não estamos falando do inovador sistema de compartilhamento de dados entre os componentes. 
Você pode conferir tudo no repositório do projeto:
 
https://github.com/diogoneves07/bemtvjs.

Bemtv é um projeto recente, você é bem-vindo para fazer parte da construção desta ferramenta.


Qualquer dúvida ou se quiser contribuir com o projeto, pode entrar em contato comigo ou abrir uma PR.

Obrigado por chegar até aqui!