Недавно я участвовал в AngularAttack 2016 Hackathon и создал Let Me See: приложение, которое помогает людям с потерей зрения увидеть мир. Это приложение было создано с использованием Ionic2 (и, конечно, Angular2). Но больше всего мне хотелось, чтобы приложение было прогрессивным, поэтому я добавил поддержку автономного кэширования - для лучшей мгновенной загрузки. Позвольте мне показать вам, как я просто и быстро добавил, что ...
Ой! Кстати, «Let Me See» выиграла приз за инновации!
Прежде чем мы начнем, я предполагаю, что у вас уже есть существующее веб-приложение. Я собираюсь использовать «Дай мне увидеть» в качестве примера, но шаги, которые мы собираемся пройти вместе, применимы к любому современному одностраничному приложению.
Давайте начнем. Вот структура нашего приложения ...
Как видите, это простое приложение Ionic2 с некоторыми дополнительными файлами конфигурации для Firebase, поскольку приложение размещено на Firebase. Но давайте поговорим об этом в другом сообщении в блоге.
Следует обратить внимание на наличие файла sw-precache-config.json. Этот файл используется инструментом Service Worker Precache (sw-precache).
Tl; Dr: Service Worker Precache позволяет нам предварительно кэшировать все необходимые ресурсы, необходимые оболочке приложения. Он также автоматически генерирует для нас рабочий файл сервера!
Вот как работает инструмент sw-precache…
Во-первых, вы должны решить, хотите ли вы использовать этот инструмент глобально в качестве интерфейса командной строки (CLI):
$ npm install --global sw-precache
И используйте это так:
$ sw-precache --sw-file='www/sw.js' \ --static-file-globs='www/**/*.html'
Или локально с вашей системой сборки:
$ npm install --save-dev sw-precache
И используйте его со своей собственной системой сборки (Gulp, Webpack…).
Затем нам нужно предоставить файл конфигурации: sw-precache-config.json. Вот как он выглядит для нашего приложения «Let Me See»:
{ "swFile": "www/sw.js", "staticFileGlobs": [ "www/manifest.json", "www/**/*.css", "www/**/*.{ttf,woff,woff2,eof}", "www/**/*.js", "www/**/*.html", "www/**/*.{png,jpg,gif,svg,mp3}" ], "handleFetch": true, "stripPrefix": "www/", "cacheId": "let-me-see-v1", "maximumFileSizeToCacheInBytes": 4194304, "ignoreUrlParametersMatching": "[/./]", "verbose": true }
Позвольте мне быстро объяснить некоторые из этих вариантов:
- swFile: путь к файлу сервис-воркера, который будет сгенерирован (эта опция не задокументирована - см. этот файл);
- staticFileGlobs: массив из одного или нескольких строковых шаблонов. Это файлы, которые будут кэшироваться и использоваться в автономном режиме;
- handleFetch: определяет, включен ли обработчик событий fetch в сгенерированный код сервис-воркера;
- cacheId: строка, используемая для различения кешей;
- maximumFileSizeToCacheInBytes: устанавливает максимально допустимый размер файла в списке предварительного кеширования (добро пожаловать);
- stripPrefix: удаляет указанную строку из начала URL-адреса пути во время выполнения.
Вы можете прочитать более подробную документацию по этим параметрам в репозитории github.
Теперь, когда у нас установлен и готов инструмент sw-precache. Нам нужно заставить его работать с нашим приложением. Я предпочитаю использовать sw-precache в качестве задачи Gulp, потому что Ionic2 использует его как систему сборки. Он даже предоставляет хуки, куда вы можете добавлять свои собственные задачи сборки.
Итак, давайте создадим нашу задачу Gulp sw:
gulp.task('sw', function(callback) { var path = require('path'); var swPrecache = require('sw-precache'); var rootDir = 'www'; var options = require('./sw-precache-config.json'); options.ignoreUrlParametersMatching = [/./]; swPrecache.write(path.join(rootDir, 'sw.js'), options, callback); });
Затем мы вызываем нашу задачу после задачи сборки, чтобы инструмент sw-precache мог сгенерировать для нас Server Worker после завершения сборки:
//... gulp.task('build:after', ['sw']); //...
При желании мы также можем запустить задачу sw во время задачи watch. Это означает, что служебный воркер будет автоматически генерироваться каждый раз, когда вы редактируете файл в своем приложении:
gulp.task('watch', ['clean'], function(done){ runSequence( ['sass', 'html', 'fonts', 'scripts'], 'sw', function(){ //...
Я также настоятельно рекомендую вам отключить параметр handleFetch, который в основном отключает событие fetch. В противном случае контент всегда будет обслуживаться из кеша сервис-воркера; и ваша настройка живой перезагрузки может работать не так, как ожидалось.
Вот и все. Вы сделали!
Вы только что добавили автономную поддержку своего веб-приложения. Вы можете увидеть полностью автоматически сгенерированный сервис-воркер для Let Me See здесь, на github.
И последнее, но не менее важное: не забудьте зарегистрировать этого сервис-воркера в своем index.html:
<script> if('serviceWorker' in navigator) { navigator.serviceWorker.register('sw.js'); } </script>
Подпишитесь на @manekinekko, чтобы узнать больше о веб-платформе.