Sunday 31 October 2021

Angular Uncaught (in promise): ChunkLoadError: Loading chunk XXXfailed

I am using angular 12, and I use Service Worker to deploy new versions.

It looks like each time I deploy a new version to production (and for some reason not on staging). Some user receive a bunch of error like

Uncaught (in promise): ChunkLoadError: Loading chunk XXX failed.

There is quite some post about this issue, but it appear to me the solution is case by case.

The difference I have in production compare to stg is just.

I call enableProdMode();

I have the service worker setup like this :

    ServiceWorkerModule.register('ngsw-worker.js', {
      enabled:
        environment.env === Environment.PRODUCTION || environment.env === Environment.STAGING,
      registrationStrategy: 'registerWhenStable:30000',
    }),

And My Config looks like

{
  "$schema": "../../node_modules/@angular/service-worker/config/schema.json",
  "index": "/index.html",
  "assetGroups": [
    {
      "name": "app",
      "installMode": "prefetch",
      "resources": {
        "files": ["/favicon.ico", "/index.html", "/manifest.webmanifest", "/*.css", "/*.js"]
      }
    },
    {
      "name": "assets",
      "installMode": "lazy",
      "updateMode": "lazy",
      "resources": {
        "files": ["/assets/**", "/*.(eot|svg|cur|jpg|png|webp|gif|otf|ttf|woff|woff2|ani)"]
      }
    }
  ]
}

And this is how I show the updates (basically a banner that can be ignored) :

@Component({
  selector: 'app-live-update-notifier',
  templateUrl: './live-update-notifier.component.html',
  styleUrls: ['./live-update-notifier.component.scss'],
})
export class LiveUpdateNotifierComponent implements OnDestroy {
  hasUpdate = false;
  isIgnored = false;

  private subscription = new SubSink();

  constructor(
    @Inject(DOCUMENT) private document: Document,
    private swUpdate: SwUpdate,
    private appRef: ApplicationRef,
    private changeDetectorRef: ChangeDetectorRef
  ) {
    const appIsStable$ = this.appRef.isStable.pipe(first((isStable) => isStable === true));
    const everySixHours$ = interval(6 * 60 * 60 * 1000);
    const everySixHoursOnceAppIsStable$ = concat(appIsStable$, everySixHours$);

    if (swUpdate.isEnabled) {
      this.subscription.add(
        everySixHoursOnceAppIsStable$.subscribe(() => swUpdate.checkForUpdate()),
        this.swUpdate.available.subscribe((evt) => {
          if (evt.type === 'UPDATE_AVAILABLE') {
            this.hasUpdate = true;
            this.changeDetectorRef.detectChanges();
          }
        })
      );
    }
  }

  ngOnDestroy(): void {
    this.subscription.unsubscribe();
  }

  updateApp() {
    this.document.location.reload();
  }

  skipNotification() {
    this.isIgnored = true;
  }
}

If you have any clue that could guide to the solution, thank you.

EDIT :

I have a bunch of lazy loaded module all across my app. I thought the reason was that some module where not loaded previous to a new version, and when user navigate to them after deploy they would have this chunk problem. But I tried to do emulate this issue by

  • editing module A and B
  • deploy
  • navigate to module A
  • editing module A and B
  • deploy
  • navigate to old module B from old A, so without updating the version of the APP RES : old B still load normally

so I don't think it s this issue



from Angular Uncaught (in promise): ChunkLoadError: Loading chunk XXXfailed

No comments:

Post a Comment