Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
119 changes: 2 additions & 117 deletions lib/generators/react_on_rails/base_generator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,12 @@
require "fileutils"
require_relative "generator_messages"
require_relative "generator_helper"
require_relative "js_dependency_manager"
module ReactOnRails
module Generators
class BaseGenerator < Rails::Generators::Base
include GeneratorHelper
include JsDependencyManager

Rails::Generators.hide_namespace(namespace)
source_root(File.expand_path("templates", __dir__))
Expand Down Expand Up @@ -134,123 +136,6 @@ def append_to_spec_rails_helper

private

def setup_js_dependencies
add_js_dependencies
install_js_dependencies
end

def add_js_dependencies
add_react_on_rails_package
add_react_dependencies
add_css_dependencies
add_dev_dependencies
end

def add_react_on_rails_package
major_minor_patch_only = /\A\d+\.\d+\.\d+\z/

# Try to use package_json gem first, fall back to direct npm commands
react_on_rails_pkg = if ReactOnRails::VERSION.match?(major_minor_patch_only)
["react-on-rails@#{ReactOnRails::VERSION}"]
else
puts "Adding the latest react-on-rails NPM module. " \
"Double check this is correct in package.json"
["react-on-rails"]
end

puts "Installing React on Rails package..."
return if add_npm_dependencies(react_on_rails_pkg)

puts "Using direct npm commands as fallback"
success = system("npm", "install", *react_on_rails_pkg)
handle_npm_failure("react-on-rails package", react_on_rails_pkg) unless success
end

def add_react_dependencies
puts "Installing React dependencies..."
react_deps = %w[
react
react-dom
@babel/preset-react
prop-types
babel-plugin-transform-react-remove-prop-types
babel-plugin-macros
]
return if add_npm_dependencies(react_deps)

success = system("npm", "install", *react_deps)
handle_npm_failure("React dependencies", react_deps) unless success
end

def add_css_dependencies
puts "Installing CSS handling dependencies..."
css_deps = %w[
css-loader
css-minimizer-webpack-plugin
mini-css-extract-plugin
style-loader
]
return if add_npm_dependencies(css_deps)

success = system("npm", "install", *css_deps)
handle_npm_failure("CSS dependencies", css_deps) unless success
end

def add_dev_dependencies
puts "Installing development dependencies..."
dev_deps = %w[
@pmmmwh/react-refresh-webpack-plugin
react-refresh
]
return if add_npm_dependencies(dev_deps, dev: true)

success = system("npm", "install", "--save-dev", *dev_deps)
handle_npm_failure("development dependencies", dev_deps, dev: true) unless success
end

def install_js_dependencies
# Detect which package manager to use
success = if File.exist?(File.join(destination_root, "yarn.lock"))
system("yarn", "install")
elsif File.exist?(File.join(destination_root, "pnpm-lock.yaml"))
system("pnpm", "install")
elsif File.exist?(File.join(destination_root, "package-lock.json")) ||
File.exist?(File.join(destination_root, "package.json"))
# Use npm for package-lock.json or as default fallback
system("npm", "install")
else
true # No package manager detected, skip
end

unless success
GeneratorMessages.add_warning(<<~MSG.strip)
⚠️ JavaScript dependencies installation failed.

This could be due to network issues or missing package manager.
You can install dependencies manually later by running:
• npm install (if using npm)
• yarn install (if using yarn)
• pnpm install (if using pnpm)
MSG
end

success
end

def handle_npm_failure(dependency_type, packages, dev: false)
install_command = dev ? "npm install --save-dev" : "npm install"
GeneratorMessages.add_warning(<<~MSG.strip)
⚠️ Failed to install #{dependency_type}.

The following packages could not be installed automatically:
#{packages.map { |pkg| " • #{pkg}" }.join("\n")}

This could be due to network issues or missing package manager.
You can install them manually later by running:
#{install_command} #{packages.join(' ')}
MSG
end

def copy_webpack_main_config(base_path, config)
webpack_config_path = "config/webpack/webpack.config.js"

Expand Down
145 changes: 11 additions & 134 deletions lib/generators/react_on_rails/install_generator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,14 @@
require "json"
require_relative "generator_helper"
require_relative "generator_messages"
require_relative "js_dependency_manager"

module ReactOnRails
module Generators
# rubocop:disable Metrics/ClassLength
class InstallGenerator < Rails::Generators::Base
include GeneratorHelper
include JsDependencyManager

# fetch USAGE file for details generator description
source_root(File.expand_path(__dir__))
Expand Down Expand Up @@ -83,10 +85,7 @@ def invoke_generators
end

