Biblioteca Moon.js
Moon.js es una biblioteca de JavaScript minimalista para desarrollar interfaces rápidas y funcionales. Tiene un tamaño relativamente pequeño, lo que permite crear aplicaciones bastante compactas sobre su base. La biblioteca tiene un rendimiento muy alto,
Moon.js adopta un enfoque basado en componentes para el diseño de la interfaz. Las plantillas se utilizan para crear componentes. Esta biblioteca es bastante similar a Vue.js.
Puntos fuertes de Moon.js
- Moon.js es de tamaño compacto (minificado y comprimido tiene aproximadamente 2 KB). Esto es más pequeño que el tamaño de otras bibliotecas y marcos como React y Angular.
- Esta biblioteca se distingue por su alta velocidad de renderizado de interfaces.
- Moon.js es una biblioteca basada en técnicas de desarrollo funcional. Al trabajar con él, se utiliza un enfoque para el diseño de la interfaz, basado en los llamados "controladores".
Inicio de obra
La biblioteca Moon.js se puede incluir en un proyecto de dos formas. El primero es instalarlo desde NPM. El segundo es conectarlo directamente a la página en la que se planea utilizarlo.
Si decide utilizar la versión NPM de la biblioteca, primero debe instalar el paquete
moon-cli
, la herramienta de línea de comandos:
$ npm i moon-cli -g
En este ejemplo, esta herramienta está instalada globalmente, puede llamarla desde cualquier directorio.
Para crear un proyecto basado en Moon.js, puede ejecutar el siguiente comando:
$ moon create moon-prj
Este comando crea un nuevo proyecto en una carpeta
moon-prj
. Una vez finalizada la creación del proyecto, tendrá a su disposición la base de la futura aplicación.
La segunda opción para usar Moon.js implica conectarlo a la página en la que planea usarlo. La biblioteca tiene un módulo
moon-browser
que le permite usar sus capacidades directamente en la página a la que está conectada.
Entonces, para conectar la biblioteca a la página, necesitamos incluir las siguientes dos etiquetas en la página:
<script src="https://unpkg.com/moon"></script>
<script src="https://unpkg.com/moon-browser"></script>
Como puede ver, los scripts correspondientes se cargan desde el CDN de unpkg. La primera etiqueta importa la biblioteca principal. El segundo es la biblioteca
moon-browser
. Ella es responsable de compilar las plantillas Moon.js para que parezcan adecuadas para su visualización en el navegador.
Ahora, para usar la sintaxis Moon.js en la página, deberá incluirlos en la etiqueta
<script>
, sin olvidar establecer su atributo type
como text/moon
.
<!-- -->
<script src="./main-script.js" type="text/moon"></script>
<!-- , -->
<script type="text/moon">
...
</script>
Conectando la aplicación Moon.js a la página
Moon.js, como otras bibliotecas y marcos utilizados para crear aplicaciones de una sola página, se conecta a un elemento de página específico. Por lo general, un elemento juega el papel de un contenedor para una aplicación Moon.js
<div>
:
<div id="root"></div>
Un elemento similar, que es el elemento raíz de la aplicación Moon.js, se coloca en el código del archivo
index.html
que es el punto de entrada al proyecto.
Se utiliza un controlador para conectar una aplicación Moon.js a este elemento
view
(a continuación, hablaremos sobre los controladores con más detalle):
Moon.use({
view: Moon.view.driver("#root")
})
Esta construcción le dice a la biblioteca que debe conectar la aplicación al elemento con el identificador
root
. Si es necesario, puede especificar un elemento similar a la biblioteca utilizando la API del navegador diseñada para trabajar con DOM:
Moon.use({
view: Moon.view.driver(document.getElementById("root"))
})
Ahora hablemos sobre cómo se organiza la manipulación de datos en Moon.js y cómo crear elementos de interfaz usando esta biblioteca.
Sintaxis para describir elementos de interfaz
Para describir las interfaces Moon.js, se utiliza el lenguaje de programación Moon View Language (MVL), que fue desarrollado específicamente para resolver este problema. Se parece a JSX. Este lenguaje se utiliza para describir elementos y personalizar sus relaciones. He aquí un ejemplo:
<script type="text/moon">
function aView(data) {
return (
<div>Hi from Moon</div>
)
}
</script>
Es fácil ver que esta pieza de Moon.js, que es responsable de la formación del elemento
<div>
, usa estructuras de sintaxis que se asemejan a HTML. Pero estas estructuras se utilizan en código JavaScript. El navegador no podrá ejecutar dicho código JavaScript, pero no es necesario, ya que Moon.js compila dichas construcciones en JavaScript ordinario.
Trabajando con datos
Moon.js utiliza el concepto de controladores para controlar la presentación visual de los elementos y trabajar con datos. Aquí echaremos un vistazo al controlador que nos permite trabajar con datos, y en la siguiente sección hablaremos sobre el controlador para trabajar con elementos de interfaz.
Un controlador de datos es responsable de almacenar los datos de la aplicación y permitir que los datos se utilicen donde se necesiten. En otras palabras, este controlador almacena el estado global de la aplicación.
Puede configurar los datos iniciales para la aplicación Moon.js mediante la API
Moon.use
:
Moon.use({
data: Moon.data.driver
})
Puede escribir nuevos datos en los estados devolviéndolos de las funciones correspondientes:
Moon.run(({ data }) => {
console.log(data) // undefined
return {
data: "Nnamdi"
}
})
La API
Moon.run
es responsable de iniciar la aplicación. La devolución de llamada pasada a esta API recibe una referencia a los datos globales como argumento data
. Dado que en el momento de llamar a esta función todavía data
no hay nada en ella, se console.log
generará el comando de este ejemplo undefined
.
Devolvemos un objeto de la devolución de llamada que tiene una propiedad
data
con un valor Nnamdi
. Este objeto representará un nuevo estado de la aplicación, cuyos datos pueden ser utilizados por cualquier otra función que llame data
.
Hemos examinado el mecanismo para trabajar con datos en Moon.js. Ahora hablemos con más detalle sobre cómo trabajar con elementos de interfaz.
Trabajar con elementos de la interfaz
Moon.js tiene un controlador
view
para crear elementos y montarlos en el DOM.
Ya hemos examinado el fragmento de código que se repite a continuación, en el que el elemento
<div>
base Moon.js está conectado al elemento:
Moon.use({
view: Moon.view.driver("#root")
})
Aquí es donde se monta el elemento. Las funciones ahora pueden devolver elementos que son capaces de reemplazar elementos antiguos. Se pueden representar como objetos que contienen una propiedad
view
, en la que se escriben los datos correspondientes. La biblioteca toma el valor de propiedad view
del objeto devuelto por la función y lo escribe en el elemento conectado al elemento con el identificador root
.
Moon.js utiliza el concepto de DOM virtual y un poderoso algoritmo para comparar versiones de interfaz antiguas y nuevas. Esto permitirá que la biblioteca tome decisiones sobre cuándo actualizar el DOM y qué partes del DOM deben actualizarse.
function handleClick() {
return {};
}
Moon.run(() => ({
view: <button @click=handleClick>Click Me!</button>
}));
Aquí, la devolución de llamada transmitida
Moon.run
está enviando el botón al DOM. Esto sucede debido al hecho de que la función devuelve un objeto con una propiedad view
. El valor asignado a esta propiedad ingresa al DOM.
El botón tiene un controlador de eventos
click
, representado por una función handleClick
. Esta función devuelve un objeto vacío, llamarlo no cambia el DOM.
Creando elementos
Moon.js proporciona al desarrollador un gran conjunto de funciones auxiliares para crear elementos de interfaz. Como resultado, resulta que los elementos se pueden crear utilizando no el lenguaje de descripción de la interfaz Moon.js, sino las funciones correspondientes:
const { div, text, node, p } = Moon.view.m
Moon.js exporta funciones cuyos nombres coinciden con los nombres de los elementos que crean. Entonces, la función le
div
permite crear elementos <div>
. La función text
crea nodos de texto. La función le node
permite crear elementos personalizados. La función p
crea elementos <p>
. Como puede ver, los nombres de estas funciones indican claramente su propósito.
Creemos un elemento
<div>
:
const Div = div({});
Puede asignar atributos a los elementos pasando un objeto con propiedades a la función correspondiente:
const Div = div({
class: "DivClass"
});
Aquí hemos descrito el elemento
<div>
, en class
cuyo atributo se debe escribir el valor DivClass
.
A continuación, se explica cómo crear un elemento de texto:
const Text = text({ data: "A text node" });
La propiedad del
data
objeto pasado a la función text
contiene el texto del elemento.
Creemos un elemento personalizado:
const CustomEl = node("custom-el");
Para asignar cualquier atributo a este elemento, puede hacer lo siguiente:
CustomEl({ "attr": "attr-value"})
Desarrollos
Puede adjuntar controladores de eventos a elementos mediante una construcción que usa un símbolo
@
:
function handleClick() {
return {};
}
Moon.run(() => ({
view: <button @click=handleClick>Click Me!</button>
}));
Como resultado, se mostrará un botón con texto en la página
Click Me
, al hacer clic en el que se llamará la función handleClick
.
Componentes
En Moon.js, las funciones son componentes. Esto significa que las funciones se pueden mencionar en la descripción de los elementos de la interfaz. Lo que devuelve la función se incluirá en el elemento.
Supongamos que tenemos una función como esta:
function aView({ data }) {
return <div>A View</div>
}
Esta función,
aView
devuelve un elemento que se puede representar:
Moon.run(() => {
view: <div><aView /></div>
})
El nombre de la función se usa en este ejemplo como el nombre del elemento. Como resultado de ejecutar este código, resulta que lo que devuelve la función se colocará en la etiqueta
<div>
. Cuando todo esto esté en el DOM, habrá un marcado como este:
<div>
<div>A View</div>
</div>
Desarrollo de aplicaciones basadas en Moon.js
Para reunir todo de lo que acabamos de hablar, creemos una aplicación TODO simple en Moon.js. Aquí usaremos el ejemplo correspondiente , que fue preparado por los desarrolladores de Moon.js.
Quiero recordarles que se recomienda, mientras se dominan nuevas bibliotecas y marcos, crear pequeñas aplicaciones con su ayuda. Esto le permite acelerar el aprendizaje y le ayuda a comprender las características de las herramientas estudiadas. Al principio, estamos hablando de sus fundamentos, pero con el tiempo, llega la comprensión de mecanismos más complejos.
Así es como se ve la página de esta aplicación.
Página de la aplicación La página tiene un título, un campo, un botón y una lista de tareas pendientes, que se pueden reponer ingresando sus descripciones en el campo y haciendo clic en el botón.
Comencemos creando un archivo
index.html
. Aquí conectamos Moon.js directamente a la 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>
La función
viewTodos
muestra los elementos necesarios para ingresar información sobre nuevos casos y mostrarlos en una lista. Sus argumentos son data
y view
.
La función
createTodo
crea un nuevo caso y lo devuelve en la propiedad del data
objeto que devuelve.
La función
updateTodo
escribe un nuevo caso en el estado de la aplicación.
Preste atención a los manejadores de eventos
@click
y @input
que están en la función viewTodos
. El evento @input
se llama cuando ingresa texto que describe el caso en el campo correspondiente. Cuando se procesa este evento, se llama a una función updateTodo
. Argumentoview
en esta función representa el evento que ocurrió. Utilizándolo, accedemos al DOM y obtenemos los datos ingresados en el campo. Estos datos luego ingresan al estado como una propiedad todo
.
El evento
@click
se llama después de hacer clic en el botón. Registra una nueva lista de tareas pendientes. La función se utiliza para resolver este problema createTodo
. Esta función accede a la propiedad de estado todo
y escribe nuevos datos en la propiedad todos
, luego de lo cual, en la propiedad del view
objeto que se le devuelve, devuelve el elemento <viewTodos>
representado por la función correspondiente, en data
cuyo atributo se escribe el valor dataNew
.
Esto volverá a renderizar
viewTodos
y actualizar el DOM. Se agrega un nuevo caso a la lista de tareas pendientes que se muestra en la página.
Ejecute esta aplicación en su navegador y experimente con ella.
Salir
Hemos cubierto los conceptos básicos de Moon.js. Es decir, hablamos sobre el hecho de que puede usar la biblioteca instalándola desde NPM y conectándola a las páginas directamente. A continuación, discutimos los mecanismos internos de la biblioteca: trabajar con datos, manejar eventos, desarrollar componentes.
Moon.js parece ser una buena biblioteca. Y, aunque no hablemos de sus otras ventajas, me gusta por su tamaño compacto.
¿Has usado Moon.js?