@@ -293,10 +293,38 @@ async function executeAppLocalNode({
293293 // Ensure frontend dependencies are installed
294294 try {
295295 logger . info ( `Ensuring frontend dependencies are installed in ${ frontendPath } ` ) ;
296- await installDependencies ( frontendPath , "nodejs" ) ;
296+
297+ // Check if node_modules exists and has basic packages
298+ const hasNodeModules = fs . existsSync ( path . join ( frontendPath , "node_modules" ) ) ;
299+ const hasVite = hasNodeModules && fs . existsSync ( path . join ( frontendPath , "node_modules" , "vite" ) ) ;
300+
301+ if ( ! hasVite ) {
302+ logger . info ( `Frontend dependencies not found or incomplete, installing...` ) ;
303+ await installDependencies ( frontendPath , "nodejs" ) ;
304+
305+ // Double-check that vite was installed
306+ const viteInstalled = fs . existsSync ( path . join ( frontendPath , "node_modules" , "vite" ) ) ;
307+ if ( ! viteInstalled ) {
308+ logger . error ( `Failed to install vite dependency in ${ frontendPath } ` ) ;
309+ safeSend ( event . sender , "app:output" , {
310+ type : "stdout" ,
311+ message : `❌ Failed to install frontend dependencies. Please run 'npm install' manually in the frontend directory.` ,
312+ appId,
313+ } ) ;
314+ return ;
315+ }
316+ logger . info ( `Frontend dependencies installed successfully` ) ;
317+ } else {
318+ logger . info ( `Frontend dependencies already installed, skipping installation` ) ;
319+ }
297320 } catch ( error ) {
298- logger . warn ( `Failed to install frontend dependencies: ${ error } ` ) ;
299- // Continue anyway - the dev server might still work
321+ logger . error ( `Failed to install frontend dependencies: ${ error } ` ) ;
322+ safeSend ( event . sender , "app:output" , {
323+ type : "stdout" ,
324+ message : `❌ Failed to install frontend dependencies: ${ error instanceof Error ? error . message : String ( error ) } . Please run 'npm install' manually in the frontend directory.` ,
325+ appId,
326+ } ) ;
327+ return ;
300328 }
301329
302330 // Determine backend framework for proper server command
@@ -370,6 +398,17 @@ async function executeAppLocalNode({
370398
371399 // Start frontend server
372400 try {
401+ // Double-check that we have the necessary dependencies before starting
402+ const viteAvailable = fs . existsSync ( path . join ( frontendPath , "node_modules" , "vite" ) ) ;
403+ if ( ! viteAvailable ) {
404+ safeSend ( event . sender , "app:output" , {
405+ type : "stdout" ,
406+ message : `❌ Cannot start frontend server: vite package not found. Please ensure dependencies are installed.` ,
407+ appId,
408+ } ) ;
409+ return ;
410+ }
411+
373412 const frontendCommand = `npx vite --port ${ frontendPort } --host` ;
374413 const frontendProcess = spawn ( frontendCommand , [ ] , {
375414 cwd : frontendPath ,
@@ -435,6 +474,26 @@ async function executeAppLocalNode({
435474 workingDir = frontendPath ;
436475 serverPort = await findAvailablePort ( 32100 ) ;
437476 modeMessage = `Running in frontend mode - Starting frontend server on port ${ serverPort } ...` ;
477+
478+ // Ensure frontend dependencies are installed for frontend-only apps
479+ try {
480+ logger . info ( `Ensuring frontend dependencies are installed in ${ frontendPath } ` ) ;
481+ const hasNodeModules = fs . existsSync ( path . join ( frontendPath , "node_modules" ) ) ;
482+ const hasVite = hasNodeModules && fs . existsSync ( path . join ( frontendPath , "node_modules" , "vite" ) ) ;
483+
484+ if ( ! hasVite ) {
485+ logger . info ( `Frontend dependencies not found or incomplete, installing...` ) ;
486+ await installDependencies ( frontendPath , "nodejs" ) ;
487+ }
488+ } catch ( error ) {
489+ logger . error ( `Failed to install frontend dependencies: ${ error } ` ) ;
490+ safeSend ( event . sender , "app:output" , {
491+ type : "stdout" ,
492+ message : `❌ Failed to install frontend dependencies: ${ error instanceof Error ? error . message : String ( error ) } . Please run 'npm install' manually in the frontend directory.` ,
493+ appId,
494+ } ) ;
495+ return ;
496+ }
438497 } else if ( hasBackend && ! hasFrontend ) {
439498 // Only backend exists (backend-only app)
440499 workingDir = backendPath ;
@@ -448,6 +507,26 @@ async function executeAppLocalNode({
448507 workingDir = frontendPath ;
449508 serverPort = await findAvailablePort ( 32100 ) ;
450509 modeMessage = `Running in frontend mode - Starting frontend server on port ${ serverPort } ...` ;
510+
511+ // Ensure frontend dependencies are installed for frontend apps
512+ try {
513+ logger . info ( `Ensuring frontend dependencies are installed in ${ frontendPath } ` ) ;
514+ const hasNodeModules = fs . existsSync ( path . join ( frontendPath , "node_modules" ) ) ;
515+ const hasVite = hasNodeModules && fs . existsSync ( path . join ( frontendPath , "node_modules" , "vite" ) ) ;
516+
517+ if ( ! hasVite ) {
518+ logger . info ( `Frontend dependencies not found or incomplete, installing...` ) ;
519+ await installDependencies ( frontendPath , "nodejs" ) ;
520+ }
521+ } catch ( error ) {
522+ logger . error ( `Failed to install frontend dependencies: ${ error } ` ) ;
523+ safeSend ( event . sender , "app:output" , {
524+ type : "stdout" ,
525+ message : `❌ Failed to install frontend dependencies: ${ error instanceof Error ? error . message : String ( error ) } . Please run 'npm install' manually in the frontend directory.` ,
526+ appId,
527+ } ) ;
528+ return ;
529+ }
451530 } else if ( hasBackend ) {
452531 // Only backend exists
453532 workingDir = backendPath ;
@@ -470,6 +549,16 @@ async function executeAppLocalNode({
470549
471550 // For frontend, override with dynamic port and host binding for proxy access
472551 if ( workingDir === frontendPath && serverPort > 0 ) {
552+ // Double-check that we have the necessary dependencies before starting
553+ const viteAvailable = fs . existsSync ( path . join ( frontendPath , "node_modules" , "vite" ) ) ;
554+ if ( ! viteAvailable ) {
555+ safeSend ( event . sender , "app:output" , {
556+ type : "stdout" ,
557+ message : `❌ Cannot start frontend server: vite package not found. Please ensure dependencies are installed.` ,
558+ appId,
559+ } ) ;
560+ return ;
561+ }
473562 command = `npx vite --port ${ serverPort } --host` ;
474563 }
475564
@@ -2301,17 +2390,16 @@ async function installDependencies(projectPath: string, framework: string) {
23012390 logger . info ( `Successfully installed dependencies for ${ framework } ` ) ;
23022391 resolve ( ) ;
23032392 } else {
2304- logger . warn ( `Dependency installation failed for ${ framework } (code: ${ code } ): ${ installError } ` ) ;
2305- // Don't reject here - we want to continue even if installation fails
2306- // as the framework files are still created and user can install manually
2307- resolve ( ) ;
2393+ const errorMsg = `Dependency installation failed for ${ framework } (code: ${ code } ): ${ installError } ` ;
2394+ logger . error ( errorMsg ) ;
2395+ reject ( new Error ( errorMsg ) ) ;
23082396 }
23092397 } ) ;
23102398
23112399 installProcess . on ( "error" , ( err ) => {
2312- logger . error ( `Failed to start dependency installation for ${ framework } :` , err ) ;
2313- // Don't reject here for the same reason as above
2314- resolve ( ) ;
2400+ const errorMsg = `Failed to start dependency installation for ${ framework } : ${ err . message } ` ;
2401+ logger . error ( errorMsg ) ;
2402+ reject ( new Error ( errorMsg ) ) ;
23152403 } ) ;
23162404 } ) ;
23172405}
0 commit comments