shakapacker 9.1.0 → 9.3.0.beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (123) hide show
  1. checksums.yaml +4 -4
  2. data/.github/ISSUE_TEMPLATE/bug_report.md +6 -9
  3. data/.github/ISSUE_TEMPLATE/feature_request.md +6 -8
  4. data/.github/workflows/claude-code-review.yml +4 -5
  5. data/.github/workflows/claude.yml +1 -2
  6. data/.github/workflows/dummy.yml +4 -4
  7. data/.github/workflows/generator.yml +9 -9
  8. data/.github/workflows/node.yml +11 -2
  9. data/.github/workflows/ruby.yml +16 -16
  10. data/.github/workflows/test-bundlers.yml +9 -9
  11. data/.gitignore +7 -0
  12. data/CHANGELOG.md +50 -4
  13. data/CLAUDE.md +6 -1
  14. data/CONTRIBUTING.md +0 -1
  15. data/Gemfile.lock +1 -1
  16. data/README.md +35 -14
  17. data/TODO.md +10 -2
  18. data/TODO_v9.md +13 -3
  19. data/bin/export-bundler-config +11 -0
  20. data/conductor-setup.sh +1 -1
  21. data/conductor.json +1 -1
  22. data/docs/cdn_setup.md +13 -8
  23. data/docs/common-upgrades.md +2 -1
  24. data/docs/configuration.md +630 -0
  25. data/docs/css-modules-export-mode.md +120 -100
  26. data/docs/customizing_babel_config.md +16 -16
  27. data/docs/deployment.md +68 -6
  28. data/docs/developing_shakapacker.md +6 -0
  29. data/docs/optional-peer-dependencies.md +9 -4
  30. data/docs/peer-dependencies.md +17 -6
  31. data/docs/precompile_hook.md +342 -0
  32. data/docs/react.md +57 -47
  33. data/docs/releasing.md +195 -0
  34. data/docs/rspack.md +25 -21
  35. data/docs/rspack_migration_guide.md +363 -8
  36. data/docs/sprockets.md +1 -0
  37. data/docs/style_loader_vs_mini_css.md +12 -12
  38. data/docs/subresource_integrity.md +13 -7
  39. data/docs/transpiler-performance.md +40 -19
  40. data/docs/troubleshooting.md +122 -23
  41. data/docs/typescript-migration.md +48 -39
  42. data/docs/typescript.md +12 -8
  43. data/docs/using_esbuild_loader.md +10 -10
  44. data/docs/v6_upgrade.md +33 -20
  45. data/docs/v7_upgrade.md +8 -6
  46. data/docs/v8_upgrade.md +13 -12
  47. data/docs/v9_upgrade.md +2 -1
  48. data/eslint.config.fast.js +134 -0
  49. data/eslint.config.js +140 -0
  50. data/knip.ts +54 -0
  51. data/lib/install/bin/export-bundler-config +11 -0
  52. data/lib/install/bin/shakapacker +1 -1
  53. data/lib/install/bin/shakapacker-dev-server +1 -1
  54. data/lib/install/config/shakapacker.yml +16 -5
  55. data/lib/shakapacker/bundler_switcher.rb +7 -0
  56. data/lib/shakapacker/compiler.rb +80 -0
  57. data/lib/shakapacker/configuration.rb +56 -2
  58. data/lib/shakapacker/dev_server_runner.rb +140 -1
  59. data/lib/shakapacker/doctor.rb +302 -57
  60. data/lib/shakapacker/instance.rb +8 -3
  61. data/lib/shakapacker/rspack_runner.rb +1 -1
  62. data/lib/shakapacker/runner.rb +245 -9
  63. data/lib/shakapacker/version.rb +1 -1
  64. data/lib/shakapacker/webpack_runner.rb +1 -1
  65. data/lib/shakapacker.rb +10 -0
  66. data/lib/tasks/shakapacker/doctor.rake +42 -2
  67. data/lib/tasks/shakapacker/export_bundler_config.rake +72 -0
  68. data/package/babel/preset.ts +7 -4
  69. data/package/config.ts +42 -30
  70. data/package/configExporter/cli.ts +1274 -0
  71. data/package/configExporter/configDocs.ts +102 -0
  72. data/package/configExporter/configFile.ts +520 -0
  73. data/package/configExporter/fileWriter.ts +96 -0
  74. data/package/configExporter/index.ts +13 -0
  75. data/package/configExporter/types.ts +70 -0
  76. data/package/configExporter/yamlSerializer.ts +280 -0
  77. data/package/dev_server.ts +1 -1
  78. data/package/environments/__type-tests__/rspack-plugin-compatibility.ts +11 -5
  79. data/package/environments/base.ts +18 -13
  80. data/package/environments/development.ts +1 -1
  81. data/package/environments/production.ts +4 -1
  82. data/package/index.d.ts +50 -3
  83. data/package/index.d.ts.template +50 -0
  84. data/package/index.ts +7 -7
  85. data/package/loaders.d.ts +2 -2
  86. data/package/optimization/rspack.ts +1 -1
  87. data/package/plugins/rspack.ts +15 -4
  88. data/package/plugins/webpack.ts +7 -3
  89. data/package/rspack/index.ts +10 -2
  90. data/package/rules/raw.ts +3 -2
  91. data/package/rules/sass.ts +1 -1
  92. data/package/types/README.md +15 -13
  93. data/package/types/index.ts +5 -5
  94. data/package/types.ts +0 -1
  95. data/package/utils/defaultConfigPath.ts +4 -1
  96. data/package/utils/errorCodes.ts +129 -100
  97. data/package/utils/errorHelpers.ts +34 -29
  98. data/package/utils/getStyleRule.ts +5 -2
  99. data/package/utils/helpers.ts +21 -11
  100. data/package/utils/pathValidation.ts +43 -35
  101. data/package/utils/requireOrError.ts +1 -1
  102. data/package/utils/snakeToCamelCase.ts +1 -1
  103. data/package/utils/typeGuards.ts +132 -83
  104. data/package/utils/validateDependencies.ts +1 -1
  105. data/package/webpack-types.d.ts +3 -3
  106. data/package/webpackDevServerConfig.ts +22 -10
  107. data/package-lock.json +2 -2
  108. data/package.json +37 -28
  109. data/scripts/type-check-no-emit.js +1 -1
  110. data/test/configExporter/configFile.test.js +392 -0
  111. data/test/configExporter/integration.test.js +275 -0
  112. data/test/helpers.js +1 -1
  113. data/test/package/configExporter.test.js +154 -0
  114. data/test/package/helpers.test.js +2 -2
  115. data/test/package/rules/sass-version-parsing.test.js +71 -0
  116. data/test/package/rules/sass.test.js +2 -4
  117. data/test/package/rules/sass1.test.js +1 -3
  118. data/test/package/rules/sass16.test.js +23 -0
  119. data/tools/README.md +15 -5
  120. data/tsconfig.eslint.json +2 -9
  121. data/yarn.lock +1635 -1442
  122. metadata +29 -3
  123. data/.eslintignore +0 -5
