Ответ 1
Кажется, это хорошо известная ошибка в сервис-сервисе Angular, и мы можем ожидать исправления/рабочей версии в какой-то момент. Большую информацию можно найти в выпуске 25611, поскольку шобхит вайш уже указан.
Однако, если вы ищете решение сейчас или собираетесь использовать более старую версию Angular 7/8, которая, возможно, не будет исправлена в ближайшее время, я постараюсь подытожить известные на данный момент обходные пути. (Также они не могут быть квалифицированы как "правильное решение"...)
Исправление ngsw-worker.js
Вы можете исправить ваш файл ngsw-worker.js
либо после вашего ng run app:build:production
, где он обычно будет находиться в папке www
внутри вашего проекта (если вы не изменили Angular outputPath
). Или вы можете установить его перед сборкой внутри node_modules/@angular/service-worker
.
В зависимости от того, как часто вы создаете свое приложение, вы можете сделать это просто вручную (то есть с помощью текстового редактора на ваш выбор) или написать сценарий, например, с помощью sed.
Теперь у вас есть два варианта:
1. Исправление handleMessage()
Поиск по
handleMessage(msg, from) {
return __awaiter$5(this, void 0, void 0, function* () {
И замените его на
handleMessage(msg, from) {
return __awaiter$5(this, void 0, void 0, function* () {
if (this.initialized === null) {
this.initialized = this.initialize();
}
try {
yield this.initialized;
}
catch (e) {
this.state = DriverReadyState.SAFE_MODE;
this.stateMessage = 'Initialization failed due to handleMessage() error: ${errorToString(e)}';
}
В зависимости от вашей версии @angular/service-worker
подпись handleMessage()
может выглядеть для вас по-разному, и вы могли бы написать более сложный catch
, но, надеюсь, в любом случае он никогда не достигнет блока catch
.
Этот патч в основном соответствует тому, что предложено в комментарии gkalpak, и, скорее всего, официальное исправление также будет примерно таким.
2. Исправление initialize()
Поиск по
try {
// Read them from the DB simultaneously.
[manifests, assignments, latest] = yield Promise.all([
table.read('manifests'),
table.read('assignments'),
table.read('latest'),
]);
И замените его на
try {
// Read them from the DB simultaneously.
[manifests, assignments, latest] = yield Promise.all([
table.read('manifests'),
table.read('assignments'),
table.read('latest'),
]);
if (latest.latest === null) throw new Error('Error latest.latest is null for what ever reason...');
Тем самым вы убедитесь, что блок catch
в initialize()
действительно будет работать и не позволит работнику сервиса войти в SAFE_MODE
. Однако это может быть не так надежно, как в первом патче, но также может работать для сервисных работников, которые уже находятся в SAFE_MODE
из-за этой проблемы. Это было предложено в комментарии hsta.
Обойти проблему в приложении Angular
Если вы не хотите возиться с ngsw-worker.js
, вы можете попытаться определить состояние работника сервиса, выбрав your-app.domain/ngsw/state
из вашего приложения Angular и если он находится в SAFE_MODE
(можно проверить, например, с помощью простой поиск regex
) вы можете попытаться сбросить его, удалив все элементы из кеш-хранилища и затем отменив регистрацию работника сервиса. Идея этого была предложена в комментарии mattlewis92 и одобрена как вероятный рабочий взлом в комментарии gkalpak.
Временное решение проблемы вручную
Как shobhit vaish уже выяснилось, вы также можете решить проблему вручную. Помимо возможности, о которой уже говорилось в исходном сообщении, вы также можете сделать это в инструментах разработки браузера на основе Chrome в разделе "Приложение" → "Очистить хранилище", выбрав "Отменить регистрацию сервисных работников" и нажав "Очистить данные сайта". Очевидно, что проблема может и, вероятно, вернется в будущих обновлениях и не сильно поможет обычным пользователям. Но это может быть удобно, если вы, как разработчик, просто хотите быстро решить эту проблему.