class ReactOnRails::Dev::ServerManager
def run_production_like(_verbose: false, route: nil, rails_env: nil)
def run_production_like(_verbose: false, route: nil, rails_env: nil) procfile = "Procfile.dev-prod-assets" features = [ "Precompiling assets with production optimizations", "Running Rails server on port 3001", "No HMR (Hot Module Replacement)", "CSS extracted to separate files (no FOUC)" ] # NOTE: Pack generation happens automatically during assets:precompile # either via precompile hook or via the configuration.rb adjust_precompile_task print_procfile_info(procfile, route: route) print_server_info( "🏭 Starting production-like development server...", features, 3001, route: route ) # Precompile assets with production webpack optimizations (includes pack generation automatically) env = { "NODE_ENV" => "production" } # Validate and sanitize rails_env to prevent shell injection if rails_env unless rails_env.match?(/\A[a-z0-9_]+\z/i) puts "❌ Invalid rails_env: '#{rails_env}'. Must contain only letters, numbers, and underscores." exit 1 end env["RAILS_ENV"] = rails_env end argv = ["bundle", "exec", "rails", "assets:precompile"] puts "🔨 Precompiling assets with production webpack optimizations..." puts "" puts Rainbow("ℹ️ Asset Precompilation Environment:").blue puts " • NODE_ENV=production → Webpack optimizations (minification, compression)" if rails_env puts " • RAILS_ENV=#{rails_env} → Custom Rails environment for assets:precompile only" puts " • Note: RAILS_ENV=production requires credentials, database setup, etc." puts " • Server processes will use environment from Procfile.dev-prod-assets" else puts " • RAILS_ENV=development → Simpler Rails setup (no credentials needed)" puts " • Use --rails-env=production for assets:precompile step only" puts " • Server processes will use environment from Procfile.dev-prod-assets" puts " • Gets production webpack bundles without production Rails complexity" end puts "" env_display = env.map { |k, v| "#{k}=#{v}" }.join(" ") puts "#{Rainbow('💻 Running:').blue} #{env_display} #{argv.join(' ')}" puts "" # Capture both stdout and stderr require "open3" stdout, stderr, status = Open3.capture3(env, *argv) if status.success? puts "✅ Assets precompiled successfully" ProcessManager.ensure_procfile(procfile) ProcessManager.run_with_process_manager(procfile) else puts "❌ Asset precompilation failed" puts "" # Combine and display all output all_output = [] all_output << stdout unless stdout.empty? all_output << stderr unless stderr.empty? unless all_output.empty? puts Rainbow("📋 Full Command Output:").red.bold puts Rainbow("─" * 60).red all_output.each { |output| puts output } puts Rainbow("─" * 60).red puts "" end puts Rainbow("🛠️ To debug this issue:").yellow.bold command_display = "#{env_display} #{argv.join(' ')}" puts "#{Rainbow('1.').cyan} #{Rainbow('Run the command separately to see detailed output:').white}" puts " #{Rainbow(command_display).cyan}" puts "" puts "#{Rainbow('2.').cyan} #{Rainbow('Add --trace for full stack trace:').white}" puts " #{Rainbow("#{command_display} --trace").cyan}" puts "" puts "#{Rainbow('3.').cyan} #{Rainbow('Or try with development webpack (faster, less optimized):').white}" puts " #{Rainbow('NODE_ENV=development bundle exec rails assets:precompile').cyan}" puts "" puts Rainbow("💡 Common fixes:").yellow.bold # Provide specific guidance based on error content error_content = "#{stderr} #{stdout}".downcase if error_content.include?("secret_key_base") puts "#{Rainbow('•').yellow} #{Rainbow('Missing secret_key_base:').white.bold} " \ "Run #{Rainbow('bin/rails credentials:edit').cyan}" end if error_content.include?("database") || error_content.include?("relation") || error_content.include?("table") puts "#{Rainbow('•').yellow} #{Rainbow('Database issues:').white.bold} " \ "Run #{Rainbow('bin/rails db:create db:migrate').cyan}" end if error_content.include?("gem") || error_content.include?("bundle") || error_content.include?("load error") puts "#{Rainbow('•').yellow} #{Rainbow('Missing dependencies:').white.bold} " \ "Run #{Rainbow('bundle install && npm install').cyan}" end if error_content.include?("webpack") || error_content.include?("module") || error_content.include?("compilation") puts "#{Rainbow('•').yellow} #{Rainbow('Webpack compilation:').white.bold} " \ "Check JavaScript/webpack errors above" end # Always show these general options puts "#{Rainbow('•').yellow} #{Rainbow('Environment config:').white} " \ "Check #{Rainbow('config/environments/production.rb').cyan}" puts "" puts Rainbow("ℹ️ Alternative for development:").blue puts " #{Rainbow('bin/dev static').green} # Static assets without production optimizations" puts "" exit 1 end end