@@ -8,9 +8,14 @@ import type { AsyncRouteComponent } from './route'
8
8
// URL to the lazy module.
9
9
// In that case, we want to attempt one window refresh to get the latest.
10
10
function isModuleNotFoundError ( error : any ) : boolean {
11
+ // chrome: "Failed to fetch dynamically imported module: http://localhost:5173/src/routes/posts.index.tsx?tsr-split"
12
+ // firefox: "error loading dynamically imported module: http://localhost:5173/src/routes/posts.index.tsx?tsr-split"
13
+ // safari: "Importing a module script failed."
14
+ if ( typeof error ?. message !== 'string' ) return false
11
15
return (
12
- typeof error ?. message === 'string' &&
13
- / F a i l e d t o f e t c h d y n a m i c a l l y i m p o r t e d m o d u l e / . test ( error . message )
16
+ error . message . startsWith ( 'Failed to fetch dynamically imported module' ) ||
17
+ error . message . startsWith ( 'error loading dynamically imported module' ) ||
18
+ error . message . startsWith ( 'Importing a module script failed' )
14
19
)
15
20
}
16
21
@@ -46,6 +51,7 @@ export function lazyRouteComponent<
46
51
let loadPromise : Promise < any > | undefined
47
52
let comp : T [ TKey ] | T [ 'default' ]
48
53
let error : any
54
+ let reload : boolean
49
55
50
56
const load = ( ) => {
51
57
if ( typeof document === 'undefined' && ssr ?.( ) === false ) {
@@ -59,7 +65,27 @@ export function lazyRouteComponent<
59
65
comp = res [ exportName ?? 'default' ]
60
66
} )
61
67
. catch ( ( err ) => {
68
+ // We don't want an error thrown from preload in this case, because
69
+ // there's nothing we want to do about module not found during preload.
70
+ // Record the error, the rest is handled during the render path.
62
71
error = err
72
+ if ( isModuleNotFoundError ( error ) ) {
73
+ if (
74
+ error instanceof Error &&
75
+ typeof window !== 'undefined' &&
76
+ typeof sessionStorage !== 'undefined'
77
+ ) {
78
+ // Again, we want to reload one time on module not found error and not enter
79
+ // a reload loop if there is some other issue besides an old deploy.
80
+ // That's why we store our reload attempt in sessionStorage.
81
+ // Use error.message as key because it contains the module path that failed.
82
+ const storageKey = `tanstack_router_reload:${ error . message } `
83
+ if ( ! sessionStorage . getItem ( storageKey ) ) {
84
+ sessionStorage . setItem ( storageKey , '1' )
85
+ reload = true
86
+ }
87
+ }
88
+ }
63
89
} )
64
90
}
65
91
@@ -68,36 +94,13 @@ export function lazyRouteComponent<
68
94
69
95
const lazyComp = function Lazy ( props : any ) {
70
96
// Now that we're out of preload and into actual render path,
71
- // throw the error if it was a module not found error during preload
97
+ if ( reload ) {
98
+ // If it was a module loading error,
99
+ // throw eternal suspense while we wait for window to reload
100
+ window . location . reload ( )
101
+ throw new Promise ( ( ) => { } )
102
+ }
72
103
if ( error ) {
73
- if ( isModuleNotFoundError ( error ) ) {
74
- // We don't want an error thrown from preload in this case, because
75
- // there's nothing we want to do about module not found during preload.
76
- // Record the error, recover the promise with a null return,
77
- // and we will attempt module not found resolution during the render path.
78
-
79
- if (
80
- error instanceof Error &&
81
- typeof window !== 'undefined' &&
82
- typeof sessionStorage !== 'undefined'
83
- ) {
84
- // Again, we want to reload one time on module not found error and not enter
85
- // a reload loop if there is some other issue besides an old deploy.
86
- // That's why we store our reload attempt in sessionStorage.
87
- // Use error.message as key because it contains the module path that failed.
88
- const storageKey = `tanstack_router_reload:${ error . message } `
89
- if ( ! sessionStorage . getItem ( storageKey ) ) {
90
- sessionStorage . setItem ( storageKey , '1' )
91
- window . location . reload ( )
92
-
93
- // Return empty component while we wait for window to reload
94
- return {
95
- default : ( ) => null ,
96
- }
97
- }
98
- }
99
- }
100
-
101
104
// Otherwise, just throw the error
102
105
throw error
103
106
}
0 commit comments