Module: ReactOnRails::Generators::JsDependencyManager
- Included in:
- BaseGenerator, InstallGenerator, ProGenerator, RscGenerator
- Defined in:
- lib/generators/react_on_rails/js_dependency_manager.rb,
sig/react_on_rails/generators/js_dependency_manager.rbs
Overview
Type signatures for JsDependencyManager module
This module provides common functionality for managing JavaScript dependencies in Rails generators using the package_json gem (available via shakapacker).
Constant Summary collapse
- REACT_DEPENDENCIES =
Core React dependencies required for React on Rails
%w[ react@^19.0.0 react-dom@^19.0.0 prop-types@^15.0.0 ].freeze
- BABEL_REACT_DEPENDENCIES =
Babel preset needed by the generated babel.config.js for non-SWC setups.
%w[ @babel/preset-react@^7.0.0 ].freeze
- CSS_DEPENDENCIES =
CSS processing dependencies for webpack
%w[ css-loader@^7.0.0 css-minimizer-webpack-plugin@^8.0.0 mini-css-extract-plugin@^2.0.0 style-loader@^4.0.0 ].freeze
- TAILWIND_DEPENDENCIES =
Tailwind v4 CSS-first setup. The patch-level floors match published releases verified with the generator's SSR smoke app.
%w[ tailwindcss@^4.3.0 @tailwindcss/postcss@^4.3.0 postcss@^8.5.15 postcss-loader@^8.2.1 ].freeze
- DEV_DEPENDENCIES =
Development-only dependencies for hot reloading (Webpack)
%w[ @pmmmwh/react-refresh-webpack-plugin react-refresh ].freeze
- RSPACK_DEPENDENCIES =
Rspack core dependencies (only installed when --rspack flag is used)
%w[ @rspack/core@^2.0.0-0 rspack-manifest-plugin@^5.0.0 ].freeze
- RSPACK_DEV_DEPENDENCIES =
Rspack development dependencies for hot reloading
%w[ @rspack/cli@^2.0.0-0 @rspack/dev-server@^2.0.0 @rspack/plugin-react-refresh@^2.0.0 react-refresh ].freeze
- TYPESCRIPT_DEPENDENCIES =
TypeScript dependencies (only installed when --typescript flag is used)
%w[ typescript@^6.0.0 @types/react@^19.0.0 @types/react-dom@^19.0.0 ].freeze
- SWC_DEPENDENCIES =
SWC transpiler dependencies (for Shakapacker 9.3.0+ default transpiler) SWC is ~20x faster than Babel and is the default for new Shakapacker installations Version ranges match Shakapacker's own constraints.
%w[ @swc/core@^1.3.0 swc-loader@^0.2.0 ].freeze
- PRO_DEPENDENCIES =
React on Rails Pro dependencies (only installed when --pro or --rsc flag is used) These packages are published publicly on npmjs.org but require a license for production use
%w[ react-on-rails-pro react-on-rails-pro-node-renderer ].freeze
- RSC_DEPENDENCIES =
React Server Components dependencies (only installed when --rsc flag is used) Requires React 19.2.x with patch >= 19.2.7 - see https://react.dev/reference/rsc/server-components
%w[ react-on-rails-rsc ].freeze
- RSC_REACT_VERSION_RANGE =
React peer-dependency range for generated RSC apps. This governs the
react/react-dominstalls (see add_react_dependencies) and intentionally stays on the React 19.2.x line with a 19.2.7 minimum. Do not widen this to later minors just because those releases are current on npm; React's RSC runtime and bundler integration can change between minors.This is intentionally distinct from RSC_PACKAGE_VERSION_PIN below, which pins
react-on-rails-rsc. Coordination note for #3609: Pro package metadata accepts the prerelease RSC package broadly enough to keepnpm lshealthy, while generated apps still install the tested React 19.2.x range and exact RSC package pin until stable 19.2.1 ships. "~19.2.7"- RSC_PACKAGE_VERSION_PIN =
Pinned to the 19.2.1 release candidate, which carries the coordinated React 19.2.7 RSC peer floor required by the React on Rails Pro 17 runtime check.
"19.2.1-rc.0"
Instance Method Summary collapse
-
#add_css_dependencies ⇒ void
Adds CSS processing dependencies to package.json.
-
#add_dev_dependencies ⇒ void
Adds development dependencies to package.json.
-
#add_js_dependencies ⇒ void
Adds all JavaScript dependencies to package.json.
-
#add_package(package, dev: false) ⇒ bool
Adds a single package using package_json gem.
-
#add_packages(packages, dev: false) ⇒ bool
Adds multiple packages at once using package_json gem.
-
#add_react_dependencies ⇒ void
Adds React dependencies to package.json.
-
#add_react_on_rails_package ⇒ void
Adds the react-on-rails package to package.json.
-
#add_rspack_dependencies ⇒ void
Adds Rspack dependencies to package.json.
-
#add_typescript_dependencies ⇒ void
Adds TypeScript dependencies to package.json as dev dependencies.
-
#install_js_dependencies ⇒ bool
Installs JavaScript dependencies using package_json gem.
-
#setup_js_dependencies ⇒ void
Sets up JavaScript dependencies by adding and installing packages.
Instance Method Details
#add_css_dependencies ⇒ void
This method returns an undefined value.
Adds CSS processing dependencies to package.json
Adds error message to GeneratorMessages if package addition fails.
67 68 69 |
# File 'sig/react_on_rails/generators/js_dependency_manager.rbs', line 67 def add_css_dependencies install_dependency_group("CSS handling dependencies", "CSS dependencies", CSS_DEPENDENCIES) end |
#add_dev_dependencies ⇒ void
This method returns an undefined value.
Adds development dependencies to package.json
Chooses between Webpack or Rspack dev dependencies based on --rspack flag. Adds error message to GeneratorMessages if package addition fails.
91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 |
# File 'sig/react_on_rails/generators/js_dependency_manager.rbs', line 91 def add_dev_dependencies say "Installing development dependencies..." # Use Rspack-specific dev dependencies if rspack is configured dev_deps = using_rspack? ? RSPACK_DEV_DEPENDENCIES : DEV_DEPENDENCIES return if add_packages(dev_deps, dev: true) GeneratorMessages.add_warning(<<~MSG.strip) ⚠️ Failed to add development dependencies. You can install them manually by running: #{manual_add_packages_command(dev_deps, dev: true)} MSG rescue StandardError => e GeneratorMessages.add_warning(<<~MSG.strip) ⚠️ Error adding development dependencies: #{e.} You can install them manually by running: #{manual_add_packages_command(dev_deps, dev: true)} MSG end |
#add_js_dependencies ⇒ void
This method returns an undefined value.
Adds all JavaScript dependencies to package.json
This method calls individual add_*_dependencies methods in sequence. All errors are handled gracefully with warnings rather than exceptions.
45 46 47 48 49 50 51 52 53 54 55 56 57 58 |
# File 'sig/react_on_rails/generators/js_dependency_manager.rbs', line 45 def add_js_dependencies using_pro = respond_to?(:use_pro?) && use_pro? using_rsc = respond_to?(:use_rsc?) && use_rsc? # Pro package includes react-on-rails, so skip base package when using Pro add_react_on_rails_package unless using_pro add_react_dependencies add_css_dependencies add_tailwind_dependencies_if_requested add_rspack_dependencies if using_rspack? add_transpiler_dependencies add_pro_dependencies if using_pro add_rsc_dependencies if using_rsc add_dev_dependencies end |
#add_package(package, dev: false) ⇒ bool
Adds a single package using package_json gem
This method is used internally for adding the react-on-rails package with version-specific handling (react-on-rails@VERSION). For batch operations, use add_packages instead.
555 556 557 |
# File 'lib/generators/react_on_rails/js_dependency_manager.rb', line 555 def add_package(package, dev: false) add_packages([package], dev:) end |
#add_packages(packages, dev: false) ⇒ bool
Adds multiple packages at once using package_json gem
Delegates to GeneratorHelper's add_npm_dependencies for better package manager abstraction and batch processing efficiency.
567 568 569 570 571 572 573 |
# File 'lib/generators/react_on_rails/js_dependency_manager.rb', line 567 def add_packages(packages, dev: false) return true if add_npm_dependencies(packages, dev:) return true if install_packages_with_fallback(packages, dev:) write_versioned_package_specs_to_package_json(packages, dev:) false end |
#add_react_dependencies ⇒ void
This method returns an undefined value.
Adds React dependencies to package.json
Adds error message to GeneratorMessages if package addition fails.
60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 |
# File 'sig/react_on_rails/generators/js_dependency_manager.rbs', line 60 def add_react_dependencies say "Installing React dependencies..." # RSC requires the coordinated React 19.2.x patch line. # Pin React to ~19.2.7 while using the matching RSC package release candidate. react_deps = if respond_to?(:use_rsc?) && use_rsc? ["react@#{RSC_REACT_VERSION_RANGE}", "react-dom@#{RSC_REACT_VERSION_RANGE}", "prop-types@^15.0.0"] else REACT_DEPENDENCIES end return if add_packages(react_deps) GeneratorMessages.add_warning(<<~MSG.strip) ⚠️ Failed to add React dependencies. You can install them manually by running: #{manual_add_packages_command(react_deps)} MSG rescue StandardError => e GeneratorMessages.add_warning(<<~MSG.strip) ⚠️ Error adding React dependencies: #{e.} You can install them manually by running: #{manual_add_packages_command(react_deps)} MSG end |
#add_react_on_rails_package ⇒ void
This method returns an undefined value.
Adds the react-on-rails package to package.json
Uses version matching for stable releases, or latest for pre-releases. Adds error message to GeneratorMessages if package addition fails.
53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 |
# File 'sig/react_on_rails/generators/js_dependency_manager.rbs', line 53 def add_react_on_rails_package # Use exact version match between gem and npm package for all versions including pre-releases # Ruby gem versions use dots (16.2.0.beta.10) but npm requires hyphens (16.2.0-beta.10) # This method converts between the two formats. # # The regex matches: # - Stable: 16.2.0 # - Beta (Ruby): 16.2.0.beta.10 or (npm): 16.2.0-beta.10 # - RC (Ruby): 16.1.0.rc.1 or (npm): 16.1.0-rc.1 # - Alpha (Ruby): 16.0.0.alpha.5 or (npm): 16.0.0-alpha.5 # This ensures beta/rc versions use the exact version instead of "latest" which would # install the latest stable release and cause version mismatches. # Accept both dot and hyphen separators for pre-release versions version_with_optional_prerelease = /\A(\d+\.\d+\.\d+)([-.]([a-zA-Z0-9.]+))?\z/ react_on_rails_pkg = if (match = ReactOnRails::VERSION.match(version_with_optional_prerelease)) base_version = match[1] prerelease = match[3] # Convert Ruby gem format (dot) to npm semver format (hyphen) npm_version = if prerelease "#{base_version}-#{prerelease}" else base_version end "react-on-rails@#{npm_version}" else say_status :warning, "Unrecognized version format #{ReactOnRails::VERSION}. " \ "Adding the latest react-on-rails NPM module. " \ "Double check this is correct in package.json", :yellow "react-on-rails" end say "Installing React on Rails package..." return if add_package(react_on_rails_pkg) GeneratorMessages.add_warning(<<~MSG.strip) ⚠️ Failed to add react-on-rails package. You can install it manually by running: #{manual_add_packages_command([react_on_rails_pkg])} MSG rescue StandardError => e GeneratorMessages.add_warning(<<~MSG.strip) ⚠️ Error adding react-on-rails package: #{e.} You can install it manually by running: #{manual_add_packages_command([react_on_rails_pkg])} MSG end |
#add_rspack_dependencies ⇒ void
This method returns an undefined value.
Adds Rspack dependencies to package.json
Only called when --rspack flag is set. Adds error message to GeneratorMessages if package addition fails.
75 76 77 |
# File 'sig/react_on_rails/generators/js_dependency_manager.rbs', line 75 def add_rspack_dependencies install_dependency_group("Rspack core dependencies", "Rspack dependencies", RSPACK_DEPENDENCIES) end |
#add_typescript_dependencies ⇒ void
This method returns an undefined value.
Adds TypeScript dependencies to package.json as dev dependencies
Only called when --typescript flag is set. Adds error message to GeneratorMessages if package addition fails.
83 84 85 86 |
# File 'sig/react_on_rails/generators/js_dependency_manager.rbs', line 83 def add_typescript_dependencies install_dependency_group("TypeScript dependencies", "TypeScript dependencies", TYPESCRIPT_DEPENDENCIES, dev: true) end |
#install_js_dependencies ⇒ bool
Installs JavaScript dependencies using package_json gem
Always available via shakapacker dependency chain. Adds warning to GeneratorMessages if installation fails.
120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 |
# File 'sig/react_on_rails/generators/js_dependency_manager.rbs', line 120 def install_js_dependencies pj = package_json if pj pj.manager.install return true end package_manager = fallback_package_manager install_args = [package_manager, "install"] return true if system(*install_args) GeneratorMessages.add_warning(<<~MSG.strip) ⚠️ JavaScript dependencies installation failed via #{package_manager}. Please run manually: #{install_args.join(' ')} MSG false rescue StandardError => e GeneratorMessages.add_warning(<<~MSG.strip) ⚠️ JavaScript dependencies installation failed: #{e.} This could be due to network issues or package manager problems. You can install dependencies manually later by running: #{manual_install_dependencies_command} MSG false end |
#setup_js_dependencies ⇒ void
This method returns an undefined value.
Sets up JavaScript dependencies by adding and installing packages
This method orchestrates the entire dependency setup process:
- Adds all required packages to package.json
- Runs package manager install
37 38 39 40 41 42 43 44 45 46 |
# File 'sig/react_on_rails/generators/js_dependency_manager.rbs', line 37 def setup_js_dependencies add_js_dependencies # Always run install to ensure all dependencies are properly installed. # The package_json gem's install method is idempotent and safe to call # even if packages were already added - it will only install what's needed. # This ensures edge cases where package.json was modified but install wasn't # run are handled correctly. install_js_dependencies end |