@@ -8,10 +8,10 @@ module ReactOnRails
88  module  Dev 
99    class  ServerManager 
1010      class  << self 
11-         def  start ( mode  =  :development ,  procfile  =  nil ,  verbose : false ,  route : nil ) 
11+         def  start ( mode  =  :development ,  procfile  =  nil ,  verbose : false ,  route : nil ,   rails_env :  nil ) 
1212          case  mode 
1313          when  :production_like 
14-             run_production_like ( _verbose : verbose ,  route : route ) 
14+             run_production_like ( _verbose : verbose ,  route : route ,   rails_env :  rails_env ) 
1515          when  :static 
1616            procfile  ||= "Procfile.dev-static-assets" 
1717            run_static_development ( procfile ,  verbose : verbose ,  route : route ) 
@@ -119,7 +119,7 @@ def show_help
119119        def  run_from_command_line ( args  =  ARGV ) 
120120          require  "optparse" 
121121
122-           options  =  {  route : nil  } 
122+           options  =  {  route : nil ,   rails_env :  nil  } 
123123
124124          OptionParser . new  do  |opts |
125125            opts . banner  =  "Usage: dev [command] [options]" 
@@ -128,6 +128,10 @@ def run_from_command_line(args = ARGV)
128128              options [ :route ]  =  route 
129129            end 
130130
131+             opts . on ( "--rails-env ENV" ,  "Override RAILS_ENV for assets:precompile step only (prod mode only)" )  do  |env |
132+               options [ :rails_env ]  =  env 
133+             end 
134+ 
131135            opts . on ( "-h" ,  "--help" ,  "Prints this help" )  do 
132136              show_help 
133137              exit 
@@ -140,7 +144,7 @@ def run_from_command_line(args = ARGV)
140144          # Main execution 
141145          case  command 
142146          when  "production-assets" ,  "prod" 
143-             start ( :production_like ,  nil ,  verbose : false ,  route : options [ :route ] ) 
147+             start ( :production_like ,  nil ,  verbose : false ,  route : options [ :route ] ,   rails_env :  options [ :rails_env ] ) 
144148          when  "static" 
145149            start ( :static ,  "Procfile.dev-static-assets" ,  verbose : false ,  route : options [ :route ] ) 
146150          when  "kill" 
@@ -182,12 +186,21 @@ def help_commands
182186        end 
183187        # rubocop:enable Metrics/AbcSize 
184188
189+         # rubocop:disable Metrics/AbcSize 
185190        def  help_options 
186191          <<~OPTIONS 
187192            #{ Rainbow ( '⚙️  OPTIONS:' ) . cyan . bold }  
188-               #{ Rainbow ( '--verbose, -v' ) . green . bold } #{ Rainbow ( 'Enable verbose output for pack generation' ) . white }  
193+               #{ Rainbow ( '--route ROUTE' ) . green . bold } #{ Rainbow ( 'Specify route to display in URLs (default: root)' ) . white }  
194+               #{ Rainbow ( '--rails-env ENV' ) . green . bold } #{ Rainbow ( 'Override RAILS_ENV for assets:precompile step only (prod mode only)' ) . white }  
195+               #{ Rainbow ( '--verbose, -v' ) . green . bold } #{ Rainbow ( 'Enable verbose output for pack generation' ) . white }  
196+ 
197+             #{ Rainbow ( '📝 EXAMPLES:' ) . cyan . bold }  
198+               #{ Rainbow ( 'bin/dev prod' ) . green . bold } #{ Rainbow ( '# NODE_ENV=production, RAILS_ENV=development' ) . white }  
199+               #{ Rainbow ( 'bin/dev prod --rails-env=production' ) . green . bold } #{ Rainbow ( '# NODE_ENV=production, RAILS_ENV=production' ) . white }  
200+               #{ Rainbow ( 'bin/dev prod --route=dashboard' ) . green . bold } #{ Rainbow ( '# Custom route in URLs' ) . white }  
189201          OPTIONS 
190202        end 
203+         # rubocop:enable Metrics/AbcSize 
191204
192205        def  help_customization 
193206          <<~CUSTOMIZATION 
@@ -225,17 +238,19 @@ def help_mode_details
225238
226239            #{ Rainbow ( '🏭 Production-assets mode' ) . cyan . bold } #{ Rainbow ( 'Procfile.dev-prod-assets' ) . green }  
227240            #{ Rainbow ( '•' ) . yellow } #{ Rainbow ( 'React on Rails pack generation before Procfile start' ) . white }  
228-             #{ Rainbow ( '•' ) . yellow } #{ Rainbow ( 'Asset precompilation with production optimizations' ) . white }  
229-             #{ Rainbow ( '•' ) . yellow } #{ Rainbow ( 'Optimized, minified bundles' ) . white }  
230-             #{ Rainbow ( '•' ) . yellow } #{ Rainbow ( 'Extracted CSS files (no FOUC)' ) . white }  
241+             #{ Rainbow ( '•' ) . yellow } #{ Rainbow ( 'Asset precompilation with NODE_ENV=production (webpack optimizations)' ) . white }  
242+             #{ Rainbow ( '•' ) . yellow } #{ Rainbow ( 'RAILS_ENV=development by default for assets:precompile (avoids credentials)' ) . white }  
243+             #{ Rainbow ( '•' ) . yellow } #{ Rainbow ( 'Use --rails-env=production for assets:precompile only (not server processes)' ) . white }  
244+             #{ Rainbow ( '•' ) . yellow } #{ Rainbow ( 'Server processes controlled by Procfile.dev-prod-assets environment' ) . white }  
245+             #{ Rainbow ( '•' ) . yellow } #{ Rainbow ( 'Optimized, minified bundles with CSS extraction' ) . white }  
231246            #{ Rainbow ( '•' ) . yellow } #{ Rainbow ( 'No HMR (static assets)' ) . white }  
232-             #{ Rainbow ( '•' ) . yellow } #{ Rainbow ( 'Slower recompilation' ) . white }  
233247            #{ Rainbow ( '•' ) . yellow } #{ Rainbow ( 'Access at:' ) . white } #{ Rainbow ( 'http://localhost:3001/<route>' ) . cyan . underline }  
234248          MODES 
235249        end 
236250        # rubocop:enable Metrics/AbcSize 
237251
238-         def  run_production_like ( _verbose : false ,  route : nil ) 
252+         # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity 
253+         def  run_production_like ( _verbose : false ,  route : nil ,  rails_env : nil ) 
239254          procfile  =  "Procfile.dev-prod-assets" 
240255
241256          print_procfile_info ( procfile ,  route : route ) 
@@ -252,12 +267,33 @@ def run_production_like(_verbose: false, route: nil)
252267            route : route 
253268          ) 
254269
255-           # Precompile assets in production mode (includes pack generation automatically) 
256-           puts  "🔨 Precompiling assets..." 
270+           # Precompile assets with production webpack optimizations (includes pack generation automatically) 
271+           env_vars  =  [ "NODE_ENV=production" ] 
272+           env_vars  << "RAILS_ENV=#{ rails_env }   if  rails_env 
273+           command  =  "#{ env_vars . join ( ' ' ) }  
274+ 
275+           puts  "🔨 Precompiling assets with production webpack optimizations..." 
276+           puts  "" 
277+ 
278+           puts  Rainbow ( "ℹ️  Asset Precompilation Environment:" ) . blue 
279+           puts  "   • NODE_ENV=production → Webpack optimizations (minification, compression)" 
280+           if  rails_env 
281+             puts  "   • RAILS_ENV=#{ rails_env }  
282+             puts  "   • Note: RAILS_ENV=production requires credentials, database setup, etc." 
283+             puts  "   • Server processes will use environment from Procfile.dev-prod-assets" 
284+           else 
285+             puts  "   • RAILS_ENV=development → Simpler Rails setup (no credentials needed)" 
286+             puts  "   • Use --rails-env=production for assets:precompile step only" 
287+             puts  "   • Server processes will use environment from Procfile.dev-prod-assets" 
288+             puts  "   • Gets production webpack bundles without production Rails complexity" 
289+           end 
290+           puts  "" 
291+           puts  "#{ Rainbow ( '💻 Running:' ) . blue } #{ command }  
292+           puts  "" 
257293
258294          # Capture both stdout and stderr 
259295          require  "open3" 
260-           stdout ,  stderr ,  status  =  Open3 . capture3 ( "RAILS_ENV=production NODE_ENV=production bundle exec rails assets:precompile" ) 
296+           stdout ,  stderr ,  status  =  Open3 . capture3 ( command ) 
261297
262298          if  status . success? 
263299            puts  "✅ Assets precompiled successfully" 
@@ -267,51 +303,69 @@ def run_production_like(_verbose: false, route: nil)
267303            puts  "❌ Asset precompilation failed" 
268304            puts  "" 
269305
270-             # Display the actual error output 
271-             unless  stderr . empty? 
272-               puts  "#{ Rainbow ( '🚨 Error Output:' ) . red . bold }  
273-               puts  stderr 
274-               puts  "" 
275-             end 
306+             # Combine and display all output 
307+             all_output  =  [ ] 
308+             all_output  << stdout  unless  stdout . empty? 
309+             all_output  << stderr  unless  stderr . empty? 
276310
277-             unless  stdout . empty?  && stdout . strip  != stderr . strip 
278-               puts  "#{ Rainbow ( '📋 Command Output:' ) . yellow . bold }  
279-               puts  stdout 
311+             unless  all_output . empty? 
312+               puts  Rainbow ( "📋 Full Command Output:" ) . red . bold 
313+               puts  Rainbow ( "─"  * 60 ) . red 
314+               all_output . each  {  |output | puts  output  } 
315+               puts  Rainbow ( "─"  * 60 ) . red 
280316              puts  "" 
281317            end 
282318
283-             puts  "#{ Rainbow ( '💡 Common fixes:' ) . yellow . bold }  
319+             puts  Rainbow ( "🛠️  To debug this issue:" ) . yellow . bold 
320+             puts  "#{ Rainbow ( '1.' ) . cyan } #{ Rainbow ( 'Run the command separately to see detailed output:' ) . white }  
321+             puts  "   #{ Rainbow ( command ) . cyan }  
322+             puts  "" 
323+             puts  "#{ Rainbow ( '2.' ) . cyan } #{ Rainbow ( 'Add --trace for full stack trace:' ) . white }  
324+             puts  "   #{ Rainbow ( "#{ command }  ) . cyan }  
325+             puts  "" 
326+             puts  "#{ Rainbow ( '3.' ) . cyan } #{ Rainbow ( 'Or try with development webpack (faster, less optimized):' ) . white }  
327+             puts  "   #{ Rainbow ( 'NODE_ENV=development bundle exec rails assets:precompile' ) . cyan }  
328+             puts  "" 
329+ 
330+             puts  Rainbow ( "💡 Common fixes:" ) . yellow . bold 
284331
285332            # Provide specific guidance based on error content 
286333            error_content  =  "#{ stderr } #{ stdout }  . downcase 
287334
288335            if  error_content . include? ( "secret_key_base" ) 
289-               puts  "#{ Rainbow ( '•' ) . yellow } #{ Rainbow ( 'Missing secret_key_base:' ) . white . bold } #{ Rainbow ( 'bin/rails credentials:edit' ) . cyan }  
336+               puts  "#{ Rainbow ( '•' ) . yellow } #{ Rainbow ( 'Missing secret_key_base:' ) . white . bold }   \
337+                    "Run #{ Rainbow ( 'bin/rails credentials:edit' ) . cyan }  
290338            end 
291339
292-             if  error_content . include? ( "database" )  || error_content . include? ( "relation" )  || error_content . include? ( "table" ) 
293-               puts  "#{ Rainbow ( '•' ) . yellow } #{ Rainbow ( 'Database issues:' ) . white . bold } #{ Rainbow ( 'bin/rails db:create db:migrate' ) . cyan }  
340+             if  error_content . include? ( "database" )  || error_content . include? ( "relation" )  ||
341+                error_content . include? ( "table" ) 
342+               puts  "#{ Rainbow ( '•' ) . yellow } #{ Rainbow ( 'Database issues:' ) . white . bold }   \
343+                    "Run #{ Rainbow ( 'bin/rails db:create db:migrate' ) . cyan }  
294344            end 
295345
296346            if  error_content . include? ( "gem" )  || error_content . include? ( "bundle" )  || error_content . include? ( "load error" ) 
297-               puts  "#{ Rainbow ( '•' ) . yellow } #{ Rainbow ( 'Missing dependencies:' ) . white . bold } #{ Rainbow ( 'bundle install && npm install' ) . cyan }  
347+               puts  "#{ Rainbow ( '•' ) . yellow } #{ Rainbow ( 'Missing dependencies:' ) . white . bold }   \
348+                    "Run #{ Rainbow ( 'bundle install && npm install' ) . cyan }  
298349            end 
299350
300-             if  error_content . include? ( "webpack" )  || error_content . include? ( "module" )  || error_content . include? ( "compilation" ) 
301-               puts  "#{ Rainbow ( '•' ) . yellow } #{ Rainbow ( 'Webpack compilation:' ) . white . bold }  
351+             if  error_content . include? ( "webpack" )  || error_content . include? ( "module" )  ||
352+                error_content . include? ( "compilation" ) 
353+               puts  "#{ Rainbow ( '•' ) . yellow } #{ Rainbow ( 'Webpack compilation:' ) . white . bold }   \
354+                    "Check JavaScript/webpack errors above" 
302355            end 
303356
304357            # Always show these general options 
305-             puts  "#{ Rainbow ( '•' ) . yellow } #{ Rainbow ( 'General debugging :' ) . white } Run with  #{ Rainbow ( '--trace' ) . cyan }  for full stack trace"  
306-             puts   " #{ Rainbow ( '•' ) . yellow }   #{ Rainbow ( 'Environment issues:' ) . white }   Check #{ Rainbow ( 'config/environments/production.rb' ) . cyan } 
358+             puts  "#{ Rainbow ( '•' ) . yellow } #{ Rainbow ( 'Environment config :' ) . white } "   \ 
359+                   " Check #{ Rainbow ( 'config/environments/production.rb' ) . cyan } 
307360
308361            puts  "" 
309-             puts  " #{ Rainbow ( ' ℹ️  Alternative for development:' ) . blue } " 
362+             puts  Rainbow ( " ℹ️  Alternative for development:" ) . blue 
310363            puts  "   #{ Rainbow ( 'bin/dev static' ) . green }  
311364            puts  "" 
312365            exit  1 
313366          end 
314367        end 
368+         # rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity 
315369
316370        def  run_static_development ( procfile ,  verbose : false ,  route : nil ) 
317371          print_procfile_info ( procfile ,  route : route ) 
0 commit comments