
Biblioteca Moon.js
Moon.js é uma biblioteca JavaScript minimalista para o desenvolvimento de interfaces rápidas e funcionais. Tem um tamanho relativamente pequeno, o que torna possível criar aplicativos bastante compactos em sua base. A biblioteca tem um desempenho muito alto.
Moon.js usa uma abordagem baseada em componentes para design de interface. Os modelos são usados para criar componentes. Esta biblioteca é bastante semelhante ao Vue.js.
Pontos fortes de Moon.js
- Moon.js é compacto em tamanho (reduzido e compactado tem cerca de 2 KB). Isso é menor do que o tamanho de outras bibliotecas e estruturas como React e Angular.
- Esta biblioteca se distingue pela alta velocidade de renderização de interfaces.
- Moon.js é uma biblioteca baseada em técnicas de desenvolvimento funcional. Ao trabalhar com ele, é utilizada uma abordagem de design de interface, baseada nos chamados "drivers".
Começo do trabalho
A biblioteca Moon.js pode ser incluída em um projeto de duas maneiras. A primeira é instalá-lo a partir do NPM. A segunda é conectá-lo diretamente à página em que está planejado para ser usado.
Se decidir usar a versão NPM da biblioteca, primeiro você precisa instalar o pacote
moon-cli
, a ferramenta de linha de comando:
$ npm i moon-cli -g
Neste exemplo, esta ferramenta é instalada globalmente, você pode chamá-la de qualquer diretório.
Para criar um projeto baseado em Moon.js, você pode executar o seguinte comando:
$ moon create moon-prj
Este comando cria um novo projeto em uma pasta
moon-prj
. Após a finalização da criação do projeto, você terá à sua disposição a base do futuro aplicativo.
A segunda opção para usar Moon.js envolve conectá-lo à página na qual você planeja usá-lo. A biblioteca possui um módulo
moon-browser
que permite usar seus recursos diretamente na página à qual está conectada.
Portanto, para conectar a biblioteca à página, precisamos incluir as duas tags a seguir na página:
<script src="https://unpkg.com/moon"></script>
<script src="https://unpkg.com/moon-browser"></script>
Como você pode ver, os scripts correspondentes são carregados do CDN descompactado. A primeira tag importa a biblioteca principal. A segunda é a biblioteca
moon-browser
. Ela é responsável por compilar os modelos Moon.js, por fazê-los parecer adequados para exibição pelo navegador.
Agora, para usar a sintaxe Moon.js na página, você precisará incluí-los na tag
<script>
, não esquecendo de definir seu atributo type
como text/moon
.
<!-- -->
<script src="./main-script.js" type="text/moon"></script>
<!-- , -->
<script type="text/moon">
...
</script>
Conectando o aplicativo Moon.js à página
Moon.js, como outras bibliotecas e estruturas usadas para criar aplicativos de página única, se conecta a um elemento de página específico. Normalmente, um elemento desempenha a função de um contêiner para um aplicativo Moon.js
<div>
:
<div id="root"></div>
Um elemento semelhante, que é o elemento raiz do aplicativo Moon.js, é colocado no código do arquivo
index.html
que é o ponto de entrada para o projeto.
Um driver é usado para conectar um aplicativo Moon.js a este elemento
view
(a seguir falaremos sobre os drivers com mais detalhes):
Moon.use({
view: Moon.view.driver("#root")
})
Essa construção informa à biblioteca que ela deve conectar o aplicativo ao elemento com o identificador
root
. Se necessário, você pode especificar um elemento semelhante à biblioteca usando a API do navegador projetada para trabalhar com o DOM:
Moon.use({
view: Moon.view.driver(document.getElementById("root"))
})
Agora vamos falar sobre como a manipulação de dados é organizada em Moon.js e como criar elementos de interface usando essa biblioteca.
Sintaxe para descrever os elementos da interface
Para descrever as interfaces Moon.js, é usada a linguagem de programação Moon View Language (MVL), que foi desenvolvida especificamente para resolver esse problema. É semelhante a JSX. Essa linguagem é usada para descrever elementos e personalizar seus relacionamentos. Aqui está um exemplo:
<script type="text/moon">
function aView(data) {
return (
<div>Hi from Moon</div>
)
}
</script>
É fácil ver que este pedaço de Moon.js, que é responsável pela formação do elemento
<div>
, usa estruturas de sintaxe que lembram HTML. Mas essas estruturas são usadas no código JavaScript. O navegador não será capaz de executar esse código JavaScript, mas não é necessário, uma vez que Moon.js compila essas construções em JavaScript comum.
Trabalhando com dados
Moon.js usa o conceito de drivers para controlar a apresentação visual dos elementos e trabalhar com dados. Aqui daremos uma olhada no driver que nos permite trabalhar com dados e na próxima seção falaremos sobre o driver para trabalhar com elementos de interface.
Um driver de dados é responsável por armazenar os dados do aplicativo e permitir que os dados sejam usados onde forem necessários. Em outras palavras, este driver armazena o estado global do aplicativo.
Você pode definir os dados iniciais para o aplicativo Moon.js usando a API
Moon.use
:
Moon.use({
data: Moon.data.driver
})
Você pode gravar novos dados em estados, retornando-os das funções correspondentes:
Moon.run(({ data }) => {
console.log(data) // undefined
return {
data: "Nnamdi"
}
})
A API
Moon.run
é responsável por iniciar o aplicativo. O retorno de chamada passado para esta API recebe uma referência aos dados globais como um argumento data
. Como no momento de chamar esta função, não data
há nada ainda, o comando console.log
deste exemplo será gerado undefined
.
Retornamos do callback um objeto que possui uma propriedade
data
com um valor Nnamdi
. Este objeto representará um novo estado do aplicativo, cujos dados podem ser usados por qualquer outra função que seja chamada data
.
Examinamos o mecanismo para trabalhar com dados em Moon.js. Agora vamos falar com mais detalhes sobre como trabalhar com elementos de interface.
Trabalho com elementos de interface
Moon.js tem um driver
view
para criar elementos e montá-los no DOM.
Já examinamos o snippet de código repetido abaixo, no qual o elemento
<div>
Moon.js base está conectado ao elemento:
Moon.use({
view: Moon.view.driver("#root")
})
É aqui que o elemento é montado. As funções agora podem retornar elementos que são capazes de substituir elementos antigos. Eles podem ser representados na forma de objetos que contêm uma propriedade
view
na qual os dados correspondentes são gravados. A biblioteca obtém o valor view
da propriedade do objeto retornado pela função e o grava no elemento conectado ao elemento com o identificador root
.
Moon.js usa o conceito de DOM virtual e um algoritmo poderoso para comparar versões antigas e novas de interface. Isso permite que a biblioteca tome decisões sobre quando atualizar o DOM e quais partes do DOM precisam ser atualizadas.
function handleClick() {
return {};
}
Moon.run(() => ({
view: <button @click=handleClick>Click Me!</button>
}));
Aqui, o retorno de chamada transmitido
Moon.run
está enviando o botão para o DOM. Isso ocorre devido ao fato da função retornar um objeto com uma propriedade view
. O valor atribuído a esta propriedade vai para o DOM.
O botão possui um manipulador de eventos
click
, representado por uma função handleClick
. Esta função retorna um objeto vazio, chamá-lo não altera o DOM.
Criação de elementos
Moon.js fornece ao desenvolvedor um grande conjunto de funções auxiliares para a criação de elementos de interface. Como resultado, descobriu-se que os elementos podem ser criados não usando a linguagem de descrição da interface Moon.js, mas as funções correspondentes:
const { div, text, node, p } = Moon.view.m
Moon.js exporta funções cujos nomes correspondem aos nomes dos elementos que eles criam. Portanto, a função
div
permite criar itens <div>
. A função text
cria nós de texto. A função node
permite criar elementos personalizados. A função p
cria elementos <p>
. Como você pode ver, os nomes dessas funções indicam claramente sua finalidade.
Vamos criar um elemento
<div>
:
const Div = div({});
Você pode atribuir atributos a elementos passando um objeto com propriedades para a função correspondente:
const Div = div({
class: "DivClass"
});
Aqui descrevemos o elemento
<div>
, em cujo atributo class
o valor deve ser escrito DivClass
.
Veja como criar um elemento de texto:
const Text = text({ data: "A text node" });
A propriedade do
data
objeto passado para a função text
contém o texto do elemento.
Vamos criar um elemento personalizado:
const CustomEl = node("custom-el");
Para atribuir qualquer atributo a este elemento, você pode fazer o seguinte:
CustomEl({ "attr": "attr-value"})
Desenvolvimentos
Você pode anexar manipuladores de eventos a elementos usando uma construção que usa um símbolo
@
:
function handleClick() {
return {};
}
Moon.run(() => ({
view: <button @click=handleClick>Click Me!</button>
}));
Como resultado, um botão com texto será exibido na página
Click Me
, ao clicar no qual a função será chamada handleClick
.
Componentes
Em Moon.js, funções são componentes. Isso significa que as funções podem ser mencionadas na descrição dos elementos da interface. O que a função retorna será incluído no elemento.
Suponha que tenhamos uma função como esta:
function aView({ data }) {
return <div>A View</div>
}
Esta função ,,
aView
retorna um elemento que pode ser renderizado:
Moon.run(() => {
view: <div><aView /></div>
})
O nome da função é usado neste exemplo como o nome do elemento. Como resultado da execução desse código, verifica-se que o que a função retorna será colocado na tag
<div>
. Quando tudo isso estiver no DOM, haverá uma marcação como esta:
<div>
<div>A View</div>
</div>
Desenvolvimento de aplicativos baseados em Moon.js
Para reunir tudo o que acabamos de falar, vamos criar um aplicativo TODO simples em Moon.js. Aqui, usaremos o exemplo correspondente , que foi preparado pelos desenvolvedores do Moon.js.
Quero lembrá-lo de que é recomendável, ao mesmo tempo que domina novas bibliotecas e estruturas, criar pequenos aplicativos com a ajuda deles. Isso permite que você agilize o aprendizado e ajuda a entender os recursos das ferramentas estudadas. No início, estamos falando sobre seus fundamentos, mas com o tempo, vem uma compreensão de mecanismos mais complexos.
Esta é a aparência da página deste aplicativo.

