Skip to content

Commit 0b00514

Browse files
authored
Add --rspack generator option for faster builds (#1852)
Add --rspack generator option for faster builds (#1852) Why Webpack builds are slow, impacting developer productivity and CI times. Summary Adds --rspack flag to generator for ~20x faster builds with unified webpack/rspack configuration and bin/switch-bundler utility. Key improvements - Generator --rspack flag installs Rspack packages and configures SWC - Unified webpack configs detect bundler, load correct plugins - bin/switch-bundler safely switches between bundlers post-install Impact - Existing: No changes, webpack remains default bundler - New: Can use --rspack flag for significantly faster builds Risks None. Feature is opt-in with fallback to webpack as default.
1 parent 82a8232 commit 0b00514

File tree

12 files changed

+636
-17
lines changed

12 files changed

+636
-17
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ Changes since the last non-beta release.
2525

2626
#### Added
2727

28+
- **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).
29+
2830
- **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).
2931

3032
- **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).

README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

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

23+
- **⚡ 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.
2324
- **ESM-only package**: Modern module system with better tree-shaking and performance
2425
- **React Server Components**: Improved rendering flow and new `RSCRoute` component for seamless SSR
2526
- **Performance improvements**: New async loading strategies and optimized bundle generation
@@ -111,8 +112,9 @@ To provide a high-performance framework for integrating Ruby on Rails with React
111112

