Skip to content

Instantly share code, notes, and snippets.

@kirandash
Last active November 17, 2022 03:07
Show Gist options
  • Save kirandash/27bfc04fe34537c1a1bd087f3aee4a4a to your computer and use it in GitHub Desktop.
Save kirandash/27bfc04fe34537c1a1bd087f3aee4a4a to your computer and use it in GitHub Desktop.
How to fix ChunkLoadError in your ReactJS application - with typescript
// Inspired from https://www.codemzy.com/blog/fix-chunkloaderror-react
import { ComponentType } from "react";
/**
*
* @param componentImport Dynamic component import
* @param name chunk name to be saved in session storage.
* 🚨 For multiple chunks on same route, set a unique chunk name explicitly to avoid infinite loading
* @returns Promise
*/
export function lazyRetry<T extends ComponentType<any>>(
componentImport: () => Promise<{ default: T }>,
name: string = "chunk",
): Promise<{ default: T }> {
return lazy(() => return new Promise((resolve, reject) => {
// check if window has already refreshed
const hasWindowRefreshed = JSON.parse(
window.sessionStorage.getItem(`retry-${name}-refreshed`) || "false",
);
componentImport()
.then((component) => {
// successfully restored the lazy module
window.sessionStorage.setItem(`retry-${name}-refreshed`, "false");
resolve(component);
})
.catch((error) => {
// if window has not refreshed so far
if (!hasWindowRefreshed) {
window.sessionStorage.setItem(`retry-${name}-refreshed`, "true");
return window.location.reload(); // refresh window
}
reject(error); // default error behaviour to execute since refresh no more required
});
}));
}
const LazyLoaderMyOrder =
lazyRetry(
() => import(/*webpackChunkName: "myorders" */ "pages/myOrders/MyOrders"),
"myorders",
);
import { lazy, ComponentType, LazyExoticComponent } from "react";
/**
*
* @param componentImport Dynamic component import
* @param name chunk name to be saved in session storage.
* 🚨 For multiple chunks on same route, set a unique chunk name explicitly to avoid infinite loading
* @returns Promise
*/
export const lazyRetry = <T extends ComponentType<any>>(
componentImport: () => Promise<{ default: T }>,
name: string = "chunk",
): LazyExoticComponent<ComponentType<any>> =>
lazy(async (): Promise<{ default: T }> => {
// check if window has already refreshed
const hasWindowRefreshed = JSON.parse(
window.sessionStorage.getItem(`retry-${name}-refreshed`) || "false",
);
try {
const component = await componentImport();
// successfully restored the lazy module
window.sessionStorage.setItem(`retry-${name}-refreshed`, "false");
return component;
} catch (error) {
// if window has not refreshed so far
if (!hasWindowRefreshed) {
window.sessionStorage.setItem(`retry-${name}-refreshed`, "true");
// @ts-ignore
return window.location.reload(); // refresh window
}
throw error; // default error behaviour to execute since refresh no more required
}
});
useEffect(() => {
window.addEventListener("error", (e) => {
if (
e.message.includes("Loading chunk") ||
e.message.includes("Loading CSS chunk")
) {
window.location.reload();
}
});
}, []);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment