Friday, 2 November 2018

Handle missing dynamic chunks after new deployment with Webpack

I have an AngularJs (1.7) SPA with Webpack (4.x).

This is how we create chunknames:

  config.output = {
    path: PATHS.build,
    publicPath: '/dist/',
    filename:  `[name]${isDev ? '' : '.[contenthash:8]'}.bundle.js`,
    chunkFilename: `chunks/[name]${isDev ? '' : '.[contenthash:8]'}.chunk.js`
  };

The lazyloading is done in the state definitions in ui-router basically like this:

  $stateProvider
    .state('reports', {
      url: '/projects/:project_id/reports',
      lazyLoad: function($transition$) {
        const injector = $transition$.injector().get('$injector');
        return import(/* webpackChunkName: "admin.reports.module" */ './reports')
          .then(mod => {
            injector.loadNewModules([mod.default]);
          })
          .catch(err => {
            throw new Error('An error occured, ' + err);
          });
      }
    })

After a deployment due changes to a module in a "dynamic" chunk - the filename will change of this chunk ([contenthash] has changed).

When a logged in user (where all bundled assets are loaded before the last deployment) now tries to open a route with the new chunk - the chunk is not there (404) and it will fail with:

Transition Rejection($id: 4 type: 6, message: The transition errored, detail: Error: An error occured, Error: Loading chunk 14 failed.
(error: admin.reports.module.8fc31757.chunk.js))

Is there a common way to circumvent/deal with this?

Maybe more in general: How can changes to a bundled web app be detected? Is there a common way to trigger a reload? Is it a manual refresh always neccessary?



from Handle missing dynamic chunks after new deployment with Webpack

No comments:

Post a Comment