Spaghettify convierte cualquier sitio HTML estático en una aplicación de una sola página con navegación basada en AJAX y funciones de persistencia de elementos DOM. Para hacerlo, implementa un interceptor DOM y un procesador de canalización de middleware que captura eventos de clic en enlaces, recupera cada documento solicitado a través de XHR y digiere la respuesta transmitiéndola a través de una serie de funciones de middlware antes de actualizar el documento del navegador.
Estas funciones de middleware son controladores de E/S conectables que respetan el principio de responsabilidad única y conforman un conjunto completo de pasos, que se pueden clasificar en ganchos de middleware onBeforeComplete
, que NO mutan el DOM de la página actual, y ganchos de middleware onAfterComplete
que sí aplican sus cambios. (por lo tanto, mutar) directamente en el DOM de la página actual después de haber sido inyectado.
Todo el proyecto está construido sobre TypeScript e implementa varios polyfills y estrategias de codificación para ampliar el soporte a navegadores antiguos, como MSIE11.
Los requisitos mínimos para ejecutar este proyecto, ya sea en modo de desarrollo o producción, y sus scripts de desarrollo son node v12.16.0
y npm v.6.14.15
, o versiones posteriores. Probablemente este proyecto se ejecutará sin problemas en versiones anteriores de node
y npm
, pero recomendamos utilizar las últimas versiones de LTS.
Este proyecto se basa en BabelJS y Webpack para compilar código en modo de desarrollo, ejecutar compilaciones para los archivos del sitio de demostración y manejar optimizaciones de código.
Toda la interacción con BabelJS
y Webpack
se ha resumido en scripts npm personalizados para su comodidad.
Como primer paso para generar un entorno de desarrollo o una compilación de producción, ejecute yarn
o npm install
para extraer todas las dependencias necesarias para este proyecto.
Ejecute yarn build
o npm run build
desde la ventana de su terminal.
El paquete del proyecto navegará por todo el árbol de aplicaciones y creará el artefacto JavaScript en la carpeta /dist
, empaquetado como spaghettify.js
. Otros paquetes útiles también se guardarán allí para su comodidad.
¿Puedo recuperar Spaghettify del registro npm? Al momento de escribir este artículo, las prioridades del proyecto son aumentar un poco más la cobertura de las pruebas y ampliar las capacidades de la API con soporte extendido para enlaces de middleware proporcionados por el usuario. Por el momento, Spaghettify está destinado a ser consumido como una dependencia del navegador, pero distribuirlo como un paquete NPM está en la hoja de ruta. Vuelva a consultar en breve para obtener actualizaciones.
Puede crear instancias de Spaghettify e interactuar con él a través de una API conveniente que incluye alternancias globales, interceptores de rutas, exclusiones y indicadores de atributos de persistencia de estado y, por último, pero no menos importante, indicadores y controladores de progreso de carga.
Una vez que haya compilado exitosamente Spaghettify, puede importarlo y crear una instancia en su aplicación de la siguiente manera:
< script type =" text/javascript " src =" /dist/spaghettify.js " > </ script >
< script type =" text/javascript " >
new Spaghettify ( {
enabled : true ,
routes : [ '*.html' , 'content/*' ] ,
excludeByAttr : 'no-spa' ,
loadProgress : true ,
persistAttr : 'data-persist' ,
} ) ;
</ script >
Como puede ver, Spaghettify puede tomar un objeto de configuración al crear una instancia. Tenga en cuenta que todos los campos son opcionales e incluso todo el objeto de configuración también es opcional. Si no se proporciona, se creará una instancia de Spaghettify con las opciones predeterminadas como se describe en la siguiente tabla.
El objeto de configuración de Spaghettify se puede resumir de la siguiente manera:
Campo | Tipo | Por defecto | Descripción |
---|---|---|---|
enabled | Boolean | true | Habilita o deshabilita Spaghettify al crear instancias |
routes | String[] | ['*'] | Define patrones para las rutas que se interceptarán y servirán a través de Spaghettify. Admite tokens globales. |
excludeByAttr | String | undefined | Define un token de atributo de datos de exclusión (con o sin el prefijo data- ). Spaghettify omitirá los enlaces decorados con este atributo. |
loadProgress | Function Boolean | false | Habilita o no una barra de progreso incorporada. También puede tomar un controlador de función que recibirá un porcentaje entero de progreso al cargar. |
persistAttr | String | undefined | Define un atributo de datos del indicador de persistencia del estado de la interfaz de usuario (con o sin el prefijo data- ). Los elementos decorados con este atributo conservarán su estado a lo largo de la navegación de la página. |
Tenga en cuenta que todas las opciones de configuración (y la carga útil de las opciones en sí) son opcionales y tomarán el valor predeterminado si no se declaran explícitamente.
Spaghettify interactúa con su documento actual vinculando internamente controladores de eventos a enlaces elegibles. Para evitar pérdidas de memoria o si desea detener Spaghettify hasta que se restablezca nuevamente, deberá destruirlo de la siguiente manera:
< script type =" text/javascript " >
// First, we instantiate Spaghettify
const spa = new Spaghettify ( ) ;
// Then we dispose it after use
spa . destroy ( ) ;
</ script >
Spaghettify configura todos los enlaces como sujetos a ser interceptados. La maquinaria interna del administrador de eventos evaluará si el enlace es elegible para ser tratado como una solicitud AJAX o no probando el valor href del enlace con los tokens globales routes
.
Sin embargo, podemos omitir este paso desde el principio configurando la opción excludeByAttr
con un valor de atributo, ya sea con el prefijo data-
o no.
No obstante, y por motivos de semántica, Spaghettify solo considerará elementos de enlace configurados con el atributo completo.
< script type =" text/javascript " >
new Spaghettify ( {
excludeByAttr : 'skip-me' ,
} ) ;
</ script >
<!-- Spaghettify will disregard the following link -->
< a href =" foo.html " data-skip-me > Skip this link </ a >
El atributo configurado se puede completar con cualquier valor o con ninguno. Spaghettify ignorará ese valor de todos modos.
Como ya vimos, la opción de configuración loadProgress
puede tomar un valor primitivo Boolean
o un controlador de función .
< script type =" text/javascript " >
new Spaghettify ( {
loadProgress : true ,
} ) ;
</ script >
Si no se configura explícitamente o se establece en false
, no se mostrará ningún indicador de barra de progreso. Si se proporciona como true
, Spaghettify mostrará un indicador de barra de progreso roja animada en la parte superior de la ventana gráfica. La barra de progreso muestra el progreso de descarga real.
Sin embargo, es posible que los consumidores quieran implementar sus propias soluciones visuales para representar la información del progreso de la descarga. Spaghettify los cubre proporcionando un controlador de progreso de carga que esperará un parámetro de valor entero en su firma, que tomará valores de 0
a 100
a medida que las páginas se soliciten y descarguen a través de HXR.
< script type =" text/javascript " >
new Spaghettify ( {
loadProgress : function onLoad ( progress ) {
console . log ( progress ) ; // Will log values from 0 to 100
} ,
} ) ;
</ script >
Spaghettify implementa una API experimental para conservar el estado en nodos DOM seleccionados y anotados en la navegación de la página. Para hacerlo, solo necesita configurar un token de valor en la opción persistAttr
y luego anotar aquellos elementos DOM cuyo estado desea que persista con el atributo data-
equivalente con un valor único cada uno:
< script type =" text/javascript " >
new Spaghettify ( {
persistAttr : 'persist-id' ,
} ) ;
</ script >
< input type =" text " data-persist-id =" my-input " />
Puede prefijar explícitamente el valor con data-
o no, pero Spaghettify requerirá que anote los elementos DOM para que persistan con la sintaxis completa del atributo de datos.
Tenga en cuenta : los valores de los atributos deben ser únicos. Spaghettify generará una excepción si más de un elemento de diferente tipo está configurado con el mismo valor de atributo.
Vale la pena resaltar que la persistencia se aplicará en todo el Node
DOM, por lo que abarcará no solo el HTML interno del elemento sino también el estado nativo tocado para los controles de entrada. Y todo ello independientemente de los cambios en el HTML exterior.
Puede generar un entorno de desarrollo ejecutando yarn dev
o npm run dev
en la consola.
El sistema generará todos los artefactos y servirá el sitio sandbox (más detalles a continuación) desde http://localhost:3000 (o cualquier otro puerto de su elección si agrega el parámetro --port=PORT
al comando dev
, donde PORT
es el puerto deseado) en modo de vigilancia , por lo que la aplicación se volverá a compilar cuando se realicen cambios en el código fuente.
El sitio sandbox es una aplicación web pequeña y súper simplista que sirve como patio de juegos y campo de pruebas para depurar Spaghettify en un entorno real. Presenta un estilo bastante simplista, a través de un conjunto de páginas jerárquicas diferentes que representan las siguientes características clave:
index.html
principal contiene una instancia de Spaghettify en línea para fines de demostración. Todos los demás documentos implementan dicha instancia como un script importado. No es necesario importar Spaghettify en cada documento, solo el de entrada. Sin embargo, esto permite iniciar Spaghettify desde cualquier documento después de recargar la ventana del navegador con fines de demostración. En un escenario de producción real, Spaghettify puede (y debe) importarse y crearse una instancia solo una vez en la ubicación de entrada./sandbox
y una subcarpeta secundaria /sandbox/content
para que los contribuyentes puedan jugar con selectores de enlaces que apunten a subcarpetas, si es necesario./sandbox/content
cuentan con JavaScript personalizado en línea o importado que Spaghettify digiere, reinyecta y ejecuta cuando sea necesario. ESLint está actualmente habilitado en el código base de Spaghettify y se activará una auditoría de linting al construir el proyecto. Puede configurar su IDE para proporcionar automáticamente una evaluación de linting a medida que introduce cambios. Además, puede activar el código linting en cualquier momento ejecutando npm run lint
o yarn lint
en la consola de su terminal.
Puede introducir pruebas en el código base o ejecutar las existentes ejecutando npm test
o yarn test
en su consola terminal. Los datos de cobertura del código se recopilan y almacenan en un documento convenientemente formateado en /coverage/lcov-report
. Para obtener informes de cobertura en pantalla, agregue el parámetro --coverage
al comando test
.
También puede consultar en línea un informe completo de cobertura de pruebas en Coveralls.
Copyright 2021 Pablo Deeleman
Por el presente se otorga permiso, sin cargo, a cualquier persona que obtenga una copia de este software y los archivos de documentación asociados (el "Software"), para operar con el Software sin restricciones, incluidos, entre otros, los derechos de uso, copia, modificación, fusión. , publicar, distribuir, sublicenciar y/o vender copias del Software, y permitir que las personas a quienes se les proporciona el Software lo hagan, sujeto a las siguientes condiciones:
El aviso de derechos de autor anterior y este aviso de permiso se incluirán en todas las copias o partes sustanciales del Software.
EL SOFTWARE SE PROPORCIONA "TAL CUAL", SIN GARANTÍA DE NINGÚN TIPO, EXPRESA O IMPLÍCITA, INCLUYENDO PERO NO LIMITADO A LAS GARANTÍAS DE COMERCIABILIDAD, IDONEIDAD PARA UN PROPÓSITO PARTICULAR Y NO INFRACCIÓN. EN NINGÚN CASO LOS AUTORES O TITULARES DE DERECHOS DE AUTOR SERÁN RESPONSABLES DE NINGÚN RECLAMO, DAÑO U OTRA RESPONSABILIDAD, YA SEA EN UNA ACCIÓN CONTRACTUAL, AGRAVIO O DE OTRA MANERA, QUE SURJA DE, FUERA DE O EN RELACIÓN CON EL SOFTWARE O EL USO U OTRAS NEGOCIOS EN EL SOFTWARE.