Module: ReactOnRails::Generators::JsDependencyManager

Included in:
BaseGenerator, InstallGenerator, ProGenerator, RscGenerator
Defined in:
lib/generators/react_on_rails/js_dependency_manager.rb

Overview

Shared module for managing JavaScript dependencies across generators This module provides common functionality for adding and installing JS dependencies to avoid code duplication between generators.

For older shakapacker versions, the package_json gem may not be available. In that case this module falls back to direct package-manager commands.

Required Methods

Including classes must include GeneratorHelper module which provides:

  • add_npm_dependencies(packages, dev: false): Add packages via package_json gem

  • package_json: Access to PackageJson instance (always available via shakapacker)

  • destination_root: Generator destination directory

  • using_rspack?: Returns true if rspack is the configured bundler (called unconditionally; provided by GeneratorHelper)

  • using_swc?: Returns true if SWC is the configured transpiler (called unconditionally; provided by GeneratorHelper)

Optional Methods

Including classes may define:

  • use_pro?: Returns true if React on Rails Pro should be used

  • use_rsc?: Returns true if React Server Components should be used

Installation Behavior

The module ALWAYS runs package manager install after adding dependencies. This is safe because package_json gem’s install method is idempotent - it only installs what’s actually needed from package.json. This prevents edge cases where package.json was modified but dependencies weren’t installed.

Error Handling Philosophy

All dependency addition methods use a graceful degradation approach:

  • Methods return false on failure instead of raising exceptions

  • StandardError is caught at the lowest level (add_package) and higher levels (add_*_dependencies)

  • Failures trigger user-facing warnings via GeneratorMessages

  • Warnings provide clear manual installation instructions

This ensures the generator ALWAYS completes successfully, even when:

  • Network connectivity issues prevent package downloads

  • Package manager (npm/yarn/pnpm) has permission errors

  • package_json gem encounters unexpected states

Users can manually run package installation commands after generator completion. This is preferable to generator crashes that leave Rails apps in incomplete states.

Usage

Include this module in generator classes and call setup_js_dependencies to handle all JS dependency installation via package_json gem.

Constant Summary collapse

REACT_DEPENDENCIES =

Core React dependencies required for React on Rails Note: @babel/preset-react is handled separately in BABEL_REACT_DEPENDENCIES and is added only when SWC is not the active transpiler.

%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
DEV_DEPENDENCIES =

Development-only dependencies for hot reloading (Webpack) Both packages are pre-1.0, so left bare (see pinning note above).

%w[
  @pmmmwh/react-refresh-webpack-plugin
  react-refresh
].freeze
RSPACK_DEPENDENCIES =

Rspack core dependencies (only installed when –rspack flag is used) @rspack/core uses ^2.0.0-0 (with -0 prerelease suffix) to include RC/beta prereleases of 2.0.0 until the stable 2.0.0 release lands.

%w[
  @rspack/core@^2.0.0-0
  rspack-manifest-plugin@^5.0.0
].freeze
RSPACK_DEV_DEPENDENCIES =

Rspack development dependencies for hot reloading react-refresh is pre-1.0, so left bare (see pinning note above). @rspack/cli uses ^2.0.0-0 to match @rspack/core’s prerelease range.

%w[
  @rspack/cli@^2.0.0-0
  @rspack/plugin-react-refresh@^2.0.0
  react-refresh
].freeze
TYPESCRIPT_DEPENDENCIES =

TypeScript dependencies (only installed when –typescript flag is used) Note: @babel/preset-typescript is NOT included because:

  • SWC is now the default javascript_transpiler (has built-in TypeScript support)

  • Shakapacker handles the transpiler configuration via shakapacker.yml

  • If users choose javascript_transpiler: ‘babel’, they should manually add @babel/preset-typescript and configure it in their babel.config.js

%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.0.x - see 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-dom` installs (see add_react_dependencies) and intentionally stays on the stable React 19.0.x line with a 19.0.4 minimum. Do not widen this to React 19.1/19.2 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 may accept the prerelease RSC package broadly enough to keep `npm ls` healthy, but generator behavior still installs the tested React 19.0.x range and exact RSC package pin until both policies advance.

"~19.0.4"
RSC_PACKAGE_VERSION_PIN =

Pinned to 19.0.5-rc.7 because the discovery plugin export, native Rspack plugin, and RSC manifest CSS fixes all ship in that prerelease. TODO(#3642): switch to a stable react-on-rails-rsc release after 19.0.5 stable ships.

"19.0.5-rc.7"