5

We are using Lazy Loading for Router Modules.

  {
    path: 'users',
    loadChildren: 'app/users/users.module#UsersModule',
  },

But when we update version of our app (upload new bundle to the server) it's always broken: old app (that user has already downloaded) tries to get old chunk file that is not on the server anymore.

Live example: https://alexshakura.github.io/chunk-error/ (I've just rename the chunk to highlight the error)

What is the correct way to handle this error?


Let me describes the steps:

  1. AppVersion1 is loaded by a user (without lazy loaded chunks)
  2. We updated the app and uploaded bundle to the server (so currently AppVersion2 is correct one)
  3. User (who still has AppVersion1) goes to route that loads lazy module, BUT it tries to load chunk from AppVersion1 that does not exist anymore.
10
  • What error? You didn't post one and it isn't clear what you mean by update. Are you saying that if you recompile and upload that the chunk file is missing? Or that the manifest isn't pointing to the newest version? Commented Mar 6, 2018 at 16:09
  • sorry for being not clear enough. http error of trying to get file (chunk) that does not exist any more (new file has new hash suffix). I'll update question with preview in a bit Commented Mar 6, 2018 at 16:10
  • Have you actually verified that the chunk is on the server post upload? And then have you verified that your manifest matches the supposed chunk? This seems to be a deployment issue based on what you've described so far. Commented Mar 6, 2018 at 16:11
  • 1
    no, it's outdated application on client side tries to load chunk by old path Commented Mar 6, 2018 at 16:12
  • 1
    yes, custom error handler could be the answer, I just want to check, maybe there is a more precise solution: preloading strategy, interceptor, a routing error Commented Mar 7, 2018 at 9:01

2 Answers 2

5
+50

You can try using the ng service worker to do this for you.

The service worker will have its own manifest that will enable the worker to keep track of app versions and cached assets. Every time a user reloads the page, the cached version of the app will be served. Then, in background, the service worker will fetch the current manifest, parse it and if there is a version change, it will cache the new app version in the background. The next user's reload will display the new version of the app.

You can enable the service worker functionality by putting "serviceWorker": true to your .angular-cli.json into your app section.

Then create a ngsw-config.json file in your src dir. The defaults should look like this:

{
  "index": "/index.html",
  "assetGroups": [{
    "name": "app",
    "installMode": "prefetch",
    "resources": {
      "files": [
        "/favicon.ico",
        "/index.html"
      ],
      "versionedFiles": [
        "/*.bundle.css",
        "/*.bundle.js",
        "/*.chunk.js"
      ]
    }
  }, {
    "name": "assets",
    "installMode": "lazy",
    "updateMode": "prefetch",
    "resources": {
      "files": [
        "/assets/**"
      ]
    }
  }]
}

And finally, put NGSW module initialization into your app.module:

@NgModule({
  // ...
  imports: [
    // ...
    ServiceWorkerModule.register('/ngsw-worker.js', { enabled: environment.production })
  ]
})
export class AppModule {}

Running ng build --prod will provide all the rest for you.

You can find more about service workers in the official docs.

Sign up to request clarification or add additional context in comments.

Comments

0

Update for 2021.

I had the same issueas OP, but I solved it by making it the app a PWA, according to @Heehaaw's tips.

However, I would not recommend @Heehaaws approach for making it an Angular PWA. Instead one should follow Angulars official guide https://angular.io/guide/service-worker-getting-started

Run this command inside your project, or follow the guide above.

ng add @angular/pwa

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.