问题
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 a manual refresh always neccessary?
回答1:
I think there are a few ways to circumvent this, since the javascript in the current context isn't aware of the new hash of the content generated by the latest build you could try:
1.) You could try setting up an http redirect on the hashed files: https://developer.mozilla.org/en-US/docs/Web/HTTP/Redirections
The browser will request the old file and the server can point to the new file instead of returning 404. If all of your files follow a convention and only store one of the file at a time ex: component.hash.js
then this should be pretty easy.
2.) A hacky client approach would be handling the transition-rejection in a try catch and reload the page, without the cache to get the new assets. https://developer.mozilla.org/en-US/docs/Web/API/Location/reload
There's always more than one approach, but this is what I could think of to solve the issue.
来源:https://stackoverflow.com/questions/53082866/handle-missing-dynamic-chunks-after-new-deployment-with-webpack