112113
| Feature | Benefit |
113114
| ----------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
115+
|**Rspack Support** | [~20x faster builds](./docs/api-reference/generator-details.md#rspack-support) with Rspack bundler - dramatically reduce build times in development and CI |
114116
| 🎯 **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 |
115-
| **Server-Side Rendering** | Enhanced React Server Components support for better SEO and UX performance |
117+
| 🌟 **Server-Side Rendering** | Enhanced React Server Components support for better SEO and UX performance |
116118
| 🚀 **Advanced Loading** | `sync`, `async`, and `defer` options for optimal performance based on your needs |
117119
| 🔥 **Hot Module Replacement** | Instant feedback during development with tight [Shakapacker](https://github.com/shakacode/shakapacker) integration |
118120
| 📦 **Easy Props Passing** | Direct Rails → React data flow without separate API calls |

RSPACK_IMPLEMENTATION.md

Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
# Rspack Generator Option Implementation
2+
3+
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).
4+
5+
## Overview
6+
7+
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).
8+
9+
## Changes Made
10+
11+
### 1. Install Generator (`lib/generators/react_on_rails/install_generator.rb`)
12+
13+
- **Added `--rspack` class option** (line 31-35): Boolean flag to enable Rspack bundler
14+
- **Updated `invoke_generators`** (line 82-83): Pass rspack option to base generator
15+
- **Added `add_rspack_dependencies` method** (line 499-513): Installs Rspack core packages:
16+
- `@rspack/core`
17+
- `rspack-manifest-plugin`
18+
- **Updated `add_dev_dependencies`** (line 515-534): Conditionally installs rspack or webpack refresh plugins:
19+
- Rspack: `@rspack/cli`, `@rspack/plugin-react-refresh`, `react-refresh`
20+
- Webpack: `@pmmmwh/react-refresh-webpack-plugin`, `react-refresh`
21+
- **Updated `add_js_dependencies`** (line 433): Calls `add_rspack_dependencies` when rspack flag is set
22+
23+
### 2. Base Generator (`lib/generators/react_on_rails/base_generator.rb`)
24+
25+
- **Added `--rspack` class option** (line 22-26): Boolean flag (passed from install generator)
26+
- **Updated `copy_packer_config`** (line 85-100): Calls `configure_rspack_in_shakapacker` after copying config
27+
- **Added `configure_rspack_in_shakapacker` method** (line 404-426):
28+
- Adds `assets_bundler: 'rspack'` to shakapacker.yml default section
29+
- Changes `webpack_loader` to `'swc'` (Rspack works best with SWC transpiler)
30+
31+
### 3. Webpack Configuration Templates
32+
33+
Updated webpack configuration templates to support both webpack and rspack bundlers with unified config approach:
34+
35+
**development.js.tt**:
36+
37+
- Added `config` to shakapacker require to access `assets_bundler` setting
38+
- Conditional React Refresh plugin loading based on `config.assets_bundler`:
39+
- Rspack: Uses `@rspack/plugin-react-refresh`
40+
- Webpack: Uses `@pmmmwh/react-refresh-webpack-plugin`
41+
- Prevents "window not found" errors when using rspack
42+
43+
**serverWebpackConfig.js.tt**:
44+
45+
- Added `bundler` variable that conditionally requires `@rspack/core` or `webpack`
46+
- Changed `webpack.optimize.LimitChunkCountPlugin` to `bundler.optimize.LimitChunkCountPlugin`
47+
- Enables same config to work with both bundlers without warnings
48+
- Avoids hardcoding webpack-specific imports
49+
50+
### 4. Bundler Switching Script (`lib/generators/react_on_rails/templates/base/base/bin/switch-bundler`)
51+
52+
Created a new executable script that allows switching between webpack and rspack after installation:
53+
54+
**Features:**
55+
56+
- Updates `shakapacker.yml` with correct `assets_bundler` setting
57+
- Switches `webpack_loader` between 'swc' (rspack) and 'babel' (webpack)
58+
- Removes old bundler dependencies from package.json
59+
- Installs new bundler dependencies
60+
- Supports npm, yarn, and pnpm package managers
61+
- Auto-detects package manager from lock files
62+
63+
**Usage:**
64+
65+
```bash
66+
bin/switch-bundler rspack # Switch to Rspack
67+
bin/switch-bundler webpack # Switch to Webpack
68+
```
69+
70+
**Dependencies managed:**
71+
72+
- **Webpack**: webpack, webpack-cli, webpack-dev-server, webpack-assets-manifest, webpack-merge, @pmmmwh/react-refresh-webpack-plugin
73+
- **Rspack**: @rspack/core, @rspack/cli, @rspack/plugin-react-refresh, rspack-manifest-plugin
74+
75+
## Usage
76+
77+
### Generate new app with Rspack:
78+
79+
```bash
80+
rails generate react_on_rails:install --rspack
81+
```
82+
83+
### Generate with Rspack and TypeScript:
84+
85+
```bash
86+
rails generate react_on_rails:install --rspack --typescript
87+
```
88+
89+
### Generate with Rspack and Redux:
90+
91+
```bash
92+
rails generate react_on_rails:install --rspack --redux
93+
```
94+
95+
### Switch existing app to Rspack:
96+
97+
```bash
98+
bin/switch-bundler rspack
99+
```
100+
101+
## Configuration Changes
102+
103+
When `--rspack` is used, the following configuration changes are applied to `config/shakapacker.yml`:
104+
105+
```yaml
106+
default: &default
107+
source_path: app/javascript
108+
assets_bundler: 'rspack' # Added
109+
# ... other settings
110+
webpack_loader: 'swc' # Changed from 'babel'
111+
```
112+
113+
## Dependencies
114+
115+
### Rspack-specific packages installed:
116+
117+
**Production:**
118+
119+
- `@rspack/core` - Core Rspack bundler
120+
- `rspack-manifest-plugin` - Manifest generation for Rspack
121+
122+
**Development:**
123+
124+
- `@rspack/cli` - Rspack CLI tools
125+
- `@rspack/plugin-react-refresh` - React Fast Refresh for Rspack
126+
- `react-refresh` - React Fast Refresh runtime
127+
128+
### Webpack packages NOT installed with --rspack:
129+
130+
**Production:**
131+
132+
- `webpack`
133+
- `webpack-assets-manifest`
134+
- `webpack-merge`
135+
136+
**Development:**
137+
138+
- `webpack-cli`
139+
- `webpack-dev-server`
140+
- `@pmmmwh/react-refresh-webpack-plugin`
141+
142+
## Performance Benefits
143+
144+
According to PR #20:
145+
146+
- Build times: ~53-270ms with Rspack vs typical webpack builds
147+
- Approximately 20x faster transpilation with SWC (used by Rspack)
148+
- Faster development builds and CI runs
149+
150+
## Testing
151+
152+
The implementation follows existing generator patterns and passes RuboCop checks with zero offenses.
153+
154+
## Compatibility
155+
156+
- Works with existing webpack configuration files (unified config approach)
157+
- Compatible with TypeScript option (`--typescript`)
158+
- Compatible with Redux option (`--redux`)
159+
- Supports all package managers (npm, yarn, pnpm)
160+
- Reversible via `bin/switch-bundler` script