def setup_react_dependencies
@added_dependencies_to_package_json ||= false
@ran_direct_installs ||= false
add_js_dependencies
install_js_dependencies if @added_dependencies_to_package_json && !@ran_direct_installs
setup_js_dependencies
end

# NOTE: other requirements for existing files such as .gitignore or application.
Expand Down Expand Up @@ -346,11 +345,17 @@ def install_typescript_dependencies
]

# Try using GeneratorHelper first (package manager agnostic)
return if add_npm_dependencies(typescript_packages, dev: true)
if add_npm_dependencies(typescript_packages, dev: true)
@added_dependencies_to_package_json = true
return
end

# Fallback to npm if GeneratorHelper fails
success = system("npm", "install", "--save-dev", *typescript_packages)
return if success
if success
@ran_direct_installs = true
return
end

warning = <<~MSG.strip
⚠️ Failed to install TypeScript dependencies automatically.
Expand Down Expand Up @@ -420,134 +425,6 @@ def create_typescript_config
puts Rainbow("✅ Created tsconfig.json").green
end

def add_js_dependencies
add_react_on_rails_package
add_react_dependencies
add_css_dependencies
add_dev_dependencies
end

def add_react_on_rails_package
major_minor_patch_only = /\A\d+\.\d+\.\d+\z/

# Try to use package_json gem first, fall back to direct npm commands
react_on_rails_pkg = if ReactOnRails::VERSION.match?(major_minor_patch_only)
["react-on-rails@#{ReactOnRails::VERSION}"]
else
puts "Adding the latest react-on-rails NPM module. " \
"Double check this is correct in package.json"
["react-on-rails"]
end

puts "Installing React on Rails package..."
if add_npm_dependencies(react_on_rails_pkg)
@added_dependencies_to_package_json = true
return
end

puts "Using direct npm commands as fallback"
success = system("npm", "install", *react_on_rails_pkg)
@ran_direct_installs = true if success
handle_npm_failure("react-on-rails package", react_on_rails_pkg) unless success
end

def add_react_dependencies
puts "Installing React dependencies..."
react_deps = %w[
react
react-dom
@babel/preset-react
prop-types
babel-plugin-transform-react-remove-prop-types
babel-plugin-macros
]
if add_npm_dependencies(react_deps)
@added_dependencies_to_package_json = true
return
end

success = system("npm", "install", *react_deps)
@ran_direct_installs = true if success
handle_npm_failure("React dependencies", react_deps) unless success
end

def add_css_dependencies
puts "Installing CSS handling dependencies..."
css_deps = %w[
css-loader
css-minimizer-webpack-plugin
mini-css-extract-plugin
style-loader
]
if add_npm_dependencies(css_deps)
@added_dependencies_to_package_json = true
return
end

success = system("npm", "install", *css_deps)
@ran_direct_installs = true if success
handle_npm_failure("CSS dependencies", css_deps) unless success
end

def add_dev_dependencies
puts "Installing development dependencies..."
dev_deps = %w[
@pmmmwh/react-refresh-webpack-plugin
react-refresh
]
if add_npm_dependencies(dev_deps, dev: true)
@added_dependencies_to_package_json = true
return
end

success = system("npm", "install", "--save-dev", *dev_deps)
@ran_direct_installs = true if success
handle_npm_failure("development dependencies", dev_deps, dev: true) unless success
end

def install_js_dependencies
# Detect which package manager to use
success = if File.exist?(File.join(destination_root, "yarn.lock"))
system("yarn", "install")
elsif File.exist?(File.join(destination_root, "pnpm-lock.yaml"))
system("pnpm", "install")
elsif File.exist?(File.join(destination_root, "package-lock.json")) ||
File.exist?(File.join(destination_root, "package.json"))
# Use npm for package-lock.json or as default fallback
system("npm", "install")
else
true # No package manager detected, skip
end

unless success
GeneratorMessages.add_warning(<<~MSG.strip)
⚠️ JavaScript dependencies installation failed.

This could be due to network issues or missing package manager.
You can install dependencies manually later by running:
• npm install (if using npm)
• yarn install (if using yarn)
• pnpm install (if using pnpm)
MSG
end

success
end

def handle_npm_failure(dependency_type, packages, dev: false)
install_command = dev ? "npm install --save-dev" : "npm install"
GeneratorMessages.add_warning(<<~MSG.strip)
⚠️ Failed to install #{dependency_type}.

The following packages could not be installed automatically:
#{packages.map { |pkg| " • #{pkg}" }.join("\n")}

This could be due to network issues or missing package manager.
You can install them manually later by running:
#{install_command} #{packages.join(' ')}
MSG
end

# Removed: Shakapacker auto-installation logic (now explicit dependency)

# Removed: Shakapacker 8+ is now required as explicit dependency
Expand Down
Loading
Loading