Le menu
À retenir
Outils
- Convertisseur de code source en HTML
- Générateur de lien en (x)HTML
- Traduction Français-Esperanto online
Vie pratique
Portfolio
Présidentielles
Culture
- Respect des droits d'auteurs et droits voisins — Refus des Mesures Techniques de Protection (MTP)
- Licence globale : finalement je suis contre...
- Lettre à la SACEM : Réaction par rapport au projet de loi DADVSI
- Reprenons en main la culture !
- Gestion Numérique des droits (DRM) : une question de confiance
- Gestion Numérique des droits (DRM) : une question de confiance (2)
Archives
- Septembre 2008
- Aout 2008
- Juillet 2008
- Juin 2008
- Mai 2008
- Avril 2008
- Mars 2008
- Février 2008
- Janvier 2008
- Décembre 2007
- Novembre 2007
- Octobre 2007
- Septembre 2007
- Aout 2007
- Juillet 2007
- Juin 2007
- Mai 2007
- Avril 2007
- Mars 2007
- Février 2007
- Janvier 2007
- Décembre 2006
- Novembre 2006
- Octobre 2006
- Septembre 2006
- Aout 2006
- Juillet 2006
- Juin 2006
- Mai 2006
- Avril 2006
- Mars 2006
- Février 2006
- Janvier 2006
- Décembre 2005
- Novembre 2005
- Octobre 2005
- Septembre 2005
- Aout 2005
- Juillet 2005
- Juin 2005
- Mai 2005
- Avril 2005
- Mars 2005
- Février 2005
- Janvier 2005
- Décembre 2004
- Novembre 2004
- Octobre 2004
Spornikethon
- Mes créations vous plaisent ?
- Vous voulez me soutenir financièrement ?
- Cliquez sur un des boutons ci-dessous selon le montant du dons.
- Merci !
Rouleaux de blogs
Mes préférés
Les amis
- Les bla-blas de Chibi
- Lysel
- Orpheelin
- Nae-chan in Psycholand
- Circée
- Faery Book
- Les bijoux de Hime-Decco
Divers
Mes liens
- Non à la brevetabilité des logiciels en Europe
- Promotion d'artistes proposant de la musique légale et gratuite à télécharger
- Associations pour le Maintien d’une Agriculture Paysanne
- La Bible
- Wikipédia
- Le Trésor de la Langue Française Informatisé
- Liste prête à l'emploi pour Adblock
- Partitions pour guitare classique
- Forum francophone pour les collectionneurs et créateurs de poupées
- Association sportive et culturelle du 13ème arrondissement
Bombardement Google
Rendre une application HTML5 disponible hors connexion avec les Service Workers
Le 21 Novembre 2016 à 05:55
Le contexte
Maintenant que j'ai installé les outils indispensable au développement HTML5 (node.js, npm, bower et yeoman actuellement), j'ai commencé à me faire la main en utilisant le générateur FountainJs et son exemple d'application "todo list".
Après avoir ajouté une sauvegarde en utilisant le stockage local, il me fallait rendre l'application disponible hors connexion (pas de réseau sous un tunnel dans le RER par exemple...) afin de pouvoir utiliser ce pense-bête sans contrainte de connectivité.
J'allais partir sur les "appcache" quand je suis tombé sur les pages de Mozilla indiquant que cette technique était considérée comme "dépréciée" et qu'il fallait plutôt utiliser les Service Workers pour les nouveaux projets. En dehors de la complexité plus élevée que appcache, la contrainte d'avoir un site en HTTPS n'est pas un problème pour moi, puisque le serveur sur lequel je déploie l'application —un Raspberry Pi— répond exclusivement à ce genre de requête.
Donc le seul obstacle qu'il reste, c'est la mise en œuvre, et pour ça, j'ai simplement cherché un plugin utilisable avec gulp (l'outil de fabrique et d'empaquetage mis en place par le modèle de FountainJs) pour faire le gros du travail. J'ai finalement choisi sw-precache (Software Worker Precache) qui m'a l'air assez poussé, bien documenté, tout en restant simple pour mon petit projets : je mets tous mes fichiers en cache.
Générer le Service Worker
Il n'y a pas de difficulté particulière, mais il va falloir exclure le fichier généré de la tâche de vérification du code avec eslint. Le service worker sera généré dans le fichier sw-app-cache.js
.
Récupérer sw-precache
npm install --save-dev sw-precache
Créer les tâches gulp
// variables de configurations (gulp.conf.js) /** * precache global conf values */ exports.precacheSpecs = { target: 'sw-app-cache.js', staticFilesGlob: '/**/*.{js,html,css,png,jpg,gif,svg,eot,ttf,woff}' }; // définition des tâches (nouveau fichier : precache.js) // noter la distinction entre l'environnement de développement et l'environnement d'utilisation const gulp = require('gulp'); const path = require('path'); const swPrecache = require('sw-precache'); const conf = require('../conf/gulp.conf'); // gulp tasks declaration gulp.task('precache', precache); gulp.task('precache:dist', precacheDist); function precache(done) { doPrecache(conf, conf.path.src()+'/', '/'); done(); } function precacheDist(done) { doPrecache(conf, conf.path.dist()+'/', conf.baseHref.default); done(); } function doPrecache(conf, rootDir, appPrefix) { swPrecache.write(path.join(rootDir, conf.precacheSpecs.target), { staticFileGlobs: [rootDir + conf.precacheSpecs.staticFilesGlob], stripPrefix: rootDir, replacePrefix: appPrefix }); } // Inscription des tâches dans la fabrique (gulpfile.js) // on met à jour les tâche "build" et "serve" gulp.task('build', gulp.series('partials', gulp.parallel('inject', 'other'), 'build', 'precache:dist')); gulp.task('serve', gulp.series('inject', 'precache', 'watch', 'browsersync'));
Exclure le fichier de la vérification de code
Cette étape est indispensable pour ne pas bloquer les tâches gulp. Dans mon cas, j'ai donc patché ma tâche scripts
comme suit :
diff --git a/gulp_tasks/scripts.js b/gulp_tasks/scripts.js index f3d2482..5044c2b 100644 --- a/gulp_tasks/scripts.js +++ b/gulp_tasks/scripts.js @@ -1,14 +1,20 @@ const gulp = require('gulp'); const eslint = require('gulp-eslint'); +const filter = require('gulp-filter'); const conf = require('../conf/gulp.conf'); gulp.task('scripts', scripts); function scripts() { + // do not lint the generated service worker + const jsFilter = filter(conf.path.tmp('**/*.js','!sw-app-cache.js'), {restore: true}); + return gulp.src(conf.path.src('**/*.js')) + .pipe(jsFilter) .pipe(eslint()) .pipe(eslint.format()) + .pipe(jsFilter.restore) .pipe(gulp.dest(conf.path.tmp())); }
Utiliser le Service Worker généré
Maintenant que la génération du service worker est en ordre de marche, on doit écrire le code qui le référence pour que le navigateur puisse l'utiliser.
J'ai repris le code de démonstration disponible, auquel j'ai rajouté les directives suivantes pour désactiver les plaintes de eslint (on n'est pas dans le code angular de mon application, donc je me permets de le faire) :
/* eslint default-case: "off", angular/log: "off" */