Как обрабатывать маршрутизацию в Угловых 5+ сервисных рабочих?

В предыдущих версиях реализации "Угловой сервис" одним из вариантов конфигурации была "routing". Это можно увидеть в этом безответном вопросе SO, на который ссылается в этой проблеме с угловым CLI, и лучшая оставшаяся документация, похоже, является записью в блоге Стивеном Флюином (в команде Angular), а также беседой I/O от Alex Rickabaugh (от Google).

С угловым 5 ServiceWorkerModule был хорошо продуман, и теперь большинство настроек можно обрабатывать с помощью ngsw-config.json. Тем не менее, больше не упоминается, как обрабатывать перенаправление для маршрутов, в любом месте в руководстве по углу.io, или в документации. Поэтому я столкнулся со следующей проблемой: когда я посетил мое приложение и перешел в автономный режим, я все равно могу получить доступ к приложению при его непосредственном посещении: https://jackkoppa.github.io/cityaq-sw-issue. Однако при загрузке приложение перенаправляется на маршрут search, и большинство пользователей будут пытаться загрузить с URL-адреса, например https://jackkoppa.github.io/cityaq-sw-issue/search?cities=Shanghai (для простоты, я "Я просто говорю о настольном и мобильном устройствах Chrome на данный момент и в Incognito, когда это возможно".

Когда вы пытаетесь посетить этот URL-адрес в автономном режиме, вы сразу получаете 504 - Gateway Timeout. Это происходит потому, что сервисный работник только кэшировал индекс и не знает, что другие маршруты должны перенаправляться на индекс, чтобы он мог загружаться. Я уверен, что предыдущие итерации работы "Угловой сервис" могли бы обработать этот сценарий, настроив переадресацию на индекс для заданных маршрутов. Есть ли способ справиться с этим перенаправлением в текущем, угловом 5+ ngsw-config.json или в сгенерированном файле ngsw.json? Если это не так, как следует обходиться в отдельном JS файле служебного работника?

Ответ 1

TL; DR: Я определил по крайней мере две проблемы, вызвавшие поломку в моем случае; вы можете использовать этот скрипт сборки, чтобы попробовать мои исправления и посмотреть, как приложение работает в автономном режиме здесь. Требуются дополнительные тесты и запросы на тяну.


Хотя мне не удалось найти документальный ответ, вот что мне удалось найти, ngsw-worker.js файл ngsw-worker.js, а также прочитав историю фиксации @angular/service-worker.

Новый подход ServiceWorkerModule к "маршрутизации" заключается в том, чтобы выполнить любой запрос "навигации" (т.е. handleFetch маршрут в том же домене) и повторно запустить метод handleFetch, но теперь указывая на запрос index.html (источник). Это должно работать нормально, учитывая, что SPA должен иметь возможность перенаправлять URL-адрес после того, как он восстановил свои кешированные файлы для индекса.

Поэтому проблемы, которые приводят к сбою моего сайта выше, когда он отключен, не должны быть напрямую связаны с маршрутизацией, и я нашел 2 до сих пор. Исправление их с помощью обходного пути позволило мне заставить мое приложение работать в основном, как и ожидалось. С этапами репликации в исходном вопросе cityaq теперь работает, а я воспроизвел оригинальный, неудачный сайт в cityaq-sw-issue.

Проблемы:

  1. Hosted версии Angular app, где флаг --base-href устанавливается из CLI, перечисляет абсолютные URL-адреса для ресурсов их сервис-работников. При сравнении запросов с этими ресурсами ngsw-worker.js ожидает относительных URL-адресов

    • источник
    • Я уверен, что эта проблема должна быть решена, и я буду работать над запросом на перенос, чтобы исправить это. Это происходит потому, что baseHref становится включенным в URL ресурсов, когда генерируется ngsw.json (источник)
  2. Из 3 доступных "состояний", с ngsw-worker.js может работать ngsw-worker.js, по моему опыту, EXISTING_CLIENTS_ONLY кажется, поставлено неверно.

    • источник 1, источник 2
    • Я менее уверен в этом изменении, потому что я не смог последовательно понять, что вызывает это состояние. Однако, если &, когда рабочий-сервис входит в это состояние, ngsw-worker.js больше не будет пытаться извлекать кешированные ресурсы (источник), а в моем тестировании под ngsw-worker.js "правильными" обстоятельствами приложение все равно входит в это состояние даже когда единственное изменение - это удаление интернет-соединения

В то время как я собрал PR для проблемы № 1 и дождался некоторой помощи в понимании проблемы №2, я использую скрипт сборки для обхода, чтобы изменить ngsw-worker.js после его создания. Предупреждение: оно уродливо и определенно изменяет предполагаемое "безопасное" поведение установки EXISTING_CLIENTS_ONLY. Однако для моего приложения он позволяет корректно выполнять автономную работу при запуске локально (http-server) и развертывании в реальном URL (страницы GitHub, в моем случае).

Чтобы использовать обходной путь: (Угловой 5, проверенный с Угловым 5.2.1)

  1. npm install replace-in-file --save-dev
  2. Включите этот скрипт в свое приложение, например, в build/fix-sw.js
  3. В вашем package.json:
"scripts": {
   ...
   "sw-build": "ng build --prod && node build/fix-sw",
   "sw-build-live": ng build --prod --base-href https://your-url.com/ && node build/fix-sw"
   ...
}
  1. Запуск локально

npm run sw-build
cd dist
http-server -p 8080
  1. И чтобы подготовить сборку для вашего живого URL-адреса, перед отправкой на сервер (например, с помощью угловых-cli-ghpages)

npm run sw-build-live