Spaghettify transforme n'importe quel site HTML statique en une application à page unique avec une navigation pilotée par AJAX et des fonctionnalités de persistance des éléments DOM. Pour ce faire, il implémente un intercepteur DOM et un processeur d'entonnoir middleware qui capture les événements de clic sur les liens, récupère chaque document demandé via XHR et digère la réponse en la diffusant via une série de fonctions middleware avant d'actualiser le document du navigateur.
Ces fonctions middleware sont des gestionnaires d'E/S enfichables qui respectent le principe de responsabilité unique et conforment un pipeline complet d'étapes, qui peuvent être classées en hooks middleware onBeforeComplete
, qui NE modifient PAS le DOM de la page actuelle, et en hooks middleware onAfterComplete
qui appliquent leurs modifications. (donc muter) directement sur la page DOM en cours après son injection.
L'ensemble du projet est construit sur TypeScript et implémente plusieurs polyfills et stratégies de codage pour étendre la prise en charge des anciens navigateurs hérités, tels que MSIE11.
La configuration minimale requise pour exécuter ce projet, en mode développement ou production, et ses scripts de développement sont node v12.16.0
et npm v.6.14.15
, ou des versions ultérieures. Ce projet fonctionnera probablement correctement sur les anciennes versions de node
et npm
mais nous vous recommandons d'utiliser les dernières versions LTS.
Ce projet s'appuie sur BabelJS et Webpack pour compiler le code en mode développement, les builds en cours d'exécution servent les fichiers du site de démonstration et gèrent les optimisations du code.
Toutes les interactions avec BabelJS
et Webpack
ont été résumées dans des scripts npm personnalisés pour votre commodité.
Dans un premier temps pour générer un environnement de développement ou une version de production, veuillez exécuter yarn
ou npm install
pour extraire toutes les dépendances requises pour ce projet.
Veuillez exécuter yarn build
ou npm run build
à partir de la fenêtre de votre terminal.
Le bundler de projet naviguera dans toute l'arborescence des applications et construira l'artefact JavaScript dans le dossier /dist
, regroupé sous le nom spaghettify.js
. D’autres ensembles utiles y seront également enregistrés pour votre commodité.
Puis-je récupérer Spaghettify à partir du registre npm ? Au moment d'écrire ces lignes, les priorités du projet sont d'augmenter un peu plus la couverture des tests et d'élargir les capacités de l'API avec une prise en charge étendue des hooks middleware fournis par l'utilisateur. Pour le moment, Spaghettify est destiné à être consommé en tant que dépendance de navigateur, mais sa distribution sous forme de package NPM est dans la feuille de route. Veuillez revenir sous peu pour les mises à jour.
Vous pouvez instancier et interagir avec Spaghettify via une API pratique avec des bascules globales, des intercepteurs de route, des exclusions et des indicateurs d'attributs de persistance d'état et, enfin et surtout, le chargement d'indicateurs de progression et de gestionnaires.
Une fois que vous avez compilé Spaghettify avec succès, vous pouvez l'importer et l'instancier dans votre application comme suit :
< 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 >
Comme vous pouvez le voir Spaghettify peut prendre un objet de configuration lors de l'instanciation. Veuillez noter que tous les champs sont facultatifs et que même l'ensemble de l'objet de configuration lui-même est également facultatif. S'il n'est pas fourni, Spaghettify sera instancié avec les options par défaut comme décrit dans le tableau ci-dessous.
L'objet des paramètres de configuration Spaghettify peut être résumé comme suit :
Champ | Taper | Défaut | Description |
---|---|---|---|
enabled | Boolean | true | Active ou désactive Spaghettify lors de l'instanciation |
routes | String[] | ['*'] | Définit les modèles pour les itinéraires à intercepter et à desservir via Spaghettify. Prend en charge les jetons globaux. |
excludeByAttr | String | undefined | Définit un jeton d'attribut de données d'exclusion (avec ou sans le préfixe data- ). Les liens décorés avec cet attribut seront contournés par Spaghettify |
loadProgress | Function Boolean | false | Active ou non une barre de progression intégrée. Il peut également prendre un gestionnaire de fonctions qui recevra un pourcentage entier de progression lors du chargement. |
persistAttr | String | undefined | Définit un attribut de données d'indicateur de persistance d'état de l'interface utilisateur (avec ou sans le préfixe data- ). Les éléments décorés avec cet attribut conserveront leur état tout au long de la navigation dans les pages. |
Veuillez noter que toutes les options de configuration (et la charge utile des options elle-même) sont facultatives et prendront la valeur par défaut si elles ne sont pas explicitement déclarées.
Spaghettify interagit avec votre document actuel en liant en interne les gestionnaires d'événements aux liens éligibles. Afin d'éviter les fuites de mémoire ou si vous souhaitez arrêter Spaghettify jusqu'à ce qu'il soit rétabli, vous souhaiterez le détruire comme suit :
< script type =" text/javascript " >
// First, we instantiate Spaghettify
const spa = new Spaghettify ( ) ;
// Then we dispose it after use
spa . destroy ( ) ;
</ script >
Tous les liens sont configurés par Spaghettify comme susceptibles d'être interceptés. Le gestionnaire d'événements interne évaluera si le lien peut être traité comme une requête AJAX ou non en testant la valeur href du lien par rapport aux jetons globaux routes
.
Cependant, nous pouvons contourner cette étape dès le départ en configurant l'option excludeByAttr
avec une valeur d'attribut, avec ou sans le préfixe data-
.
Néanmoins, et par souci de sémantique, Spaghettify ne considérera alors que les éléments de lien configurés avec l'attribut à part entière.
< 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 >
L'attribut configuré peut être renseigné avec n'importe quelle valeur ou aucune valeur du tout. Spaghettify ignorera cette valeur de toute façon.
Comme nous l'avons déjà vu, l'option de configuration loadProgress
peut prendre une valeur primitive Boolean
ou un gestionnaire de fonction .
< script type =" text/javascript " >
new Spaghettify ( {
loadProgress : true ,
} ) ;
</ script >
S’il n’est pas explicitement configuré ou défini sur false
, aucun indicateur de barre de progression ne sera affiché. S'il est fourni comme true
, Spaghettify affichera un indicateur de barre de progression rouge animé en haut de la fenêtre. La barre de progression affiche la progression réelle du téléchargement.
Cependant, les consommateurs souhaiteront peut-être mettre en œuvre leurs propres solutions visuelles pour afficher les informations sur la progression du téléchargement. Spaghettify les couvre en fournissant un gestionnaire de progression de chargement qui attendra un paramètre de valeur entière dans sa signature, qui prendra des valeurs de 0
à 100
à mesure que les pages sont demandées et téléchargées via HXR.
< script type =" text/javascript " >
new Spaghettify ( {
loadProgress : function onLoad ( progress ) {
console . log ( progress ) ; // Will log values from 0 to 100
} ,
} ) ;
</ script >
Spaghettify implémente une API expérimentale pour conserver l'état dans les nœuds DOM sélectionnés et annotés lors de la navigation dans les pages. Pour ce faire, il vous suffit de configurer un jeton de valeur dans l'option persistAttr
, puis d'annoter les éléments DOM dont vous souhaitez conserver l'état avec l'attribut data-
équivalent avec chacun une valeur unique :
< script type =" text/javascript " >
new Spaghettify ( {
persistAttr : 'persist-id' ,
} ) ;
</ script >
< input type =" text " data-persist-id =" my-input " />
Vous pouvez explicitement préfixer la valeur avec data-
ou non, mais Spaghettify vous demandera d'annoter les éléments DOM pour qu'ils soient conservés avec la syntaxe complète de l'attribut de données.
Attention : les valeurs d'attribut sont censées être uniques. Spaghettify lèvera une exception si plusieurs éléments de type différent sont configurés avec la même valeur d'attribut.
Il convient de souligner que la persistance sera appliquée sur la base d'un Node
DOM complet, elle englobera donc non seulement le code HTML interne de l'élément, mais également l'état tactile natif pour les contrôles d'entrée. Et tout cela indépendamment des modifications apportées au HTML externe.
Vous pouvez créer un environnement de développement en exécutant yarn dev
ou npm run dev
dans la console.
Le système générera tous les artefacts et servira le site sandbox (plus de détails ci-dessous) à partir de http://localhost:3000 (ou de tout autre port de votre choix si vous ajoutez le paramètre --port=PORT
à la commande dev
, où PORT
est le port souhaité) en mode montre , l'application sera donc recompilée lors des modifications du code source.
Le site sandbox est une petite application Web ultra-simpliste qui sert de terrain de jeu et d'arène de test pour déboguer Spaghettify dans un environnement réel. Il présente un style assez simpliste, à travers un ensemble de pages différentes et hiérarchiques décrivant les fonctionnalités clés suivantes :
index.html
principal contient une instance de Spaghettify en ligne à des fins de démonstration. Tous les autres documents implémentent une telle instance sous forme de script importé. Vous n'avez pas besoin d'importer Spaghettify sur chaque document, seulement celui d'entrée. Cependant, cela permet de lancer Spaghettify à partir de n'importe quel document après avoir rechargé la fenêtre du navigateur à des fins de démonstration. Dans un scénario de production réel, Spaghettify peut (et doit) être importé et instancié une seule fois dans l'emplacement d'entrée./sandbox
et un sous-dossier enfant /sandbox/content
afin que les contributeurs puissent jouer avec les sélecteurs de liens pointant vers des sous-dossiers, si nécessaire./sandbox/content
comportent du JavaScript personnalisé en ligne ou importé que Spaghettify digérera, réinjectera et exécutera si nécessaire. ESLint est actuellement activé dans la base de code Spaghettify et un audit de peluchage sera déclenché lors de la construction du projet. Vous pouvez configurer votre IDE pour fournir automatiquement une évaluation du peluchage à mesure que vous introduisez des modifications. De plus, vous pouvez déclencher le peluchage de code à tout moment en exécutant npm run lint
ou yarn lint
dans votre console de terminal.
Vous pouvez introduire des tests dans la base de code ou exécuter ceux existants en exécutant npm test
ou yarn test
dans votre console de terminal. Les données de couverture de code sont collectées et stockées dans un document formaté de manière pratique dans /coverage/lcov-report
. Pour obtenir un rapport de couverture à l'écran, veuillez ajouter le paramètre --coverage
à la commande test
.
Vous pouvez également consulter en ligne un rapport complet de couverture des tests sur Coveralls.
Copyright 2021 Pablo Deeleman
L'autorisation est accordée par la présente, gratuitement, à toute personne obtenant une copie de ce logiciel et des fichiers de documentation associés (le « Logiciel »), d'utiliser le Logiciel sans restriction, y compris, sans limitation, les droits d'utilisation, de copie, de modification, de fusion. , publier, distribuer, accorder des sous-licences et/ou vendre des copies du Logiciel, et permettre aux personnes à qui le Logiciel est fourni de le faire, sous réserve des conditions suivantes :
L'avis de droit d'auteur ci-dessus et cet avis d'autorisation doivent être inclus dans toutes les copies ou parties substantielles du logiciel.
LE LOGICIEL EST FOURNI « EN L'ÉTAT », SANS GARANTIE D'AUCUNE SORTE, EXPRESSE OU IMPLICITE, Y COMPRIS MAIS SANS LIMITATION LES GARANTIES DE QUALITÉ MARCHANDE, D'ADAPTATION À UN USAGE PARTICULIER ET DE NON-VIOLATION. EN AUCUN CAS LES AUTEURS OU LES TITULAIRES DES DROITS D'AUTEUR NE SERONT RESPONSABLES DE TOUTE RÉCLAMATION, DOMMAGES OU AUTRE RESPONSABILITÉ, QUE CE SOIT DANS UNE ACTION CONTRACTUELLE, DÉLIT OU AUTRE, DÉCOULANT DE, DE OU EN RELATION AVEC LE LOGICIEL OU L'UTILISATION OU D'AUTRES TRANSACTIONS DANS LE LOGICIEL.