- La gente habla de htmx como si fuera a salvar la web de las SPA
- Carson Gross, creador de htmx, explica con ingenio esta dinámica como la "dialéctica de Hegel":
- tesis: MPA tradicional
- antítesis: SPA
- síntesis: una aplicación compuesta por islas interactivas basadas en hipermedia
- Pero yo no vi eso y, hace tiempo, "hice una SPA con htmx"
- Es un PoC de una app simple de lista de tareas
- Una vez que carga la página, ya no se comunica con el servidor
- Todo se procesa localmente en el cliente
- Si htmx está enfocado en gestionar el intercambio de hipermedia a través de la red, ¿cómo funciona esto?
- Un truco simple: el código del "lado del servidor" se ejecuta en un Service Worker
Service Worker
- Actúa como proxy entre la página web y el internet
- Puede interceptar y manipular solicitudes de red
- Puede modificar solicitudes, cachear respuestas para uso offline y generar nuevas respuestas sin enviar solicitudes fuera del navegador
- Esta última capacidad es la clave de esta app de una sola página
- Cuando se hace una solicitud de red con htmx, el Service Worker la intercepta
- Luego el Service Worker ejecuta la lógica de negocio y genera HTML nuevo
- htmx reemplaza el DOM con ese HTML nuevo
Ventajas frente a una SPA tradicional
- El Service Worker tiene que usar IndexedDB como almacenamiento
- Eso mantiene el estado entre cargas de página
- Aunque cierres la página y vuelvas después, la app recuerda los datos
- Es un beneficio colateral que obtienes "gratis" al elegir esta arquitectura
- Es fácil hacer que también funcione offline
Desventajas
- El soporte de las herramientas de desarrollo es deficiente
console.log se pierde de forma intermitente
- Los reportes sobre si el Service Worker está instalado no son confiables
- Falta soporte para módulos ES en Firefox
- Todo el código tiene que ir en un solo archivo
- La experiencia general de desarrollo "no es divertida"
Aun así, la SPA con htmx funciona bien
Detalles de implementación
- El HTML base es el armazón vacío de la app de una sola página
- La etiqueta
<body> configura el cuerpo de la app usando htmx
hx-boost="true": le indica a htmx que reemplace con Ajax las respuestas de clics en enlaces y envíos de formularios, sin navegación de página completa
hx-push-url="false": evita que htmx cambie la URL según los clics en enlaces y envíos de formularios
hx-get="./ui": le indica que, al cargar la página, obtenga y reemplace el contenido desde /ui
hx-target="body": le indica que reemplace el resultado en el elemento <body>
hx-trigger="load": le indica que haga todo esto al cargar la página
/ui endpoint
- Devuelve el marcado real de la app
- Después, htmx controla los enlaces y formularios para volverla interactiva
- El Service Worker maneja el ruteo de solicitudes con una librería estilo Express
setFilter y listTodos son funciones simples que envuelven IDB Keyval
- El componente
App está compuesto por el formulario de filtro, la lista de tareas y el formulario para agregar
/todos/add endpoint
- Guarda la tarea y devuelve una respuesta que vuelve a renderizar la UI
- htmx reemplaza el DOM con la respuesta
Componente Todo
- Está compuesto por una casilla de verificación, un botón de eliminar y el texto de la tarea
- La casilla de verificación dispara una solicitud a
/todos/${id}/update
- El botón de eliminar dispara una solicitud de borrado a
/todos/${id}
- El texto de la tarea tiene dos estados: "normal" y "editing"
- htmx escucha el evento de doble clic
- Solicita
/ui/todos/${id}?editable=true
- El Service Worker devuelve HTML de
Todo con un <input> incluido
- htmx reemplaza la tarea actual con el HTML de la respuesta
Resumen
- Técnicamente funciona
- ¿Es una buena idea? ¿Es realmente la culminación de las apps basadas en hipermedia? ¿Deberíamos abandonar React y construir así?
- En una app completamente local, la indirección de htmx se siente más como una carga que como una liberación
- La mayoría de las apps no son completamente locales
- Me parece mejor el patrón de "islas interactivas" que dividir el código del "lado del servidor" entre el Service Worker y un servidor real
- Fue un intento experimental de mostrar cómo construir una app de una sola página completamente local con hipermedia
Aún no hay comentarios.