data/docs/react.md CHANGED
@@ -53,19 +53,17 @@ npm install --dev react-refresh @pmmmwh/react-refresh-webpack-plugin
53
53
  Alter `config/webpack/webpack.config.js` like so:
54
54
 
55
55
  ```js
56
- const { generateWebpackConfig, inliningCss } = require('shakapacker');
57
- const ReactRefreshWebpackPlugin = require('@pmmmwh/react-refresh-webpack-plugin');
58
- const isDevelopment = process.env.NODE_ENV !== 'production';
56
+ const { generateWebpackConfig, inliningCss } = require("shakapacker")
57
+ const ReactRefreshWebpackPlugin = require("@pmmmwh/react-refresh-webpack-plugin")
58
+ const isDevelopment = process.env.NODE_ENV !== "production"
59
59
 
60
- const webpackConfig = generateWebpackConfig();
60
+ const webpackConfig = generateWebpackConfig()
61
61
 
62
62
  if (isDevelopment && inliningCss) {
63
- webpackConfig.plugins.push(
64
- new ReactRefreshWebpackPlugin()
65
- );
63
+ webpackConfig.plugins.push(new ReactRefreshWebpackPlugin())
66
64
  }
67
65
 
68
- module.exports = webpackConfig;
66
+ module.exports = webpackConfig
69
67
  ```
