typescript - Hvordan leser du versjonshashen til den nåværende PWA-en i Angular?


Jeg skulle ønske jeg kunne lese den nåværende aktive hashen til min Angular PWA. Men jeg kan ikke se noen mekanisme for å gjøre det.

SwUpdate-objektet gir observables som lar deg lese den nåværende versjonens hash når en ny versjon aktiveres eller når den blir tilgjengelig, men ser ikke ut til å eksponere noen statisk metode for å få hashen til den nåværende versjonen.

class SwUpdate {
  available: Observable<UpdateAvailableEvent>
  activated: Observable<UpdateActivatedEvent>
  unrecoverable: Observable<UnrecoverableStateEvent>
  isEnabled: boolean
  checkForUpdate(): Promise<void>
  activateUpdate(): Promise<void>
}

Jeg skulle ønske jeg kunne lese noe som SwUpdate.current for å lese den nåværende hash-verdien (si a518f9f1ab65954c2eafa02fec134fa54b391651) uten å måtte vente på en available eller activated hendelse. Er dette mulig?

Tillegg

Jeg løste aldri dette ved å bruke den offisielle ruten. Løsningen jeg endte opp med å bruke var å skrive min egen hash-versjon for appen under CI-byggprosessen. Jeg la det i en JSON-fil i appen som appen kunne laste selv og deretter bruke det som hash for app-versjonen i stedet for den angular-genererte hashen. I praksis har dette fungert fint.

Svar #1

Du kan bruke SwUpdate fra @angular/service-worker for å gjøre det. For eksempel kan du sjekke det i app.component.ts slik:

import { Component, OnInit } from '@angular/core';
import { SwUpdate } from '@angular/service-worker';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss'],
})
export class AppComponent implements OnInit {

  constructor(private swUpdate: SwUpdate) {}

  checkForUpdate() {
    if (this.swUpdate.isEnabled) {
      this.swUpdate.available.subscribe((event) => {
        console.log('Update is available!');
        console.log('Current version: ' + event.current.hash);
        console.log('New available version: ' + event.available.hash);
      });
    }
  }

  ngOnInit() {
    this.checkForUpdate();
  }
}

Svar #2

Jeg hadde det samme problemet og kunne ikke finne et svar noe sted på internett. Jeg kan fortsatt ikke forstå hvorfor Angular ikke gir denne informasjonen direkte. Så jeg begynte å eksperimentere til jeg fant noe som kanskje fungerer. Applikasjonsinformasjonen og dens versjoner er lagret i cachen:

Spesifikt finnes hashen til den sist lagrede versjonen på /latest-stien, og den kan hentes på denne måten:

caches.open('ngsw:/:db:control').then((cache) => {
  cache.match('/latest').then((res) => {
    res?.json().then((body) => {
      console.log(body.latest)
    }
  }
}

Jeg var også interessert i å få versjonsdatoen, så jeg så inni manifestet til den versjonen, og for å unngå at det spredte seg som et løfte, konverterte jeg det til et observabelt med "from"-operatoren fra rxjs:

    import { from } from 'rxjs';

    getAppVersion() {
        return from(
          caches.open('ngsw:/:db:control').then((cache) => {
            return cache.match('/latest').then((resLts) => {
              return resLts?.json().then((bodyLts) => {
                return cache.match('/manifests').then((resManifests) => {
                  return resManifests?.json().then((manifests) => {
                    return {
                      hash: bodyLts.latest,
                      timestamp: manifests[bodyLts.latest].timestamp,
                    };
                  });
                });
              });
            });
          })
        );
      }

Dette er så langt jeg har kommet, og jeg er fornøyd med resultatet, selv om det har problemet at ved første lasting av nettstedet eksisterer ikke cachen ennå, og det vil ikke returnere noe. Kanskje periodiske spørringer kan gjøres til informasjonen blir funnet, men jeg er ikke sikker på om det vil fungere.

Et annet problem jeg ser er at dette kan være en midlertidig løsning siden det ikke finnes noe offisielt i Angular-dokumentasjonen som indikerer at disse hurtigbufrede rutene vil forbli de samme.

Vel, selv om dette spørsmålet allerede er flere år gammelt, tenkte jeg det var viktig å dele det i tilfelle det er nyttig for noen andre.

Relaterte artikler