Página do aplicativo A página possui um título, um campo, um botão e uma lista de tarefas, que pode ser reabastecida inserindo suas descrições no campo e clicando no botão.
Vamos começar criando um arquivo
index.html
. Aqui, conectamos Moon.js diretamente à página:
<html>
<body>
<div id="root"></div>
</body>
<script src="https://unpkg.com/moon"></script>
<script src="https://unpkg.com/moon-browser"></script>
<!-- , -->
<script type="text/moon">
function viewTodos({data, view}) {
return (
<div>
<input type="text" value=data.todo @input=updateTodo/>
<button @click=createTodo>Create</button>
<ul children=(data.todos.map(todo =>
<li>{todo}</li>
))/>
</div>
)
}
function updateTodo({ data, view }) {
const dataNew = { ...data, todo: view.target.value };
return {
data: dataNew,
view: <viewTodos data=dataNew/>
}
}
function createTodo({ data }) {
const dataNew = {
todo: "",
todos: [...data.todos, data.todo]
};
return {
data: dataNew,
view: <viewTodos data=dataNew/>
}
}
<!-- data view -->
Moon.use({
data: Moon.data.driver,
view: Moon.view.driver("#root")
})
<!-- -->
Moon.run(() => {
data: [],
view: <viewTodos data=[]>
})
</script>
</html>
A função
viewTodos
exibe os itens necessários para inserir informações sobre novos casos e exibi-los em uma lista. Seus argumentos são data
e view
.
A função
createTodo
cria um novo caso e o retorna na propriedade do data
objeto que retorna.
A função
updateTodo
grava um novo caso no estado do aplicativo.
Preste atenção aos manipuladores de eventos
@click
e @input
que estão na função viewTodos
. O evento @input
é acionado quando você insere um texto que descreve o caso no campo apropriado. Quando este evento é processado, uma função é chamada updateTodo
. Argumentoview
nesta função representa o evento que ocorreu. Com ele, acessamos o DOM e obtemos os dados inseridos no campo. Esses dados então entram no estado como uma propriedade todo
.
O evento
@click
é chamado após clicar no botão. Ele registra uma nova lista de tarefas pendentes. A função é usada para resolver este problema createTodo
. Esta função acessa a propriedade state todo
e grava novos dados na propriedade todos
, após os quais, na propriedade do view
objeto que lhe é devolvido, retorna o elemento <viewTodos>
representado pela função correspondente, em cujo atributo data
o valor está escrito dataNew
.
Isso irá renderizar novamente
viewTodos
e atualizar o DOM. Um novo caso é adicionado à lista de tarefas exibida na página.
Execute este aplicativo em seu navegador e experimente-o.
Resultado
Cobrimos o básico do Moon.js. Ou seja, falamos sobre o fato de que você pode usar a biblioteca instalando-a do NPM e conectando-a diretamente às páginas. A seguir, discutimos os mecanismos internos da biblioteca: trabalhar com dados, manipular eventos, desenvolver componentes.
Moon.js parece ser uma boa biblioteca. E, mesmo sem falar das outras vantagens, gosto dele pelo tamanho compacto.
Você usou Moon.js?