70
68
 
71
69
  This applies the plugin to the webpack configuration.
@@ -85,16 +83,16 @@ Then create a `babel.config.js` file in the root of project and add the followin
85
83
 
86
84
  ```js
87
85
  module.exports = function (api) {
88
- const defaultConfigFunc = require('shakapacker/package/babel/preset.js')
86
+ const defaultConfigFunc = require("shakapacker/package/babel/preset.js")
89
87
  const resultConfig = defaultConfigFunc(api)
90
- const isDevelopmentEnv = api.env('development')
91
- const isProductionEnv = api.env('production')
92
- const isTestEnv = api.env('test')
88
+ const isDevelopmentEnv = api.env("development")
89
+ const isProductionEnv = api.env("production")
90
+ const isTestEnv = api.env("test")
93
91
 
94
92
  const changesOnDefault = {
95
93
  presets: [
96
94
  [
97
- '@babel/preset-react',
95
+ "@babel/preset-react",
98
96
  {
99
97
  development: isDevelopmentEnv || isTestEnv,
100
98
  useBuiltIns: true
@@ -102,17 +100,18 @@ module.exports = function (api) {
102
100
  ]
103
101
  ].filter(Boolean),
104
102
  plugins: [
105
- isProductionEnv && ['babel-plugin-transform-react-remove-prop-types',
103
+ isProductionEnv && [
104
+ "babel-plugin-transform-react-remove-prop-types",
106
105
  {
107
106
  removeImport: true
108
107
  }
109
108
  ],
110
- process.env.WEBPACK_SERVE && 'react-refresh/babel'
111
- ].filter(Boolean),
109
+ process.env.WEBPACK_SERVE && "react-refresh/babel"
110
+ ].filter(Boolean)
112
111
  }
113
112
 
114
113
  resultConfig.presets = [...resultConfig.presets, ...changesOnDefault.presets]
115
- resultConfig.plugins = [...resultConfig.plugins, ...changesOnDefault.plugins ]
114
+ resultConfig.plugins = [...resultConfig.plugins, ...changesOnDefault.plugins]
116
115
 
117
116
  return resultConfig
118
117
  }
@@ -127,6 +126,7 @@ HMR for your React app is now enabled. 🚀
127
126
  To test that all of the above is working, you can follow these instructions to create a basic React app using Shakapacker.
128
127
 
129
128
  1. Create a new Rails app:
129
+
130
130
  ```shell
131
131
  rails new myapp --skip-javascript
132
132
  cd myapp
@@ -138,44 +138,52 @@ npm install css-loader style-loader mini-css-extract-plugin css-minimizer-webpac
138
138
  ```
139
139
 
140
140
  2. Generate a controller
141
+
141
142
  ```shell
142
143
  rails g controller site index
143
144
  echo '<div id="root"></div>' > app/views/site/index.html.erb
144
145
  ```
145
146
 
146
147
  3. Create a CSS file and a React component:
148
+
147
149
  ```shell
148
150
  touch app/javascript/App.css app/javascript/App.js
149
151
  ```
150
152
 
151
153
  4. Edit `app/javascript/packs/application.js` like so:
154
+
152
155
  ```jsx
153
- import React from 'react';
154
- import { createRoot } from 'react-dom/client';
155
- import HelloMessage from '../App';
156
+ import React from "react"
157
+ import { createRoot } from "react-dom/client"
158
+ import HelloMessage from "../App"
156
159
 
