Skip to content

Commit 1e6d774

Browse files
authored
Add shakapacker:switch_bundler rake task (#660)
This new feature makes it easy to switch between webpack and rspack bundlers in Shakapacker applications, based on the switch-bundler script from react_on_rails-demos. Key features: - Automatically updates config/shakapacker.yml to switch bundler - Optional --install-deps flag to manage npm dependencies automatically - Support for custom dependencies via .shakapacker-switch-bundler-dependencies.yml - Preserves config file structure and comments during updates - Updates javascript_transpiler to swc when switching to rspack (recommended) Usage: rails shakapacker:switch_bundler [webpack|rspack] [--install-deps] rails shakapacker:switch_bundler --init-config # Create custom deps config rails shakapacker:switch_bundler --help # Show usage information
1 parent 2e5894d commit 1e6d774

10 files changed

Lines changed: 14341 additions & 513 deletions

File tree

CHANGELOG.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,20 @@ Changes since the last non-beta release.
3333

3434
### Added
3535

36+
- **New `shakapacker:switch_bundler` rake task** for easy switching between webpack and rspack
37+
- Automatically updates `config/shakapacker.yml` to switch bundler configuration
38+
- Optional `--install-deps` flag to automatically manage dependencies
39+
- `--no-uninstall` flag for faster switching by keeping both bundlers installed
40+
- **Supports all package managers**: Auto-detects and uses npm, yarn, pnpm, or bun
41+
- Shows clear list of packages being added/removed during dependency management
42+
- Support for custom dependency configuration via `.shakapacker-switch-bundler-dependencies.yml`
43+
- Includes SWC dependencies (`@swc/core`, `swc-loader`) in default webpack setup
44+
- Preserves config file structure and comments during updates
45+
- Updates `javascript_transpiler` to `swc` when switching to rspack (recommended)
46+
- Ruby 2.7+ compatible YAML loading with proper alias/anchor support
47+
- Secure command execution (prevents shell injection)
48+
- Usage: `rails shakapacker:switch_bundler [webpack|rspack] [--install-deps] [--no-uninstall]`
49+
- See rake task help: `rails shakapacker:switch_bundler --help`
3650
- **Stimulus compatibility built into SWC migration** ([#657](https://github.com/shakacode/shakapacker/issues/657))
3751
- `rake shakapacker:migrate_to_swc` now creates `config/swc.config.js` with `keepClassNames: true`
3852
- Prevents SWC from mangling class names, which breaks Stimulus controller discovery

README.md

Lines changed: 152 additions & 106 deletions
Large diffs are not rendered by default.

docs/rspack_migration_guide.md

Lines changed: 90 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,21 @@
11
# Rspack Migration Guide for Shakapacker
22

33
## Overview
4+
45
This guide documents the differences between webpack and Rspack configurations in Shakapacker, and provides migration guidance for users switching to Rspack.
56

67
## Key Differences from Webpack
78

89
### 1. Built-in Loaders
10+
911
Rspack provides built-in loaders for better performance:
1012

1113
**JavaScript/TypeScript:**
14+
1215
- Use `builtin:swc-loader` instead of `babel-loader` or `ts-loader`
1316
- 20x faster than Babel on single thread, 70x on multiple cores
1417
- Configuration example:
18+
1519
```javascript
1620
{
1721
test: /\.(js|jsx|ts|tsx)$/,
@@ -36,36 +40,44 @@ Rspack provides built-in loaders for better performance:
3640
### 2. Plugin Replacements
3741

3842
#### Built-in Rspack Alternatives
39-
| Webpack Plugin | Rspack Alternative | Status |
40-
|---------------|-------------------|---------|
41-
| `copy-webpack-plugin` | `rspack.CopyRspackPlugin` | ✅ Built-in |
42-
| `mini-css-extract-plugin` | `rspack.CssExtractRspackPlugin` | ✅ Built-in |
43-
| `terser-webpack-plugin` | `rspack.SwcJsMinimizerRspackPlugin` | ✅ Built-in |
43+
44+
| Webpack Plugin | Rspack Alternative | Status |
45+
| ------------------------------ | ------------------------------------------ | ----------- |
46+
| `copy-webpack-plugin` | `rspack.CopyRspackPlugin` | ✅ Built-in |
47+
| `mini-css-extract-plugin` | `rspack.CssExtractRspackPlugin` | ✅ Built-in |
48+
| `terser-webpack-plugin` | `rspack.SwcJsMinimizerRspackPlugin` | ✅ Built-in |
4449
| `css-minimizer-webpack-plugin` | `rspack.LightningCssMinimizerRspackPlugin` | ✅ Built-in |
4550

4651
#### Community Alternatives
47-
| Webpack Plugin | Rspack Alternative | Package |
48-
|---------------|-------------------|----------|
49-
| `fork-ts-checker-webpack-plugin` | `ts-checker-rspack-plugin` | `npm i -D ts-checker-rspack-plugin` |
52+
53+
| Webpack Plugin | Rspack Alternative | Package |
54+
| -------------------------------------- | ------------------------------ | --------------------------------------- |
55+
| `fork-ts-checker-webpack-plugin` | `ts-checker-rspack-plugin` | `npm i -D ts-checker-rspack-plugin` |
5056
| `@pmmmwh/react-refresh-webpack-plugin` | `@rspack/plugin-react-refresh` | `npm i -D @rspack/plugin-react-refresh` |
51-
| `eslint-webpack-plugin` | `eslint-rspack-plugin` | `npm i -D eslint-rspack-plugin` |
57+
| `eslint-webpack-plugin` | `eslint-rspack-plugin` | `npm i -D eslint-rspack-plugin` |
5258

5359
#### Incompatible Plugins
60+
5461
The following webpack plugins are NOT compatible with Rspack:
62+
5563
- `webpack.optimize.LimitChunkCountPlugin` - Use `optimization.splitChunks` configuration instead
5664
- `webpack-manifest-plugin` - Use `rspack-manifest-plugin` instead
5765
- Git revision plugins - Use alternative approaches
5866

5967
### 3. Asset Module Types
68+
6069
Replace file loaders with asset modules:
70+
6171
- `file-loader``type: 'asset/resource'`
6272
- `url-loader``type: 'asset/inline'`
6373
- `raw-loader``type: 'asset/source'`
6474

6575
### 4. Configuration Differences
6676

6777
#### TypeScript Configuration
78+
6879
**Required:** Add `isolatedModules: true` to your `tsconfig.json`:
80+
6981
```json
7082
{
7183
"compilerOptions": {
@@ -75,22 +87,22 @@ Replace file loaders with asset modules:
7587
```
7688

7789
#### React Fast Refresh
90+
7891
```javascript
7992
// Development configuration
80-
const ReactRefreshPlugin = require('@rspack/plugin-react-refresh');
93+
const ReactRefreshPlugin = require("@rspack/plugin-react-refresh")
8194

8295
module.exports = {
83-
plugins: [
84-
new ReactRefreshPlugin(),
85-
new rspack.HotModuleReplacementPlugin()
86-
]
87-
};
96+
plugins: [new ReactRefreshPlugin(), new rspack.HotModuleReplacementPlugin()]
97+
}
8898
```
8999

90100
### 5. Optimization Differences
91101

92102
#### Code Splitting
103+
93104
Rspack's `splitChunks` configuration is similar to webpack but with some differences:
105+
94106
```javascript
95107
optimization: {
96108
splitChunks: {
@@ -107,6 +119,7 @@ optimization: {
107119
```
108120

109121
#### Minimization
122+
110123
```javascript
111124
optimization: {
112125
minimize: true,
@@ -118,7 +131,9 @@ optimization: {
118131
```
119132

120133
### 6. Development Server
134+
121135
Rspack uses its own dev server with some configuration differences:
136+
122137
```javascript
123138
devServer: {
124139
// Rspack-specific: Force writing assets to disk
@@ -130,7 +145,55 @@ devServer: {
130145

131146
## Migration Checklist
132147

148+
### Quick Start: Using the Switch Bundler Task
149+
150+
Shakapacker provides a convenient rake task to switch between webpack and rspack:
151+
152+
```bash
153+
# Switch to rspack with automatic dependency management
154+
rails shakapacker:switch_bundler rspack --install-deps
155+
# or with rake (note the -- separator)
156+
rake shakapacker:switch_bundler rspack -- --install-deps
157+
158+
# Fast switching without uninstalling old bundler (keeps both)
159+
rails shakapacker:switch_bundler webpack --install-deps --no-uninstall
160+
rake shakapacker:switch_bundler rspack -- --install-deps --no-uninstall
161+
162+
# Switch to rspack manually (you manage dependencies yourself)
163+
rails shakapacker:switch_bundler rspack
164+
rake shakapacker:switch_bundler rspack
165+
166+
# Switch back to webpack if needed
167+
rails shakapacker:switch_bundler webpack --install-deps
168+
rake shakapacker:switch_bundler webpack -- --install-deps
169+
170+
# Show help
171+
rails shakapacker:switch_bundler --help
172+
rake shakapacker:switch_bundler -- --help
173+
```
174+
175+
**Note:** When using `rake`, you must use `--` to separate rake options from task arguments.
176+
177+
The task will:
178+
179+
- Update `config/shakapacker.yml` to switch the bundler
180+
- Optionally install/uninstall npm dependencies with `--install-deps`
181+
- Use `--no-uninstall` to skip uninstalling the old bundler's packages (faster switching, keeps both bundlers installed)
182+
- Update `javascript_transpiler` to `swc` when switching to rspack (recommended)
183+
- Preserve your config file comments and structure
184+
185+
**Custom Dependencies:** You can customize which dependencies are installed by creating a `.shakapacker-switch-bundler-dependencies.yml` file:
186+
187+
```bash
188+
rails shakapacker:switch_bundler --init-config
189+
```
190+
191+
### Manual Migration Steps
192+
193+
If you prefer to migrate manually or need more control:
194+
133195
### Step 1: Update Dependencies
196+
134197
```bash
135198
# Remove webpack dependencies
136199
npm uninstall webpack webpack-cli webpack-dev-server
@@ -140,27 +203,33 @@ npm install --save-dev @rspack/core @rspack/cli
140203
```
141204

142205
### Step 2: Update Configuration Files
206+
143207
1. Create `config/rspack/rspack.config.js` based on your webpack config
144208
2. Update `config/shakapacker.yml`:
209+
145210
```yaml
146-
assets_bundler: 'rspack'
211+
assets_bundler: "rspack"
147212
```
148213
149214
### Step 3: Replace Loaders
215+
150216
- Replace `babel-loader` with `builtin:swc-loader`
151217
- Remove `file-loader`, `url-loader`, `raw-loader` - use asset modules
152218
- Update CSS loaders to use Rspack's built-in support
153219

154220
### Step 4: Update Plugins
221+
155222
- Replace plugins with Rspack alternatives (see table above)
156223
- Remove incompatible plugins
157224
- Add Rspack-specific plugins as needed
158225

159226
### Step 5: TypeScript Setup
227+
160228
1. Add `isolatedModules: true` to `tsconfig.json`
161229
2. Optional: Add `ts-checker-rspack-plugin` for type checking
162230

163231
### Step 6: Test Your Build
232+
164233
```bash
165234
# Development build
166235
bin/shakapacker
@@ -172,18 +241,22 @@ bin/shakapacker --mode production
172241
## Common Issues and Solutions
173242

174243
### Issue: LimitChunkCountPlugin Error
244+
175245
**Error:** `Cannot read properties of undefined (reading 'tap')`
176246
**Solution:** Remove `webpack.optimize.LimitChunkCountPlugin` and use `splitChunks` configuration instead.
177247

178248
### Issue: Missing Loaders
249+
179250
**Error:** Module parse errors
180251
**Solution:** Check console logs for skipped loaders and install missing dependencies.
181252

182253
### Issue: CSS Extraction
254+
183255
**Error:** CSS not being extracted properly
184256
**Solution:** Use `rspack.CssExtractRspackPlugin` instead of `mini-css-extract-plugin`.
185257

186258
### Issue: TypeScript Errors
259+
187260
**Error:** TypeScript compilation errors
188261
**Solution:** Ensure `isolatedModules: true` is set in `tsconfig.json`.
189262

@@ -199,4 +272,4 @@ bin/shakapacker --mode production
199272
- [Rspack Documentation](https://rspack.rs)
200273
- [Rspack Examples](https://github.com/rspack-contrib/rspack-examples)
201274
- [Awesome Rspack](https://github.com/rspack-contrib/awesome-rspack)
202-
- [Migration Guide](https://rspack.rs/guide/migration/webpack)
275+
- [Migration Guide](https://rspack.rs/guide/migration/webpack)

0 commit comments

Comments
 (0)