Solution to Loading chunk {n} failed problem in Vue project

  vue-router, vue.js, webpack

Recently, there is an occasional Vue project.Loading chunk {n} failedSome bundle files lazy loading failed after the webpack carried out codespirt. However, the root cause of this problem has not been found, because the chance of this problem is too high, and some mobile phones will appear, some will not, with the simulator will not appear, with the real machine will appear again, don’t know is the network reason or the bug of the webpack. In github, stackoverflow and other places, no reason or solution can be found. This is the discussion on this issue on github:Loading chunk {n} failed #742, although in the end or go away, but you can refer to.

The probability of this problem is relatively small, but once it occurs, it will cause the page to crash, so it still needs to be solved. I will post my solution below:

My idea is to try to capture the error and make fault-tolerant treatment since the cause of the error cannot be found. There are two implementations, one is to capture the error at the server side and the other is to capture it at the front end.

Server side implementation

The reason for reporting the error is that some js bundle have not been found, so when the server receives the request to obtain the js file, it first judges whether the js file exists, if so, it directly returns the js file, if not, it returns a prompt message to the front end for the front end to process. Assuming that the server uses express as the static file server, the code is as follows:

app.all(/\.js$/, (req, res) => {
 const fileName = req.path.slice(req.path.lastIndexOf('/') + 1);
 const filePath = path.resolve(__dirname, './public/static/js/' + fileName);
 if (fs.existsSync(filePath)) {
 fs.sendFile(filePath);
 } else {
 res.setHeader('Content-Type', 'application/javascript;  charset=UTF-8')
 res.setHeader('Accept-Ranges', 'bytes')
 res.setHeader('Vary', 'Accept-Encoding')
 res.setHeader('Transfer-Encoding', 'chunked')
 res.setHeader('Last-Modified', new Date().toUTCString())
 res.setHeader('Cache-Control', 'no-cache')
 res.send('window.serverRebuildHook && window.serverRebuildHook();'  )
 }
 });

When js file is not found, passres.send('window.serverRebuildHook && window.serverRebuildHook();' )Returns a message to the front end and executes theserverRebuildHookMethods.

Then we implement it at the front end.serverRebuildHookMethods:

window.serverRebuildHook = function () {
 Alert ('Server Version Updated, Flushing Local Cache, Please Later ...');
 location.replace(location.href);
 }

The method is very simple, prompt the user server to update and refresh the current page again.

This implementation is a referenceAnswers on github, relatively cumbersome, and the user experience is not good, can only refresh the current page, can’t jump to the target page.

Front-end implementation

Since vue-router and vue-router’s error handling function are used in the projectonErrorIs it possible to catch the error? Let’s look at the description of the official document:

image

An error occurred while attempting to parse an asynchronous component while rendering a route.It completely conforms to our scenario, so in the onError method we implement the following code:

router.onError((error) => {
 const pattern = /Loading chunk (\d)+ failed/g;
 const isChunkLoadFailed = error.message.match(pattern);
 const targetPath = router.history.pending.fullPath;
 if (isChunkLoadFailed) {
 router.replace(targetPath);
 }
 });

When capturedLoading chunk {n} failedWe re-render the target page when the error occurs. This implementation is obviously simpler and more friendly.

After that, if it is found that the causeLoading chunk {n} failedThe essential reason will update this article again, welcome to pay attention!

Thank you for reading. In addition, I’m here to help my friends raise funds for love. I hope everyone can give some love. My friend’s mother is suffering from rectal cancer. She is currently receiving treatment in Beijing Armed Police General Hospital. Please leave a message and leave your contact information. Thank you in the future!

clipboard.png