157
- const container = document.getElementById('root');
158
- const root = createRoot(container);
160
+ const container = document.getElementById("root")
161
+ const root = createRoot(container)
159
162
 
160
- document.addEventListener('DOMContentLoaded', () => {
161
- root.render(<HelloMessage name="World" />);
162
- });
163
+ document.addEventListener("DOMContentLoaded", () => {
164
+ root.render(<HelloMessage name="World" />)
165
+ })
163
166
  ```
164
167
 
165
168
  5. Add the following to `app/javascript/App.js`:
169
+
166
170
  ```jsx
167
- import React from 'react';
168
- import 'App.css';
169
- const HelloMessage = ({ name }) => <h1>Hello, {name}!</h1>;
170
- export default HelloMessage;
171
+ import React from "react"
172
+ import "App.css"
173
+ const HelloMessage = ({ name }) => <h1>Hello, {name}!</h1>
174
+ export default HelloMessage
171
175
  ```
172
176
 
173
177
  6. Add the following to `app/javascript/App.css`:
178
+
174
179
  ```css
175
- h1 { color: blue; }
180
+ h1 {
181
+ color: blue;
182
+ }
176
183
  ```
177
184
 
178
185
  7. Enable HMR in config/shakapacker.yml:
186
+
179
187
  ```shell
180
188
  hmr: true
181
189
  ```
@@ -189,22 +197,21 @@ npm install --dev react-refresh @pmmmwh/react-refresh-webpack-plugin
189
197
  9. Alter `config/webpack/webpack.config.js` like so:
190
198
 
191
199
  ```js
192
- const { generateWebpackConfig, inliningCss } = require('shakapacker');
193
- const ReactRefreshWebpackPlugin = require('@pmmmwh/react-refresh-webpack-plugin');
194
- const isDevelopment = process.env.NODE_ENV !== 'production';
200
+ const { generateWebpackConfig, inliningCss } = require("shakapacker")
201
+ const ReactRefreshWebpackPlugin = require("@pmmmwh/react-refresh-webpack-plugin")
202
+ const isDevelopment = process.env.NODE_ENV !== "production"
195
203
 
196
- const webpackConfig = generateWebpackConfig();
204
+ const webpackConfig = generateWebpackConfig()
197
205
 
198
206
  if (isDevelopment && inliningCss) {
199
- webpackConfig.plugins.push(
200
- new ReactRefreshWebpackPlugin()
201
- );
207
+ webpackConfig.plugins.push(new ReactRefreshWebpackPlugin())
202
208
  }
203
209
 
204
- module.exports = webpackConfig;
210
+ module.exports = webpackConfig
205
211
  ```
206
212
 
207
213
  10. Remove the Babel configuration from `package.json`
214
+
208
215
  ```diff
