@tanstack/vue-router
Version:
Modern and scalable routing for Vue applications
74 lines (73 loc) • 2.6 kB
JavaScript
import { ClientOnly } from "./ClientOnly.js";
import { Outlet } from "./Match.js";
import * as Vue from "vue";
//#region src/lazyRouteComponent.tsx
function isModuleNotFoundError(error) {
if (typeof error?.message !== "string") return false;
return error.message.startsWith("Failed to fetch dynamically imported module") || error.message.startsWith("error loading dynamically imported module") || error.message.startsWith("Importing a module script failed");
}
function lazyRouteComponent(importer, exportName, ssr) {
let loadPromise;
let comp = null;
let error = null;
let attemptedReload = false;
const load = () => {
if (typeof document === "undefined" && ssr?.() === false) {
comp = () => null;
return Promise.resolve(comp);
}
if (!loadPromise) loadPromise = importer().then((res) => {
loadPromise = void 0;
comp = res[exportName ?? "default"];
return comp;
}).catch((err) => {
error = err;
loadPromise = void 0;
if (isModuleNotFoundError(error)) return null;
throw err;
});
return loadPromise;
};
const lazyComp = Vue.defineComponent({
name: "LazyRouteComponent",
setup(props) {
const component = Vue.shallowRef(comp ? Vue.markRaw(comp) : comp);
const errorState = Vue.ref(error);
const loading = Vue.ref(!component.value && !errorState.value);
Vue.onMounted(() => {
if (!component.value && !errorState.value) {
loading.value = true;
load().then((result) => {
component.value = result ? Vue.markRaw(result) : result;
loading.value = false;
}).catch((err) => {
errorState.value = err;
loading.value = false;
});
}
});
if (errorState.value && isModuleNotFoundError(errorState.value) && !attemptedReload) {
if (typeof window !== "undefined" && typeof sessionStorage !== "undefined") {
const storageKey = `tanstack_router_reload:${errorState.value.message}`;
if (!sessionStorage.getItem(storageKey)) {
sessionStorage.setItem(storageKey, "1");
attemptedReload = true;
window.location.reload();
return () => null;
}
}
}
if (errorState.value && !isModuleNotFoundError(errorState.value)) throw errorState.value;
return () => {
if (loading.value || !component.value) return Vue.h("div", null);
if (ssr?.() === false) return Vue.h(ClientOnly, { fallback: Vue.h(Outlet) }, { default: () => Vue.h(component.value, props) });
return Vue.h(component.value, props);
};
}
});
lazyComp.preload = load;
return lazyComp;
}
//#endregion
export { lazyRouteComponent };
//# sourceMappingURL=lazyRouteComponent.js.map