Skip to content
Merged
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
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ Changes since the last non-beta release.

#### Added

- **Rspack Support**: Added `--rspack` flag to `react_on_rails:install` generator for significantly faster builds (~20x improvement with SWC). Includes unified webpack/rspack configuration templates and `bin/switch-bundler` utility to switch between bundlers post-installation. [PR #1852](https://github.com/shakacode/react_on_rails/pull/1852) by [justin808](https://github.com/justin808).

- **Attribution Comment**: Added HTML comment attribution to Rails views containing React on Rails functionality. The comment automatically displays which version is in use (open source React on Rails or React on Rails Pro) and, for Pro users, shows the license status. This helps identify React on Rails usage across your application. [PR #1857](https://github.com/shakacode/react_on_rails/pull/1857) by [AbanoubGhadban](https://github.com/AbanoubGhadban).

- **Improved Error Messages**: Error messages for version mismatches and package configuration issues now include package-manager-specific installation commands (npm, yarn, pnpm, bun). [PR #1881](https://github.com/shakacode/react_on_rails/pull/1881) by [AbanoubGhadban](https://github.com/AbanoubGhadban).
Expand Down
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

**🚀 React on Rails v16.0 Released!** Major modernization with ESM support, enhanced React Server Components, and streamlined configuration.

- **⚡ Rspack Support**: New `--rspack` generator flag for ~20x faster builds! Use Rspack instead of Webpack for dramatically improved build performance. See [Rspack documentation](https://www.shakacode.com/react-on-rails/docs/api/generator-details#rspack-support) for details.
- **ESM-only package**: Modern module system with better tree-shaking and performance
- **React Server Components**: Improved rendering flow and new `RSCRoute` component for seamless SSR
- **Performance improvements**: New async loading strategies and optimized bundle generation
Expand Down Expand Up @@ -111,8 +112,9 @@ To provide a high-performance framework for integrating Ruby on Rails with React

| Feature | Benefit |
| ----------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| ⚡ **Rspack Support** | [~20x faster builds](./docs/api-reference/generator-details.md#rspack-support) with Rspack bundler - dramatically reduce build times in development and CI |
| 🎯 **Smart Bundle Loading** | [Automated bundle optimization](./docs/guides/auto-bundling-file-system-based-automated-bundle-generation.md) based on components used - no more manual `javascript_pack_tags` configuration |
| **Server-Side Rendering** | Enhanced React Server Components support for better SEO and UX performance |
| 🌟 **Server-Side Rendering** | Enhanced React Server Components support for better SEO and UX performance |
| 🚀 **Advanced Loading** | `sync`, `async`, and `defer` options for optimal performance based on your needs |
| 🔥 **Hot Module Replacement** | Instant feedback during development with tight [Shakapacker](https://github.com/shakacode/shakapacker) integration |
| 📦 **Easy Props Passing** | Direct Rails → React data flow without separate API calls |
Expand Down
160 changes: 160 additions & 0 deletions RSPACK_IMPLEMENTATION.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
# Rspack Generator Option Implementation

This document summarizes the implementation of the `--rspack` option for the React on Rails generator, based on the patterns from [PR #20 in react_on_rails-demos](https://github.com/shakacode/react_on_rails-demos/pull/20).

## Overview

The `--rspack` flag allows users to generate a React on Rails application using Rspack instead of Webpack as the bundler. Rspack provides significantly faster build times (~53-270ms vs typical webpack builds).

## Changes Made

### 1. Install Generator (`lib/generators/react_on_rails/install_generator.rb`)

- **Added `--rspack` class option** (line 31-35): Boolean flag to enable Rspack bundler
- **Updated `invoke_generators`** (line 82-83): Pass rspack option to base generator
- **Added `add_rspack_dependencies` method** (line 499-513): Installs Rspack core packages:
- `@rspack/core`
- `rspack-manifest-plugin`
- **Updated `add_dev_dependencies`** (line 515-534): Conditionally installs rspack or webpack refresh plugins:
- Rspack: `@rspack/cli`, `@rspack/plugin-react-refresh`, `react-refresh`
- Webpack: `@pmmmwh/react-refresh-webpack-plugin`, `react-refresh`
- **Updated `add_js_dependencies`** (line 433): Calls `add_rspack_dependencies` when rspack flag is set

### 2. Base Generator (`lib/generators/react_on_rails/base_generator.rb`)

- **Added `--rspack` class option** (line 22-26): Boolean flag (passed from install generator)
- **Updated `copy_packer_config`** (line 85-100): Calls `configure_rspack_in_shakapacker` after copying config
- **Added `configure_rspack_in_shakapacker` method** (line 404-426):
- Adds `assets_bundler: 'rspack'` to shakapacker.yml default section
- Changes `webpack_loader` to `'swc'` (Rspack works best with SWC transpiler)

### 3. Webpack Configuration Templates

Updated webpack configuration templates to support both webpack and rspack bundlers with unified config approach:

**development.js.tt**:

- Added `config` to shakapacker require to access `assets_bundler` setting
- Conditional React Refresh plugin loading based on `config.assets_bundler`:
- Rspack: Uses `@rspack/plugin-react-refresh`
- Webpack: Uses `@pmmmwh/react-refresh-webpack-plugin`
- Prevents "window not found" errors when using rspack

**serverWebpackConfig.js.tt**:

- Added `bundler` variable that conditionally requires `@rspack/core` or `webpack`
- Changed `webpack.optimize.LimitChunkCountPlugin` to `bundler.optimize.LimitChunkCountPlugin`
- Enables same config to work with both bundlers without warnings
- Avoids hardcoding webpack-specific imports

### 4. Bundler Switching Script (`lib/generators/react_on_rails/templates/base/base/bin/switch-bundler`)

Created a new executable script that allows switching between webpack and rspack after installation:

**Features:**

- Updates `shakapacker.yml` with correct `assets_bundler` setting
- Switches `webpack_loader` between 'swc' (rspack) and 'babel' (webpack)
- Removes old bundler dependencies from package.json
- Installs new bundler dependencies
- Supports npm, yarn, and pnpm package managers
- Auto-detects package manager from lock files

**Usage:**

```bash
bin/switch-bundler rspack # Switch to Rspack
bin/switch-bundler webpack # Switch to Webpack
```

**Dependencies managed:**

- **Webpack**: webpack, webpack-cli, webpack-dev-server, webpack-assets-manifest, webpack-merge, @pmmmwh/react-refresh-webpack-plugin
- **Rspack**: @rspack/core, @rspack/cli, @rspack/plugin-react-refresh, rspack-manifest-plugin

## Usage

### Generate new app with Rspack:

```bash
rails generate react_on_rails:install --rspack
```

### Generate with Rspack and TypeScript:

```bash
rails generate react_on_rails:install --rspack --typescript
```

### Generate with Rspack and Redux:

```bash
rails generate react_on_rails:install --rspack --redux
```

### Switch existing app to Rspack:

```bash
bin/switch-bundler rspack
```

## Configuration Changes

When `--rspack` is used, the following configuration changes are applied to `config/shakapacker.yml`:

```yaml
default: &default
source_path: app/javascript
assets_bundler: 'rspack' # Added
# ... other settings
webpack_loader: 'swc' # Changed from 'babel'
```

## Dependencies

### Rspack-specific packages installed:

**Production:**

- `@rspack/core` - Core Rspack bundler
- `rspack-manifest-plugin` - Manifest generation for Rspack

**Development:**

- `@rspack/cli` - Rspack CLI tools
- `@rspack/plugin-react-refresh` - React Fast Refresh for Rspack
- `react-refresh` - React Fast Refresh runtime

### Webpack packages NOT installed with --rspack:

**Production:**

- `webpack`
- `webpack-assets-manifest`
- `webpack-merge`

**Development:**

- `webpack-cli`
- `webpack-dev-server`
- `@pmmmwh/react-refresh-webpack-plugin`

## Performance Benefits

According to PR #20:

- Build times: ~53-270ms with Rspack vs typical webpack builds
- Approximately 20x faster transpilation with SWC (used by Rspack)
- Faster development builds and CI runs

## Testing

The implementation follows existing generator patterns and passes RuboCop checks with zero offenses.

## Compatibility

- Works with existing webpack configuration files (unified config approach)
- Compatible with TypeScript option (`--typescript`)
- Compatible with Redux option (`--redux`)
- Supports all package managers (npm, yarn, pnpm)
- Reversible via `bin/switch-bundler` script
76 changes: 76 additions & 0 deletions docs/api-reference/generator-details.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ Usage:

Options:
-R, [--redux], [--no-redux] # Install Redux package and Redux version of Hello World Example. Default: false
-T, [--typescript], [--no-typescript] # Generate TypeScript files and install TypeScript dependencies. Default: false
[--rspack], [--no-rspack] # Use Rspack instead of Webpack as the bundler. Default: false
[--ignore-warnings], [--no-ignore-warnings] # Skip warnings. Default: false

Runtime options:
Expand All @@ -29,6 +31,18 @@ can pass the redux option if you'd like to have redux setup for you automaticall
to integrate the Redux state container framework. The necessary node modules
will be automatically included for you.

* TypeScript

Passing the --typescript generator option generates TypeScript files (.tsx)
instead of JavaScript files (.jsx) and sets up TypeScript configuration.

* Rspack

Passing the --rspack generator option uses Rspack instead of Webpack as the
bundler, providing significantly faster builds (~20x improvement with SWC).
Includes unified configuration that works with both bundlers and a
bin/switch-bundler utility to switch between bundlers post-installation.

*******************************************************************************


Expand Down Expand Up @@ -106,6 +120,68 @@ rails generate react_on_rails:install --typescript

This creates `.tsx` files instead of `.jsx` and adds TypeScript configuration.

### Rspack Support

The generator supports a `--rspack` option for using Rspack instead of Webpack as the bundler:

```bash
rails generate react_on_rails:install --rspack
```

**Benefits:**

- **~20x faster builds** with SWC transpilation (build times of ~53-270ms vs typical webpack builds)
- **Unified configuration** - same webpack config files work for both bundlers
- **Easy switching** - includes `bin/switch-bundler` utility to switch between bundlers post-installation

**What gets installed:**

- Rspack core packages (`@rspack/core`, `@rspack/cli`)
- Rspack-specific plugins (`@rspack/plugin-react-refresh`, `rspack-manifest-plugin`)
- Shakapacker configured with `assets_bundler: 'rspack'` and `webpack_loader: 'swc'`

**Switching bundlers after installation:**

```bash
# Switch to Rspack
bin/switch-bundler rspack

# Switch back to Webpack
bin/switch-bundler webpack
```

The switch-bundler script automatically:

- Updates shakapacker.yml configuration
- Installs/removes appropriate dependencies
- Works with npm, yarn, and pnpm

**Limitations of `bin/switch-bundler`:**

The switch-bundler utility handles the standard configuration and dependencies, but has some limitations:

- **Custom webpack plugins**: Does not modify custom webpack plugins or loaders in your config files
- **Manual updates needed**: If you have custom webpack configuration, you may need to update it to use unified patterns (see examples in [Webpack Configuration](../core-concepts/webpack-configuration.md#unified-configuration))
- **Third-party dependencies**: Does not detect or update third-party webpack-specific packages you may have added
- **YAML formatting**: Uses YAML.dump which may change formatting/whitespace (but preserves functionality)

For apps with custom webpack configurations, review the generated config templates to understand the unified configuration patterns that work with both bundlers.

**Combining with other options:**

```bash
# Rspack with TypeScript
rails generate react_on_rails:install --rspack --typescript

# Rspack with Redux
rails generate react_on_rails:install --rspack --redux

# All options combined
rails generate react_on_rails:install --rspack --typescript --redux
```

For more details on Rspack configuration, see the [Webpack Configuration](../core-concepts/webpack-configuration.md#rspack-vs-webpack) docs.

### Auto-Bundling and Component Registration

Modern React on Rails uses auto-bundling to eliminate manual webpack configuration. Components placed in the configured `components_subdirectory` (default: `ror_components`) are automatically:
Expand Down
67 changes: 67 additions & 0 deletions docs/core-concepts/webpack-configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,73 @@

To get a deeper understanding of Shakapacker, watch [RailsConf 2020 CE - Webpacker, It-Just-Works, But How? by Justin Gordon](https://youtu.be/sJLoOpc5LD8).

## Rspack vs. Webpack

[Rspack](https://rspack.dev/) is a high-performance JavaScript bundler written in Rust that provides significantly faster builds than Webpack (~20x improvement). React on Rails supports both bundlers through unified configuration.

### Using Rspack

Generate a new app with Rspack:

```bash
rails generate react_on_rails:install --rspack
```

Or switch an existing app to Rspack:

```bash
bin/switch-bundler rspack
```

### Performance Benefits

- **Build times**: ~53-270ms with Rspack vs typical webpack builds
- **~20x faster transpilation** with SWC (used by Rspack)
- **Faster development** builds and CI runs

### Unified Configuration

React on Rails generates unified webpack configuration files that work with both bundlers:

**config/webpack/development.js** - Conditional plugin loading:

```javascript
const { config } = require('shakapacker');

if (config.assets_bundler === 'rspack') {
// Rspack uses @rspack/plugin-react-refresh
const ReactRefreshPlugin = require('@rspack/plugin-react-refresh');
clientWebpackConfig.plugins.push(new ReactRefreshPlugin());
} else {
// Webpack uses @pmmmwh/react-refresh-webpack-plugin
const ReactRefreshWebpackPlugin = require('@pmmmwh/react-refresh-webpack-plugin');
clientWebpackConfig.plugins.push(new ReactRefreshWebpackPlugin());
}
```

**config/webpack/serverWebpackConfig.js** - Dynamic bundler detection:

```javascript
const { config } = require('shakapacker');

const bundler = config.assets_bundler === 'rspack' ? require('@rspack/core') : require('webpack');

// Use bundler-specific APIs
serverWebpackConfig.plugins.unshift(new bundler.optimize.LimitChunkCountPlugin({ maxChunks: 1 }));
```

### Configuration in shakapacker.yml

Rspack configuration is controlled via `config/shakapacker.yml`:

```yaml
default: &default
assets_bundler: 'rspack' # or 'webpack'
webpack_loader: 'swc' # Rspack works best with SWC
```

The `bin/switch-bundler` script automatically updates this configuration when switching bundlers.

Per the example repo [shakacode/react_on_rails_demo_ssr_hmr](https://github.com/shakacode/react_on_rails_demo_ssr_hmr),
you should consider keeping your codebase mostly consistent with the defaults for [Shakapacker](https://github.com/shakacode/shakapacker).

Expand Down
7 changes: 7 additions & 0 deletions docs/getting-started/quick-start.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ git add . && git commit -m "Add react_on_rails gem"

# Run the installer
bin/rails generate react_on_rails:install

# Optional: Use Rspack for ~20x faster builds
# bin/rails generate react_on_rails:install --rspack
```

Take a look at the files created by the generator.
Expand All @@ -41,6 +44,10 @@ Take a look at the files created by the generator.
- A sample controller and view
- Webpack configuration

> 💡 **Performance Tip:** Add the `--rspack` flag for significantly faster builds (~20x improvement). You can also switch bundlers later with `bin/switch-bundler rspack`.
>
> **Note on `bin/switch-bundler`:** This utility safely switches between webpack and rspack by updating `shakapacker.yml` and managing dependencies. However, it does not modify custom webpack configuration code. If you have custom webpack plugins or loaders, you may need to update those manually to work with rspack. See [Rspack documentation](../api-reference/generator-details.md#rspack-support) for details on unified configuration patterns.

## 🎯 Step 2: Start the Development Server (1 minute)

> **Note:** Ensure you have `overmind` or `foreman` installed to run `bin/dev`.
Expand Down
Loading
Loading