209
216
  - "babel": {
210
217
  - "presets": [
@@ -214,18 +221,19 @@ module.exports = webpackConfig;
214
221
  ```
215
222
 
216
223
  11. Create a `babel.config.js` file in the project root and add the following [sample code](https://github.com/shakacode/shakapacker/blob/main/docs/customizing_babel_config.md#react-configuration):
224
+
217
225
  ```js
218
226
  module.exports = function (api) {
219
- const defaultConfigFunc = require('shakapacker/package/babel/preset.js')
227
+ const defaultConfigFunc = require("shakapacker/package/babel/preset.js")
220
228
  const resultConfig = defaultConfigFunc(api)
221
- const isDevelopmentEnv = api.env('development')
222
- const isProductionEnv = api.env('production')
223
- const isTestEnv = api.env('test')
229
+ const isDevelopmentEnv = api.env("development")
230
+ const isProductionEnv = api.env("production")
231
+ const isTestEnv = api.env("test")
224
232
 
225
233
  const changesOnDefault = {
226
234
  presets: [
227
235
  [
228
- '@babel/preset-react',
236
+ "@babel/preset-react",
229
237
  {
230
238
  development: isDevelopmentEnv || isTestEnv,
231
239
  useBuiltIns: true
@@ -233,23 +241,25 @@ module.exports = function (api) {
233
241
  ]
234
242
  ].filter(Boolean),
235
243
  plugins: [
236
- isProductionEnv && ['babel-plugin-transform-react-remove-prop-types',
244
+ isProductionEnv && [
245
+ "babel-plugin-transform-react-remove-prop-types",
237
246
  {
238
247
  removeImport: true
239
248
  }
240
249
  ],
241
- process.env.WEBPACK_SERVE && 'react-refresh/babel'
242
- ].filter(Boolean),
250
+ process.env.WEBPACK_SERVE && "react-refresh/babel"
251
+ ].filter(Boolean)
243
252
  }
244
253
 
245
254
  resultConfig.presets = [...resultConfig.presets, ...changesOnDefault.presets]
246
- resultConfig.plugins = [...resultConfig.plugins, ...changesOnDefault.plugins ]
255
+ resultConfig.plugins = [...resultConfig.plugins, ...changesOnDefault.plugins]
247
256
 
248
257
  return resultConfig
249
258
  }
250
259
  ```
251
260
 
252
261
  9. Start the Rails server and the `shakapacker-dev-server` in separate console windows:
262
+
253
263
  ```shell
254
264
  rails s
255
265
  ./bin/shakapacker-dev-server
data/docs/releasing.md ADDED
@@ -0,0 +1,195 @@
1
+ # Releasing Shakapacker
2
+
3
+ This guide is for Shakapacker maintainers who need to publish a new release.
4
+
5
+ ## Prerequisites
6
+
7
+ 1. **Install required tools:**
8
+
9
+ ```bash
10
+ bundle install # Installs gem-release
11
+ yarn global add release-it # Installs release-it for npm publishing
12
+ ```
13
+
14
+ 2. **Ensure you have publishing access:**
15
+ - npm: You must be a collaborator on the [shakapacker npm package](https://www.npmjs.com/package/shakapacker)
16
+ - RubyGems: You must be an owner of the [shakapacker gem](https://rubygems.org/gems/shakapacker)
17
+
18
+ 3. **Enable 2FA on both platforms:**
19
+ - npm: 2FA is required for publishing
20
+ - RubyGems: 2FA is required for publishing
21
+
22
+ ## Release Process
23
+
24
+ ### 1. Prepare the Release
25
+
26
+ Before running the release task:
27
+
28
+ 1. Ensure all desired changes are merged to `main` branch
29
+ 2. Update `CHANGELOG.md` with the new version and release notes
30
+ 3. Commit the CHANGELOG changes
31
+ 4. Ensure your working directory is clean (`git status` shows no uncommitted changes)
32
+
33
+ ### 2. Run the Release Task
34
+
35
+ The automated release task handles the entire release process:
36
+
37
+ ```bash
38
+ # For a specific version (e.g., 9.1.0)
39
+ rake create_release[9.1.0]
40
+
41
+ # For a beta release (note: use period, not dash)
42
+ rake create_release[9.2.0.beta.1] # Creates npm package 9.2.0-beta.1
43
+
44
+ # For a patch version bump (auto-increments)
45
+ rake create_release
46
+
47
+ # Dry run to test without publishing
48
+ rake create_release[9.1.0,true]
49
+ ```
50
+
51
+ ### 3. What the Release Task Does
52
+
53
+ The `create_release` task automatically:
54
+
55
+ 1. **Pulls latest changes** from the repository
56
+ 2. **Bumps version numbers** in:
57
+ - `lib/shakapacker/version.rb` (Ruby gem version)
58
+ - `package.json` (npm package version - converted from Ruby format)
59
+ 3. **Publishes to npm:**
60
+ - Prompts for npm OTP (2FA code)
61
+ - Creates git tag
62
+ - Pushes to GitHub
63
+ 4. **Publishes to RubyGems:**
64
+ - Prompts for RubyGems OTP (2FA code)
65
+ 5. **Updates spec/dummy lockfiles:**
66
+ - Runs `bundle install` to update `Gemfile.lock`
67
+ - Runs `npm install` to update `package-lock.json` (yarn.lock may also be updated for multi-package-manager compatibility testing)
68
+ 6. **Commits and pushes lockfile changes** automatically
69
+
70
+ ### 4. Version Format
71
+
72
+ **Important:** Use Ruby gem version format (no dashes):
73
+
74
+ - ✅ Correct: `9.1.0`, `9.2.0.beta.1`, `9.0.0.rc.2`
75
+ - ❌ Wrong: `9.1.0-beta.1`, `9.0.0-rc.2`
76
+
77
+ The task automatically converts Ruby gem format to npm semver format:
78
+
79
+ - Ruby: `9.2.0.beta.1` → npm: `9.2.0-beta.1`
80
+ - Ruby: `9.0.0.rc.2` → npm: `9.0.0-rc.2`
81
+
82
+ **Examples:**
83
+
84
+ ```bash
85
+ # Regular release
86
+ rake create_release[9.1.0] # Gem: 9.1.0, npm: 9.1.0
87
+
88
+ # Beta release
89
+ rake create_release[9.2.0.beta.1] # Gem: 9.2.0.beta.1, npm: 9.2.0-beta.1
90
+
91
+ # Release candidate
92
+ rake create_release[10.0.0.rc.1] # Gem: 10.0.0.rc.1, npm: 10.0.0-rc.1
93
+ ```
94
+
95
+ ### 5. During the Release
96
+
97
+ 1. When prompted for **npm OTP**, enter your 2FA code from your authenticator app
98
+ 2. Accept defaults for release-it options
99
+ 3. When prompted for **RubyGems OTP**, enter your 2FA code
100
+ 4. The script will automatically commit and push lockfile updates
101
+
102
+ ### 6. After Release
103
+
104
+ 1. Verify the release on:
105
+ - [npm](https://www.npmjs.com/package/shakapacker)
106
+ - [RubyGems](https://rubygems.org/gems/shakapacker)
107
+ - [GitHub releases](https://github.com/shakacode/shakapacker/releases)
108
+
109
+ 2. Check that the lockfile commit was pushed:
110
+
111
+ ```bash
112
+ git log --oneline -5
113
+ # Should see "Update spec/dummy lockfiles after release"
114
+ ```
115
+
116
+ 3. Announce the release (if appropriate):
117
+ - Post in relevant Slack/Discord channels
118
+ - Tweet about major releases
119
+ - Update documentation if needed
120
+
121
+ ## Troubleshooting
122
+
123
+ ### Uncommitted Changes After Release
124
+
125
+ If you see uncommitted changes to lockfiles after a release, this means:
126
+
127
+ 1. The release was successful but the lockfile commit step may have failed
128
+ 2. **Solution:** Manually commit these files:
129
+ ```bash
130
+ git add spec/dummy/Gemfile.lock spec/dummy/package-lock.json spec/dummy/yarn.lock
131
+ git commit -m 'Update spec/dummy lockfiles after release'
132
+ git push
133
+ ```
134
+
135
+ ### Failed npm or RubyGems Publish
136
+
137
+ If publishing fails partway through:
138
+
139
+ 1. Check which step failed (npm or RubyGems)
140
+ 2. If npm failed: Fix the issue and manually run `npm publish`
141
+ 3. If RubyGems failed: Fix the issue and manually run `gem release`
142
+ 4. Then manually update and commit spec/dummy lockfiles
143
+
144
+ ### Wrong Version Format
145
+
146
+ If you accidentally use npm format (with dashes):
147
+
148
+ 1. The gem will be created with an invalid version
149
+ 2. **Solution:** Don't push the changes, reset your branch:
150
+ ```bash
151
+ git reset --hard HEAD
152
+ ```
153
+ 3. Re-run with correct Ruby gem format
154
+
155
+ ## Manual Release Steps
156
+
157
+ If you need to release manually (not recommended):
158
+
159
+ 1. **Bump version:**
160
+
161
+ ```bash
162
+ gem bump --version 9.1.0
163
+ bundle install
164
+ ```
165
+
166
+ 2. **Publish to npm:**
167
+
168
+ ```bash
169
+ release-it 9.1.0 --npm.publish
170
+ ```
171
+
172
+ 3. **Publish to RubyGems:**
173
+
174
+ ```bash
175
+ gem release
176
+ ```
177
+
178
+ 4. **Update lockfiles:**
179
+ ```bash
180
+ cd spec/dummy
181
+ bundle install
182
+ npm install
183
+ cd ../..
184
+ git add spec/dummy/Gemfile.lock spec/dummy/package-lock.json spec/dummy/yarn.lock
185
+ git commit -m 'Update spec/dummy lockfiles after release'
186
+ git push
187
+ ```
188
+
189
+ ## Questions?
190
+
191
+ If you encounter issues not covered here, please:
192
+
193
+ 1. Check the [CONTRIBUTING.md](../CONTRIBUTING.md) guide
194
+ 2. Ask in the maintainers channel
195
+ 3. Update this documentation for future releases
data/docs/rspack.md CHANGED
@@ -2,6 +2,8 @@
2
2
 
3
3
  Shakapacker supports [Rspack](https://rspack.rs) as an alternative assets bundler to Webpack. Rspack is a fast Rust-based web bundler with webpack-compatible API that can significantly speed up your build times.
4
4
 
5
+ **📖 For configuration options, see the [Configuration Guide](./configuration.md)**
6
+
5
7
  ## Installation
6
8
 
7
9
  First, install the required Rspack dependencies:
@@ -10,7 +12,7 @@ First, install the required Rspack dependencies:
10
12
  npm install @rspack/core @rspack/cli -D
11
13
  # or
12
14
  yarn add @rspack/core @rspack/cli -D
13
- # or
15
+ # or
14
16
  pnpm add @rspack/core @rspack/cli -D
15
17
  # or
16
18
  bun add @rspack/core @rspack/cli -D
@@ -23,9 +25,8 @@ Note: These packages are already listed as optional peer dependencies in Shakapa
23
25
  To enable Rspack, update your `config/shakapacker.yml`:
24
26
 
25
27
  ```yaml
26
- default: &default
27
- # ... other config options
28
- assets_bundler: 'rspack' # Change from 'webpack' to 'rspack'
28
+ default: &default # ... other config options
29
+ assets_bundler: "rspack" # Change from 'webpack' to 'rspack'
29
30
  ```
30
31
 
31
32
  ### Configuration Files
@@ -33,7 +34,7 @@ default: &default
33
34
  Rspack uses its own configuration directory to keep things organized. Create your Rspack configuration file at `config/rspack/rspack.config.js`:
34
35
 
35
36
  ```javascript
36
- const { generateRspackConfig } = require('shakapacker/rspack')
37
+ const { generateRspackConfig } = require("shakapacker/rspack")
37
38
 
38
39
  module.exports = generateRspackConfig()
39
40
  ```
@@ -43,14 +44,12 @@ module.exports = generateRspackConfig()
43
44
  If you need to customize your Rspack configuration:
44
45
 
45
46
  ```javascript
46
- const { generateRspackConfig } = require('shakapacker/rspack')
47
+ const { generateRspackConfig } = require("shakapacker/rspack")
47
48
 
48
49
  const rspackConfig = generateRspackConfig({
49
- plugins: [
50
- new SomeRspackCompatiblePlugin()
51
- ],
50
+ plugins: [new SomeRspackCompatiblePlugin()],
52
51
  resolve: {
53
- extensions: ['.ts', '.tsx', '.js', '.jsx']
52
+ extensions: [".ts", ".tsx", ".js", ".jsx"]
54
53
  }
55
54
  })
56
55
 
@@ -62,14 +61,16 @@ module.exports = rspackConfig
62
61
  If you have an existing `config/webpack/webpack.config.js`, you can migrate it to `config/rspack/rspack.config.js`:
63
62
 
64
63
  **Old (webpack.config.js):**
64
+
65
65
  ```javascript
66
- const { generateWebpackConfig } = require('shakapacker')
66
+ const { generateWebpackConfig } = require("shakapacker")
67
67
  module.exports = generateWebpackConfig()
68
68
  ```
69
69
 
70
70
  **New (rspack.config.js):**
71
+
71
72
  ```javascript
72
- const { generateRspackConfig } = require('shakapacker/rspack')
73
+ const { generateRspackConfig } = require("shakapacker/rspack")
73
74
  module.exports = generateRspackConfig()
74
75
  ```
75
76
 
@@ -89,11 +90,11 @@ Rspack has built-in loaders that are faster than their webpack counterparts:
89
90
 
90
91
  Most webpack plugins work with Rspack, but some have Rspack-specific alternatives:
91
92
 
92
- | Webpack Plugin | Rspack Alternative | Status |
93
- |---|---|---|
94
- | `mini-css-extract-plugin` | `rspack.CssExtractRspackPlugin` | Built-in |
95
- | `copy-webpack-plugin` | `rspack.CopyRspackPlugin` | Built-in |
96
- | `terser-webpack-plugin` | `rspack.SwcJsMinimizerRspackPlugin` | Built-in |
93
+ | Webpack Plugin | Rspack Alternative | Status |
94
+ | ------------------------- | ----------------------------------- | -------- |
95
+ | `mini-css-extract-plugin` | `rspack.CssExtractRspackPlugin` | Built-in |
96
+ | `copy-webpack-plugin` | `rspack.CopyRspackPlugin` | Built-in |
97
+ | `terser-webpack-plugin` | `rspack.SwcJsMinimizerRspackPlugin` | Built-in |
97
98
 
98
99
  ### Minification
99
100
 
@@ -136,28 +137,31 @@ The same dev server configuration in `shakapacker.yml` applies to both webpack a
136
137
  Rspack typically provides:
137
138
 
138
139
  - **2-10x faster** cold builds
139
- - **5-20x faster** incremental builds
140
+ - **5-20x faster** incremental builds
140
141
  - **Faster HMR** (Hot Module Replacement)
141
142
  - **Lower memory usage**
142
143
 
143
144
  ## Migration Checklist
144
145
 
145
146
  1. **Install Rspack dependencies:**
147
+
146
148
  ```bash
147
149
  npm install @rspack/core @rspack/cli -D
148
150
  ```
149
151
 
150
152
  2. **Update configuration:**
153
+
151
154
  ```yaml
152
155
  # config/shakapacker.yml
153
156
  default: &default
154
- assets_bundler: 'rspack'
157
+ assets_bundler: "rspack"
155
158
  ```
156
159
 
157
160
  3. **Create Rspack config:**
161
+
158
162
  ```javascript
159
163
  // config/rspack/rspack.config.js
160
- const { generateRspackConfig } = require('shakapacker/rspack')
164
+ const { generateRspackConfig } = require("shakapacker/rspack")
161
165
  module.exports = generateRspackConfig()
162
166
  ```
163
167
 
@@ -187,4 +191,4 @@ If builds are unexpectedly slow:
187
191
 
188
192
  - [Rspack Official Documentation](https://rspack.rs)
189
193
  - [Rspack Migration Guide](https://rspack.rs/guide/migration/webpack)
190
- - [Rspack Plugins](https://rspack.rs/plugins/webpack/)
194
+ - [Rspack Plugins](https://rspack.rs/plugins/webpack/)