docs/api-reference/generator-details.md

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ Usage:
1010
1111
Options:
1212
-R, [--redux], [--no-redux] # Install Redux package and Redux version of Hello World Example. Default: false
13+
-T, [--typescript], [--no-typescript] # Generate TypeScript files and install TypeScript dependencies. Default: false
14+
[--rspack], [--no-rspack] # Use Rspack instead of Webpack as the bundler. Default: false
1315
[--ignore-warnings], [--no-ignore-warnings] # Skip warnings. Default: false
1416
1517
Runtime options:
@@ -29,6 +31,18 @@ can pass the redux option if you'd like to have redux setup for you automaticall
2931
to integrate the Redux state container framework. The necessary node modules
3032
will be automatically included for you.
3133
34+
* TypeScript
35+
36+
Passing the --typescript generator option generates TypeScript files (.tsx)
37+
instead of JavaScript files (.jsx) and sets up TypeScript configuration.
38+
39+
* Rspack
40+
41+
Passing the --rspack generator option uses Rspack instead of Webpack as the
42+
bundler, providing significantly faster builds (~20x improvement with SWC).
43+
Includes unified configuration that works with both bundlers and a
44+
bin/switch-bundler utility to switch between bundlers post-installation.
45+
3246
*******************************************************************************
3347
3448
@@ -106,6 +120,68 @@ rails generate react_on_rails:install --typescript
106120

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

