|
4 | 4 | require "json"
|
5 | 5 | require_relative "generator_helper"
|
6 | 6 | require_relative "generator_messages"
|
| 7 | +require_relative "js_dependency_manager" |
7 | 8 |
|
8 | 9 | module ReactOnRails
|
9 | 10 | module Generators
|
10 | 11 | # rubocop:disable Metrics/ClassLength
|
11 | 12 | class InstallGenerator < Rails::Generators::Base
|
12 | 13 | include GeneratorHelper
|
| 14 | + include JsDependencyManager |
13 | 15 |
|
14 | 16 | # fetch USAGE file for details generator description
|
15 | 17 | source_root(File.expand_path(__dir__))
|
@@ -83,10 +85,7 @@ def invoke_generators
|
83 | 85 | end
|
84 | 86 |
|
85 | 87 | def setup_react_dependencies
|
86 |
| - @added_dependencies_to_package_json ||= false |
87 |
| - @ran_direct_installs ||= false |
88 |
| - add_js_dependencies |
89 |
| - install_js_dependencies if @added_dependencies_to_package_json && !@ran_direct_installs |
| 88 | + setup_js_dependencies |
90 | 89 | end
|
91 | 90 |
|
92 | 91 | # NOTE: other requirements for existing files such as .gitignore or application.
|
@@ -346,11 +345,17 @@ def install_typescript_dependencies
|
346 | 345 | ]
|
347 | 346 |
|
348 | 347 | # Try using GeneratorHelper first (package manager agnostic)
|
349 |
| - return if add_npm_dependencies(typescript_packages, dev: true) |
| 348 | + if add_npm_dependencies(typescript_packages, dev: true) |
| 349 | + @added_dependencies_to_package_json = true |
| 350 | + return |
| 351 | + end |
350 | 352 |
|
351 | 353 | # Fallback to npm if GeneratorHelper fails
|
352 | 354 | success = system("npm", "install", "--save-dev", *typescript_packages)
|
353 |
| - return if success |
| 355 | + if success |
| 356 | + @ran_direct_installs = true |
| 357 | + return |
| 358 | + end |
354 | 359 |
|
355 | 360 | warning = <<~MSG.strip
|
356 | 361 | ⚠️ Failed to install TypeScript dependencies automatically.
|
@@ -420,134 +425,6 @@ def create_typescript_config
|
420 | 425 | puts Rainbow("✅ Created tsconfig.json").green
|
421 | 426 | end
|
422 | 427 |
|
423 |
| - def add_js_dependencies |
424 |
| - add_react_on_rails_package |
425 |
| - add_react_dependencies |
426 |
| - add_css_dependencies |
427 |
| - add_dev_dependencies |
428 |
| - end |
429 |
| - |
430 |
| - def add_react_on_rails_package |
431 |
| - major_minor_patch_only = /\A\d+\.\d+\.\d+\z/ |
432 |
| - |
433 |
| - # Try to use package_json gem first, fall back to direct npm commands |
434 |
| - react_on_rails_pkg = if ReactOnRails::VERSION.match?(major_minor_patch_only) |
435 |
| - ["react-on-rails@#{ReactOnRails::VERSION}"] |
436 |
| - else |
437 |
| - puts "Adding the latest react-on-rails NPM module. " \ |
438 |
| - "Double check this is correct in package.json" |
439 |
| - ["react-on-rails"] |
440 |
| - end |
441 |
| - |
442 |
| - puts "Installing React on Rails package..." |
443 |
| - if add_npm_dependencies(react_on_rails_pkg) |
444 |
| - @added_dependencies_to_package_json = true |
445 |
| - return |
446 |
| - end |
447 |
| - |
448 |
| - puts "Using direct npm commands as fallback" |
449 |
| - success = system("npm", "install", *react_on_rails_pkg) |
450 |
| - @ran_direct_installs = true if success |
451 |
| - handle_npm_failure("react-on-rails package", react_on_rails_pkg) unless success |
452 |
| - end |
453 |
| - |
454 |
| - def add_react_dependencies |
455 |
| - puts "Installing React dependencies..." |
456 |
| - react_deps = %w[ |
457 |
| - react |
458 |
| - react-dom |
459 |
| - @babel/preset-react |
460 |
| - prop-types |
461 |
| - babel-plugin-transform-react-remove-prop-types |
462 |
| - babel-plugin-macros |
463 |
| - ] |
464 |
| - if add_npm_dependencies(react_deps) |
465 |
| - @added_dependencies_to_package_json = true |
466 |
| - return |
467 |
| - end |
468 |
| - |
469 |
| - success = system("npm", "install", *react_deps) |
470 |
| - @ran_direct_installs = true if success |
471 |
| - handle_npm_failure("React dependencies", react_deps) unless success |
472 |
| - end |
473 |
| - |
474 |
| - def add_css_dependencies |
475 |
| - puts "Installing CSS handling dependencies..." |
476 |
| - css_deps = %w[ |
477 |
| - css-loader |
478 |
| - css-minimizer-webpack-plugin |
479 |
| - mini-css-extract-plugin |
480 |
| - style-loader |
481 |
| - ] |
482 |
| - if add_npm_dependencies(css_deps) |
483 |
| - @added_dependencies_to_package_json = true |
484 |
| - return |
485 |
| - end |
486 |
| - |
487 |
| - success = system("npm", "install", *css_deps) |
488 |
| - @ran_direct_installs = true if success |
489 |
| - handle_npm_failure("CSS dependencies", css_deps) unless success |
490 |
| - end |
491 |
| - |
492 |
| - def add_dev_dependencies |
493 |
| - puts "Installing development dependencies..." |
494 |
| - dev_deps = %w[ |
495 |
| - @pmmmwh/react-refresh-webpack-plugin |
496 |
| - react-refresh |
497 |
| - ] |
498 |
| - if add_npm_dependencies(dev_deps, dev: true) |
499 |
| - @added_dependencies_to_package_json = true |
500 |
| - return |
501 |
| - end |
502 |
| - |
503 |
| - success = system("npm", "install", "--save-dev", *dev_deps) |
504 |
| - @ran_direct_installs = true if success |
505 |
| - handle_npm_failure("development dependencies", dev_deps, dev: true) unless success |
506 |
| - end |
507 |
| - |
508 |
| - def install_js_dependencies |
509 |
| - # Detect which package manager to use |
510 |
| - success = if File.exist?(File.join(destination_root, "yarn.lock")) |
511 |
| - system("yarn", "install") |
512 |
| - elsif File.exist?(File.join(destination_root, "pnpm-lock.yaml")) |
513 |
| - system("pnpm", "install") |
514 |
| - elsif File.exist?(File.join(destination_root, "package-lock.json")) || |
515 |
| - File.exist?(File.join(destination_root, "package.json")) |
516 |
| - # Use npm for package-lock.json or as default fallback |
517 |
| - system("npm", "install") |
518 |
| - else |
519 |
| - true # No package manager detected, skip |
520 |
| - end |
521 |
| - |
522 |
| - unless success |
523 |
| - GeneratorMessages.add_warning(<<~MSG.strip) |
524 |
| - ⚠️ JavaScript dependencies installation failed. |
525 |
| -
|
526 |
| - This could be due to network issues or missing package manager. |
527 |
| - You can install dependencies manually later by running: |
528 |
| - • npm install (if using npm) |
529 |
| - • yarn install (if using yarn) |
530 |
| - • pnpm install (if using pnpm) |
531 |
| - MSG |
532 |
| - end |
533 |
| - |
534 |
| - success |
535 |
| - end |
536 |
| - |
537 |
| - def handle_npm_failure(dependency_type, packages, dev: false) |
538 |
| - install_command = dev ? "npm install --save-dev" : "npm install" |
539 |
| - GeneratorMessages.add_warning(<<~MSG.strip) |
540 |
| - ⚠️ Failed to install #{dependency_type}. |
541 |
| -
|
542 |
| - The following packages could not be installed automatically: |
543 |
| - #{packages.map { |pkg| " • #{pkg}" }.join("\n")} |
544 |
| -
|
545 |
| - This could be due to network issues or missing package manager. |
546 |
| - You can install them manually later by running: |
547 |
| - #{install_command} #{packages.join(' ')} |
548 |
| - MSG |
549 |
| - end |
550 |
| - |
551 | 428 | # Removed: Shakapacker auto-installation logic (now explicit dependency)
|
552 | 429 |
|
553 | 430 | # Removed: Shakapacker 8+ is now required as explicit dependency
|
|
0 commit comments