@@ -150,14 +150,42 @@ async function loadDynamicComponent(
150150
151151/**
152152 * Resolve a component path to an async component.
153- * First tries the build-time glob, then falls back to runtime loading.
154- * CSS injection only happens for runtime-loaded modules (static modules use Vite's built-in CSS handling).
153+ *
154+ * In production, always uses manifest-based loading from the module's own build.
155+ * The build-time glob creates chunks in the main app's output with different content
156+ * hashes than the module's independent build, causing 404s when builds are out of sync.
157+ *
158+ * In development, tries the build-time glob first (HMR support), then falls back
159+ * to runtime loading.
155160 */
156161function resolveComponent ( module : string , componentPath : string ) : Component | null {
157- // Build the glob path: ../../../modules/{module}/resources/js/{componentPath}
158- const globPath = `../../../modules/${ module } /resources/js/${ componentPath } ` ;
162+ // In production, always use manifest-based loading from the module's own build.
163+ if ( ! import . meta. env . DEV ) {
164+ return defineAsyncComponent ( {
165+ loader : async ( ) => {
166+ const result = await loadDynamicComponent ( module , componentPath ) ;
167+ if ( ! result ) {
168+ throw new Error ( `Component not found: ${ module } /${ componentPath } ` ) ;
169+ }
170+ void injectModuleStyles ( module ) ;
171+ return result ;
172+ } ,
173+ delay : 0 ,
174+ timeout : 15000 ,
175+ onError : ( error , _retry , fail , attempts ) => {
176+ console . error (
177+ `[ModuleSlots] Failed to load component (attempt ${ attempts } ):` ,
178+ `\n Module: ${ module } ` ,
179+ `\n Component: ${ componentPath } ` ,
180+ `\n Error: ${ error instanceof Error ? error . message : error } ` ,
181+ ) ;
182+ fail ( ) ;
183+ } ,
184+ } ) ;
185+ }
159186
160- // Try build-time glob first (fastest, for modules present at build time)
187+ // Development: try build-time glob first (fastest, HMR support)
188+ const globPath = `../../../modules/${ module } /resources/js/${ componentPath } ` ;
161189 const staticLoader = moduleComponents [ globPath ] ;
162190 if ( staticLoader ) {
163191 return defineAsyncComponent ( {
@@ -177,19 +205,18 @@ function resolveComponent(module: string, componentPath: string): Component | nu
177205 } ) ;
178206 }
179207
180- // Fallback: try runtime dynamic loading for modules installed after build
208+ // Development fallback: runtime dynamic loading
181209 return defineAsyncComponent ( {
182210 loader : async ( ) => {
183211 const result = await loadDynamicComponent ( module , componentPath ) ;
184212 if ( ! result ) {
185213 throw new Error ( `Component not found: ${ module } /${ componentPath } ` ) ;
186214 }
187- // Inject CSS only for runtime-loaded modules (manifest already cached by loadDynamicComponent)
188215 void injectModuleStyles ( module ) ;
189216 return result ;
190217 } ,
191218 delay : 0 ,
192- timeout : 15000 , // Slightly longer timeout for network requests
219+ timeout : 15000 ,
193220 onError : ( error , _retry , fail , attempts ) => {
194221 console . error (
195222 `[ModuleSlots] Failed to load dynamic component (attempt ${ attempts } ):` ,
0 commit comments