123+
### Rspack Support
124+
125+
The generator supports a `--rspack` option for using Rspack instead of Webpack as the bundler:
126+
127+
```bash
128+
rails generate react_on_rails:install --rspack
129+
```
130+
131+
**Benefits:**
132+
133+
- **~20x faster builds** with SWC transpilation (build times of ~53-270ms vs typical webpack builds)
134+
- **Unified configuration** - same webpack config files work for both bundlers
135+
- **Easy switching** - includes `bin/switch-bundler` utility to switch between bundlers post-installation
136+
137+
**What gets installed:**
138+
139+
- Rspack core packages (`@rspack/core`, `@rspack/cli`)
140+
- Rspack-specific plugins (`@rspack/plugin-react-refresh`, `rspack-manifest-plugin`)
141+
- Shakapacker configured with `assets_bundler: 'rspack'` and `webpack_loader: 'swc'`
142+
143+
**Switching bundlers after installation:**
144+
145+
```bash
146+
# Switch to Rspack
147+
bin/switch-bundler rspack
148+
149+
# Switch back to Webpack
150+
bin/switch-bundler webpack
151+
```
152+
153+
The switch-bundler script automatically:
154+
155+
- Updates shakapacker.yml configuration
156+
- Installs/removes appropriate dependencies
157+
- Works with npm, yarn, and pnpm
158+
159+
**Limitations of `bin/switch-bundler`:**
160+
161+
The switch-bundler utility handles the standard configuration and dependencies, but has some limitations:
162+
163+
- **Custom webpack plugins**: Does not modify custom webpack plugins or loaders in your config files
164+
- **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))
165+
- **Third-party dependencies**: Does not detect or update third-party webpack-specific packages you may have added
166+
- **YAML formatting**: Uses YAML.dump which may change formatting/whitespace (but preserves functionality)
167+
168+
For apps with custom webpack configurations, review the generated config templates to understand the unified configuration patterns that work with both bundlers.
169+
170+
**Combining with other options:**
171+
172+
```bash
173+
# Rspack with TypeScript
174+
rails generate react_on_rails:install --rspack --typescript
175+
176+
# Rspack with Redux
177+
rails generate react_on_rails:install --rspack --redux
178+
179+
# All options combined
180+
rails generate react_on_rails:install --rspack --typescript --redux
181+
```
182+
183+
For more details on Rspack configuration, see the [Webpack Configuration](../core-concepts/webpack-configuration.md#rspack-vs-webpack) docs.
184+
109185
### Auto-Bundling and Component Registration
110186

111187
Modern React on Rails uses auto-bundling to eliminate manual webpack configuration. Components placed in the configured `components_subdirectory` (default: `ror_components`) are automatically:

docs/core-concepts/webpack-configuration.md

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,73 @@
1111

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

14+
## Rspack vs. Webpack
15+
16+
[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.
17+
18+
### Using Rspack
19+
20+
Generate a new app with Rspack:
21+
22+
```bash
23+
rails generate react_on_rails:install --rspack
24+
```
25+
26+
Or switch an existing app to Rspack:
27+
28+
```bash
29+
bin/switch-bundler rspack
30+
```
31+
32+
### Performance Benefits
33+
34+
- **Build times**: ~53-270ms with Rspack vs typical webpack builds
35+
- **~20x faster transpilation** with SWC (used by Rspack)
36+
- **Faster development** builds and CI runs
37+
38+
### Unified Configuration
39+
40+
React on Rails generates unified webpack configuration files that work with both bundlers:
41+
42+
**config/webpack/development.js** - Conditional plugin loading:
43+
44+
```javascript
45+
const { config } = require('shakapacker');
46+
47+
if (config.assets_bundler === 'rspack') {
48+
// Rspack uses @rspack/plugin-react-refresh
49+
const ReactRefreshPlugin = require('@rspack/plugin-react-refresh');
50+
clientWebpackConfig.plugins.push(new ReactRefreshPlugin());
51+
} else {
52+
// Webpack uses @pmmmwh/react-refresh-webpack-plugin
53+
const ReactRefreshWebpackPlugin = require('@pmmmwh/react-refresh-webpack-plugin');
54+
clientWebpackConfig.plugins.push(new ReactRefreshWebpackPlugin());
55+
}
56+
```
57+
58+
**config/webpack/serverWebpackConfig.js** - Dynamic bundler detection:
59+
60+
```javascript
61+
const { config } = require('shakapacker');
62+
63+
const bundler = config.assets_bundler === 'rspack' ? require('@rspack/core') : require('webpack');
64+
65+
// Use bundler-specific APIs
66+
serverWebpackConfig.plugins.unshift(new bundler.optimize.LimitChunkCountPlugin({ maxChunks: 1 }));
67+
```
68+
69+
### Configuration in shakapacker.yml
70+
71+
Rspack configuration is controlled via `config/shakapacker.yml`:
72+
73+
```yaml
74+
default: &default
75+
assets_bundler: 'rspack' # or 'webpack'
76+
webpack_loader: 'swc' # Rspack works best with SWC
77+
```
78+
79+
The `bin/switch-bundler` script automatically updates this configuration when switching bundlers.
80+
1481
Per the example repo [shakacode/react_on_rails_demo_ssr_hmr](https://github.com/shakacode/react_on_rails_demo_ssr_hmr),
1582
you should consider keeping your codebase mostly consistent with the defaults for [Shakapacker](https://github.com/shakacode/shakapacker).
1683

docs/getting-started/quick-start.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,9 @@ git add . && git commit -m "Add react_on_rails gem"
3131

3232
# Run the installer
3333
bin/rails generate react_on_rails:install
34+
35+
# Optional: Use Rspack for ~20x faster builds
36+
# bin/rails generate react_on_rails:install --rspack
3437
```
3538

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

47+
> 💡 **Performance Tip:** Add the `--rspack` flag for significantly faster builds (~20x improvement). You can also switch bundlers later with `bin/switch-bundler rspack`.
48+
>
49+
> **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.
50+
4451
## 🎯 Step 2: Start the Development Server (1 minute)
4552

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

0 commit comments

Comments
 (0)