shakapacker 8.0.2 → 9.2.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 (198) hide show
  1. checksums.yaml +4 -4
  2. data/.eslintignore +1 -0
  3. data/.eslintrc.fast.js +40 -0
  4. data/.eslintrc.js +48 -0
  5. data/.github/STATUS.md +1 -0
  6. data/.github/workflows/claude-code-review.yml +54 -0
  7. data/.github/workflows/claude.yml +50 -0
  8. data/.github/workflows/dummy.yml +9 -4
  9. data/.github/workflows/generator.yml +32 -10
  10. data/.github/workflows/node.yml +23 -1
  11. data/.github/workflows/ruby.yml +33 -2
  12. data/.github/workflows/test-bundlers.yml +170 -0
  13. data/.gitignore +20 -0
  14. data/.husky/pre-commit +2 -0
  15. data/.npmignore +56 -0
  16. data/.prettierignore +3 -0
  17. data/.rubocop.yml +1 -0
  18. data/.yalcignore +26 -0
  19. data/CHANGELOG.md +302 -16
  20. data/CLAUDE.md +29 -0
  21. data/CONTRIBUTING.md +138 -20
  22. data/Gemfile.lock +83 -89
  23. data/README.md +343 -105
  24. data/Rakefile +39 -4
  25. data/TODO.md +50 -0
  26. data/TODO_v9.md +87 -0
  27. data/bin/export-bundler-config +11 -0
  28. data/conductor-setup.sh +70 -0
  29. data/conductor.json +7 -0
  30. data/docs/cdn_setup.md +379 -0
  31. data/docs/common-upgrades.md +615 -0
  32. data/docs/css-modules-export-mode.md +512 -0
  33. data/docs/deployment.md +62 -9
  34. data/docs/optional-peer-dependencies.md +198 -0
  35. data/docs/peer-dependencies.md +60 -0
  36. data/docs/react.md +6 -14
  37. data/docs/releasing.md +197 -0
  38. data/docs/rspack.md +190 -0
  39. data/docs/rspack_migration_guide.md +305 -0
  40. data/docs/subresource_integrity.md +54 -0
  41. data/docs/transpiler-migration.md +209 -0
  42. data/docs/transpiler-performance.md +179 -0
  43. data/docs/troubleshooting.md +157 -22
  44. data/docs/typescript-migration.md +379 -0
  45. data/docs/typescript.md +99 -0
  46. data/docs/using_esbuild_loader.md +3 -3
  47. data/docs/using_swc_loader.md +112 -10
  48. data/docs/v6_upgrade.md +10 -0
  49. data/docs/v8_upgrade.md +3 -5
  50. data/docs/v9_upgrade.md +458 -0
  51. data/gemfiles/Gemfile-rails.6.0.x +2 -1
  52. data/gemfiles/Gemfile-rails.6.1.x +1 -1
  53. data/gemfiles/Gemfile-rails.7.0.x +2 -2
  54. data/gemfiles/Gemfile-rails.7.1.x +1 -2
  55. data/gemfiles/Gemfile-rails.7.2.x +11 -0
  56. data/gemfiles/Gemfile-rails.8.0.x +11 -0
  57. data/lib/install/bin/export-bundler-config +11 -0
  58. data/lib/install/bin/shakapacker +4 -6
  59. data/lib/install/bin/shakapacker-dev-server +1 -1
  60. data/lib/install/config/rspack/rspack.config.js +6 -0
  61. data/lib/install/config/rspack/rspack.config.ts +7 -0
  62. data/lib/install/config/shakapacker.yml +25 -5
  63. data/lib/install/config/webpack/webpack.config.ts +7 -0
  64. data/lib/install/package.json +38 -0
  65. data/lib/install/template.rb +194 -44
  66. data/lib/shakapacker/bundler_switcher.rb +329 -0
  67. data/lib/shakapacker/compiler.rb +2 -1
  68. data/lib/shakapacker/compiler_strategy.rb +2 -2
  69. data/lib/shakapacker/configuration.rb +173 -2
  70. data/lib/shakapacker/dev_server_runner.rb +29 -8
  71. data/lib/shakapacker/digest_strategy.rb +2 -1
  72. data/lib/shakapacker/doctor.rb +905 -0
  73. data/lib/shakapacker/helper.rb +64 -16
  74. data/lib/shakapacker/manifest.rb +10 -3
  75. data/lib/shakapacker/mtime_strategy.rb +1 -1
  76. data/lib/shakapacker/railtie.rb +4 -4
  77. data/lib/shakapacker/rspack_runner.rb +19 -0
  78. data/lib/shakapacker/runner.rb +159 -10
  79. data/lib/shakapacker/swc_migrator.rb +384 -0
  80. data/lib/shakapacker/utils/manager.rb +15 -2
  81. data/lib/shakapacker/version.rb +1 -1
  82. data/lib/shakapacker/version_checker.rb +2 -2
  83. data/lib/shakapacker/webpack_runner.rb +6 -43
  84. data/lib/shakapacker.rb +22 -11
  85. data/lib/tasks/shakapacker/doctor.rake +8 -0
  86. data/lib/tasks/shakapacker/export_bundler_config.rake +72 -0
  87. data/lib/tasks/shakapacker/install.rake +12 -2
  88. data/lib/tasks/shakapacker/migrate_to_swc.rake +13 -0
  89. data/lib/tasks/shakapacker/switch_bundler.rake +82 -0
  90. data/lib/tasks/shakapacker.rake +2 -0
  91. data/package/.npmignore +4 -0
  92. data/package/babel/preset.ts +56 -0
  93. data/package/config.ts +175 -0
  94. data/package/configExporter/cli.ts +683 -0
  95. data/package/configExporter/configDocs.ts +102 -0
  96. data/package/configExporter/fileWriter.ts +92 -0
  97. data/package/configExporter/index.ts +5 -0
  98. data/package/configExporter/types.ts +36 -0
  99. data/package/configExporter/yamlSerializer.ts +266 -0
  100. data/package/{dev_server.js → dev_server.ts} +8 -5
  101. data/package/env.ts +92 -0
  102. data/package/environments/__type-tests__/rspack-plugin-compatibility.ts +30 -0
  103. data/package/environments/{base.js → base.ts} +56 -60
  104. data/package/environments/development.ts +90 -0
  105. data/package/environments/production.ts +80 -0
  106. data/package/environments/test.ts +53 -0
  107. data/package/environments/types.ts +98 -0
  108. data/package/esbuild/index.ts +42 -0
  109. data/package/index.d.ts +3 -60
  110. data/package/index.ts +55 -0
  111. data/package/loaders.d.ts +28 -0
  112. data/package/optimization/rspack.ts +36 -0
  113. data/package/optimization/webpack.ts +57 -0
  114. data/package/plugins/rspack.ts +103 -0
  115. data/package/plugins/webpack.ts +62 -0
  116. data/package/rspack/index.ts +64 -0
  117. data/package/rules/{babel.js → babel.ts} +2 -2
  118. data/package/rules/{coffee.js → coffee.ts} +1 -1
  119. data/package/rules/css.ts +3 -0
  120. data/package/rules/{erb.js → erb.ts} +1 -1
  121. data/package/rules/esbuild.ts +10 -0
  122. data/package/rules/file.ts +40 -0
  123. data/package/rules/{jscommon.js → jscommon.ts} +4 -4
  124. data/package/rules/{less.js → less.ts} +4 -4
  125. data/package/rules/raw.ts +25 -0
  126. data/package/rules/rspack.ts +176 -0
  127. data/package/rules/{sass.js → sass.ts} +7 -3
  128. data/package/rules/{stylus.js → stylus.ts} +4 -8
  129. data/package/rules/swc.ts +10 -0
  130. data/package/rules/webpack.ts +16 -0
  131. data/package/swc/index.ts +56 -0
  132. data/package/types/README.md +88 -0
  133. data/package/types/index.ts +61 -0
  134. data/package/types.ts +108 -0
  135. data/package/utils/configPath.ts +6 -0
  136. data/package/utils/debug.ts +49 -0
  137. data/package/utils/defaultConfigPath.ts +4 -0
  138. data/package/utils/errorCodes.ts +219 -0
  139. data/package/utils/errorHelpers.ts +143 -0
  140. data/package/utils/getStyleRule.ts +64 -0
  141. data/package/utils/helpers.ts +85 -0
  142. data/package/utils/{inliningCss.js → inliningCss.ts} +3 -3
  143. data/package/utils/pathValidation.ts +139 -0
  144. data/package/utils/requireOrError.ts +15 -0
  145. data/package/utils/snakeToCamelCase.ts +5 -0
  146. data/package/utils/typeGuards.ts +342 -0
  147. data/package/utils/validateDependencies.ts +61 -0
  148. data/package/webpack-types.d.ts +33 -0
  149. data/package/webpackDevServerConfig.ts +117 -0
  150. data/package-lock.json +13047 -0
  151. data/package.json +154 -18
  152. data/scripts/remove-use-strict.js +45 -0
  153. data/scripts/type-check-no-emit.js +27 -0
  154. data/test/helpers.js +1 -1
  155. data/test/package/config.test.js +43 -0
  156. data/test/package/env.test.js +42 -7
  157. data/test/package/environments/base.test.js +5 -1
  158. data/test/package/rules/babel.test.js +16 -0
  159. data/test/package/rules/esbuild.test.js +1 -1
  160. data/test/package/rules/raw.test.js +40 -7
  161. data/test/package/rules/swc.test.js +1 -1
  162. data/test/package/rules/webpack.test.js +35 -0
  163. data/test/package/staging.test.js +4 -3
  164. data/test/package/transpiler-defaults.test.js +127 -0
  165. data/test/peer-dependencies.sh +85 -0
  166. data/test/scripts/remove-use-strict.test.js +125 -0
  167. data/test/typescript/build.test.js +118 -0
  168. data/test/typescript/environments.test.js +107 -0
  169. data/test/typescript/pathValidation.test.js +142 -0
  170. data/test/typescript/securityValidation.test.js +182 -0
  171. data/tools/README.md +124 -0
  172. data/tools/css-modules-v9-codemod.js +179 -0
  173. data/tsconfig.eslint.json +16 -0
  174. data/tsconfig.json +38 -0
  175. data/yarn.lock +4165 -2706
  176. metadata +129 -41
  177. data/package/babel/preset.js +0 -37
  178. data/package/config.js +0 -54
  179. data/package/env.js +0 -48
  180. data/package/environments/development.js +0 -13
  181. data/package/environments/production.js +0 -88
  182. data/package/environments/test.js +0 -3
  183. data/package/esbuild/index.js +0 -40
  184. data/package/index.js +0 -40
  185. data/package/rules/css.js +0 -3
  186. data/package/rules/esbuild.js +0 -10
  187. data/package/rules/file.js +0 -29
  188. data/package/rules/index.js +0 -20
  189. data/package/rules/raw.js +0 -5
  190. data/package/rules/swc.js +0 -10
  191. data/package/swc/index.js +0 -50
  192. data/package/utils/configPath.js +0 -4
  193. data/package/utils/defaultConfigPath.js +0 -2
  194. data/package/utils/getStyleRule.js +0 -40
  195. data/package/utils/helpers.js +0 -58
  196. data/package/utils/snakeToCamelCase.js +0 -5
  197. data/package/webpackDevServerConfig.js +0 -71
  198. data/test/package/rules/index.test.js +0 -16
@@ -0,0 +1,305 @@
1
+ # Rspack Migration Guide for Shakapacker
2
+
3
+ > 💡 **Quick Start**: For a step-by-step migration guide from Webpack to Rspack, see [Common Upgrades Guide - Webpack to Rspack](./common-upgrades.md#migrating-from-webpack-to-rspack).
4
+
5
+ ## Overview
6
+
7
+ This guide documents the differences between webpack and Rspack configurations in Shakapacker, and provides migration guidance for users switching to Rspack.
8
+
9
+ ## Key Differences from Webpack
10
+
11
+ ### 1. Built-in Loaders
12
+
13
+ Rspack provides built-in loaders for better performance:
14
+
15
+ **JavaScript/TypeScript:**
16
+
17
+ - Use `builtin:swc-loader` instead of `babel-loader` or `ts-loader`
18
+ - 20x faster than Babel on single thread, 70x on multiple cores
19
+ - Configuration example:
20
+
21
+ ```javascript
22
+ {
23
+ test: /\.(js|jsx|ts|tsx)$/,
24
+ loader: 'builtin:swc-loader',
25
+ options: {
26
+ jsc: {
27
+ parser: {
28
+ syntax: 'typescript', // or 'ecmascript'
29
+ tsx: true, // for TSX files
30
+ jsx: true // for JSX files
31
+ },
32
+ transform: {
33
+ react: {
34
+ runtime: 'automatic'
35
+ }
36
+ }
37
+ }
38
+ }
39
+ }
40
+ ```
41
+
42
+ ### 2. Plugin Replacements
43
+
44
+ #### Built-in Rspack Alternatives
45
+
46
+ | Webpack Plugin | Rspack Alternative | Status |
47
+ | ------------------------------ | ------------------------------------------ | ----------- |
48
+ | `copy-webpack-plugin` | `rspack.CopyRspackPlugin` | ✅ Built-in |
49
+ | `mini-css-extract-plugin` | `rspack.CssExtractRspackPlugin` | ✅ Built-in |
50
+ | `terser-webpack-plugin` | `rspack.SwcJsMinimizerRspackPlugin` | ✅ Built-in |
51
+ | `css-minimizer-webpack-plugin` | `rspack.LightningCssMinimizerRspackPlugin` | ✅ Built-in |
52
+
53
+ #### Community Alternatives
54
+
55
+ | Webpack Plugin | Rspack Alternative | Package |
56
+ | -------------------------------------- | ------------------------------ | --------------------------------------- |
57
+ | `fork-ts-checker-webpack-plugin` | `ts-checker-rspack-plugin` | `npm i -D ts-checker-rspack-plugin` |
58
+ | `@pmmmwh/react-refresh-webpack-plugin` | `@rspack/plugin-react-refresh` | `npm i -D @rspack/plugin-react-refresh` |
59
+ | `eslint-webpack-plugin` | `eslint-rspack-plugin` | `npm i -D eslint-rspack-plugin` |
60
+
61
+ #### Incompatible Plugins
62
+
63
+ The following webpack plugins are NOT compatible with Rspack:
64
+
65
+ - `webpack.optimize.LimitChunkCountPlugin` - Use `optimization.splitChunks` configuration instead
66
+ - `webpack-manifest-plugin` - Use `rspack-manifest-plugin` instead
67
+ - Git revision plugins - Use alternative approaches
68
+
69
+ ### 3. Asset Module Types
70
+
71
+ Replace file loaders with asset modules:
72
+
73
+ - `file-loader` → `type: 'asset/resource'`
74
+ - `url-loader` → `type: 'asset/inline'`
75
+ - `raw-loader` → `type: 'asset/source'`
76
+
77
+ ### 4. Configuration Differences
78
+
79
+ #### TypeScript Configuration
80
+
81
+ **Required:** Add `isolatedModules: true` to your `tsconfig.json`:
82
+
83
+ ```json
84
+ {
85
+ "compilerOptions": {
86
+ "isolatedModules": true
87
+ }
88
+ }
89
+ ```
90
+
91
+ #### React Fast Refresh
92
+
93
+ ```javascript
94
+ // Development configuration
95
+ const ReactRefreshPlugin = require("@rspack/plugin-react-refresh")
96
+
97
+ module.exports = {
98
+ plugins: [new ReactRefreshPlugin(), new rspack.HotModuleReplacementPlugin()]
99
+ }
100
+ ```
101
+
102
+ ### 5. Optimization Differences
103
+
104
+ #### Code Splitting
105
+
106
+ Rspack's `splitChunks` configuration is similar to webpack but with some differences:
107
+
108
+ ```javascript
109
+ optimization: {
110
+ splitChunks: {
111
+ chunks: 'all',
112
+ cacheGroups: {
113
+ vendor: {
114
+ test: /[\\/]node_modules[\\/]/,
115
+ priority: -10,
116
+ reuseExistingChunk: true
117
+ }
118
+ }
119
+ }
120
+ }
121
+ ```
122
+
123
+ #### Minimization
124
+
125
+ ```javascript
126
+ optimization: {
127
+ minimize: true,
128
+ minimizer: [
129
+ new rspack.SwcJsMinimizerRspackPlugin(),
130
+ new rspack.LightningCssMinimizerRspackPlugin()
131
+ ]
132
+ }
133
+ ```
134
+
135
+ ### 6. Development Server
136
+
137
+ Rspack uses its own dev server with some configuration differences:
138
+
139
+ ```javascript
140
+ devServer: {
141
+ // Rspack-specific: Force writing assets to disk
142
+ devMiddleware: {
143
+ writeToDisk: true
144
+ }
145
+ }
146
+ ```
147
+
148
+ ## Migration Checklist
149
+
150
+ ### Quick Start: Using the Switch Bundler Task
151
+
152
+ Shakapacker provides a convenient rake task to switch between webpack and rspack:
153
+
154
+ ```bash
155
+ # Switch to rspack with automatic dependency management
156
+ rails shakapacker:switch_bundler rspack --install-deps
157
+ # or with rake (note the -- separator)
158
+ rake shakapacker:switch_bundler rspack -- --install-deps
159
+
160
+ # Fast switching without uninstalling old bundler (keeps both)
161
+ rails shakapacker:switch_bundler webpack --install-deps --no-uninstall
162
+ rake shakapacker:switch_bundler rspack -- --install-deps --no-uninstall
163
+
164
+ # Switch to rspack manually (you manage dependencies yourself)
165
+ rails shakapacker:switch_bundler rspack
166
+ rake shakapacker:switch_bundler rspack
167
+
168
+ # Switch back to webpack if needed
169
+ rails shakapacker:switch_bundler webpack --install-deps
170
+ rake shakapacker:switch_bundler webpack -- --install-deps
171
+
172
+ # Show help
173
+ rails shakapacker:switch_bundler --help
174
+ rake shakapacker:switch_bundler -- --help
175
+ ```
176
+
177
+ **Note:** When using `rake`, you must use `--` to separate rake options from task arguments.
178
+
179
+ The task will:
180
+
181
+ - Update `config/shakapacker.yml` to switch the bundler
182
+ - Optionally install/uninstall npm dependencies with `--install-deps`
183
+ - Use `--no-uninstall` to skip uninstalling the old bundler's packages (faster switching, keeps both bundlers installed)
184
+ - Update `javascript_transpiler` to `swc` when switching to rspack (recommended)
185
+ - Preserve your config file comments and structure
186
+
187
+ **Custom Dependencies:** You can customize which dependencies are installed by creating a `.shakapacker-switch-bundler-dependencies.yml` file:
188
+
189
+ ```bash
190
+ rails shakapacker:switch_bundler --init-config
191
+ ```
192
+
193
+ ### Manual Migration Steps
194
+
195
+ If you prefer to migrate manually or need more control:
196
+
197
+ ### Step 1: Update Dependencies
198
+
199
+ ```bash
200
+ # Remove webpack dependencies
201
+ npm uninstall webpack webpack-cli webpack-dev-server
202
+
203
+ # Install Rspack
204
+ npm install --save-dev @rspack/core @rspack/cli
205
+ ```
206
+
207
+ ### Step 2: Update Configuration Files
208
+
209
+ 1. Create `config/rspack/rspack.config.js` based on your webpack config
210
+ 2. Update `config/shakapacker.yml`:
211
+
212
+ ```yaml
213
+ assets_bundler: "rspack"
214
+ ```
215
+
216
+ ### Step 3: Replace Loaders
217
+
218
+ - Replace `babel-loader` with `builtin:swc-loader`
219
+ - Remove `file-loader`, `url-loader`, `raw-loader` - use asset modules
220
+ - Update CSS loaders to use Rspack's built-in support
221
+
222
+ ### Step 4: Update Plugins
223
+
224
+ - Replace plugins with Rspack alternatives (see table above)
225
+ - Remove incompatible plugins
226
+ - Add Rspack-specific plugins as needed
227
+
228
+ ### Step 5: TypeScript Setup
229
+
230
+ 1. Add `isolatedModules: true` to `tsconfig.json`
231
+ 2. Optional: Add `ts-checker-rspack-plugin` for type checking
232
+
233
+ ### Step 6: Test Your Build
234
+
235
+ ```bash
236
+ # Development build
237
+ bin/shakapacker
238
+
239
+ # Production build
240
+ bin/shakapacker --mode production
241
+ ```
242
+
243
+ ## Common Issues and Solutions
244
+
245
+ ### Issue: LimitChunkCountPlugin Error
246
+
247
+ **Error:** `Cannot read properties of undefined (reading 'tap')`
248
+ **Solution:** Remove `webpack.optimize.LimitChunkCountPlugin` and use `splitChunks` configuration instead.
249
+
250
+ ### Issue: Missing Loaders
251
+
252
+ **Error:** Module parse errors
253
+ **Solution:** Check console logs for skipped loaders and install missing dependencies.
254
+
255
+ ### Issue: CSS Extraction
256
+
257
+ **Error:** CSS not being extracted properly
258
+ **Solution:** Use `rspack.CssExtractRspackPlugin` instead of `mini-css-extract-plugin`.
259
+
260
+ ### Issue: TypeScript Errors
261
+
262
+ **Error:** TypeScript compilation errors
263
+ **Solution:** Ensure `isolatedModules: true` is set in `tsconfig.json`.
264
+
265
+ ## Performance Tips
266
+
267
+ 1. **Use Built-in Loaders:** Always prefer Rspack's built-in loaders for better performance
268
+ 2. **Minimize Plugins:** Use only necessary plugins as each adds overhead
269
+ 3. **Enable Caching:** Rspack has built-in persistent caching
270
+ 4. **Use SWC:** The built-in SWC loader is significantly faster than Babel
271
+
272
+ ## Debugging Configuration
273
+
274
+ To compare your webpack and rspack configurations during migration:
275
+
276
+ ```bash
277
+ # Export webpack configs before switching
278
+ bin/export-bundler-config --doctor
279
+
280
+ # Switch to rspack
281
+ rails shakapacker:switch_bundler rspack --install-deps
282
+
283
+ # Export rspack configs to compare
284
+ bin/export-bundler-config --doctor
285
+
286
+ # Compare the files in shakapacker-config-exports/
287
+ diff shakapacker-config-exports/webpack-production-client.yaml \
288
+ shakapacker-config-exports/rspack-production-client.yaml
289
+ ```
290
+
291
+ The config export utility creates annotated YAML files that make it easy to:
292
+
293
+ - Verify plugin replacements are correct
294
+ - Compare loader configurations
295
+ - Identify missing or different options
296
+ - Debug configuration issues
297
+
298
+ See the [Troubleshooting Guide](./troubleshooting.md#exporting-webpack--rspack-configuration) for more details.
299
+
300
+ ## Resources
301
+
302
+ - [Rspack Documentation](https://rspack.rs)
303
+ - [Rspack Examples](https://github.com/rspack-contrib/rspack-examples)
304
+ - [Awesome Rspack](https://github.com/rspack-contrib/awesome-rspack)
305
+ - [Migration Guide](https://rspack.rs/guide/migration/webpack)
@@ -0,0 +1,54 @@
1
+ # Subresource integrity
2
+ It's a cryptographic hash that helps browsers check that the served js or css file has not been tampered in any way.
3
+
4
+ [MDN - Subresource Integrity](https://developer.mozilla.org/en-US/docs/Web/Security/Subresource_Integrity)
5
+
6
+ ## Important notes
7
+ - If you somehow modify the file after the hash was generated, it will automatically be considered as tampered, and the browser will not allow it to be executed.
8
+ - Enabling subresource integrity generation, will change the structure of `manifest.json`. Keep that in mind if you utilize this file in any other custom implementation.
9
+
10
+ Before:
11
+ ```json
12
+ {
13
+ "application.js": "/path_to_asset"
14
+ }
15
+ ```
16
+
17
+ After:
18
+ ```json
19
+ {
20
+ "application.js": {
21
+ "src": "/path_to_asset",
22
+ "integrity": "<sha256-hash> <sha384-hash> <sha512-hash>"
23
+ }
24
+ }
25
+ ```
26
+
27
+ ## Possible CORS issues
28
+ Enabling subresource integrity for an asset, actually enforces CORS checks on that resource too. Which means that
29
+ if you haven't set that up properly beforehand, it will probably lead to CORS errors with cached assets.
30
+
31
+ [MDN - How browsers handle Subresource Integrity](https://developer.mozilla.org/en-US/docs/Web/Security/Subresource_Integrity#how_browsers_handle_subresource_integrity)
32
+
33
+ ## Configuration
34
+
35
+ By default, this setting is disabled, to ensure backwards compatibility, and let developers adapt at their own pace.
36
+ This may change in the future, as it is a very nice security feature, and it should be enabled by default.
37
+
38
+ To enable it, just add this in `shakapacker.yml`
39
+ ```yml
40
+ integrity:
41
+ enabled: true
42
+ ```
43
+
44
+ For further customization, you can also utilize the options `hash_functions` that control the functions used to generate
45
+ integrity hashes. And `cross_origin` that sets the cross-origin loading attribute.
46
+
47
+ ```yml
48
+ integrity:
49
+ enabled: true
50
+ hash_functions: ["sha256", "sha384", "sha512"]
51
+ cross_origin: "anonymous" # or "use-credentials"
52
+ ```
53
+
54
+ This will utilize under the hood webpack-subresource-integrity plugin and will modify `manifest.json` to include integrity hashes.
@@ -0,0 +1,209 @@
1
+ # JavaScript Transpiler Configuration
2
+
3
+ > 💡 **Quick Start**: For a concise guide to migrating from Babel to SWC, see [Common Upgrades Guide - Babel to SWC](./common-upgrades.md#migrating-from-babel-to-swc).
4
+
5
+ ## Default Transpilers
6
+
7
+ Shakapacker uses different default JavaScript transpilers based on the bundler:
8
+
9
+ - **Webpack**: `babel` (default) - Maintains backward compatibility
10
+ - **Rspack**: `swc` (default) - Modern, faster transpiler for new bundler
11
+
12
+ ## Available Transpilers
13
+
14
+ - `babel` - Traditional JavaScript transpiler with wide ecosystem support
15
+ - `swc` - Rust-based transpiler, 20-70x faster than Babel
16
+ - `esbuild` - Go-based transpiler, extremely fast
17
+ - `none` - No transpilation (use native JavaScript)
18
+
19
+ ## Configuration
20
+
21
+ Set the transpiler in your `config/shakapacker.yml`:
22
+
23
+ ```yaml
24
+ default: &default
25
+ # For webpack users (babel is default, no change needed)
26
+ javascript_transpiler: babel
27
+
28
+ # To opt-in to SWC for better performance
29
+ javascript_transpiler: swc
30
+
31
+ # For rspack users (swc is default, no change needed)
32
+ assets_bundler: rspack
33
+ javascript_transpiler: swc
34
+ ```
35
+
36
+ ## Migration Guide
37
+
38
+ ### Migrating from Babel to SWC
39
+
40
+ SWC offers significant performance improvements while maintaining high compatibility with Babel.
41
+
42
+ #### 1. Install SWC dependencies
43
+
44
+ ```bash
45
+ yarn add --dev @swc/core swc-loader
46
+ ```
47
+
48
+ #### 2. Update your configuration
49
+
50
+ ```yaml
51
+ # config/shakapacker.yml
52
+ default: &default
53
+ javascript_transpiler: swc
54
+ ```
55
+
56
+ #### 3. Create SWC configuration (optional)
57
+
58
+ If you need custom transpilation settings, create `config/swc.config.js`:
59
+
60
+ ```javascript
61
+ // config/swc.config.js
62
+ // This file is merged with Shakapacker's default SWC configuration
63
+ // See: https://swc.rs/docs/configuration/compilation
64
+
65
+ module.exports = {
66
+ jsc: {
67
+ transform: {
68
+ react: {
69
+ runtime: "automatic"
70
+ }
71
+ }
72
+ }
73
+ }
74
+ ```
75
+
76
+ **Important:** Use `config/swc.config.js` instead of `.swcrc`. The `.swcrc` file completely overrides Shakapacker's default SWC settings and can cause build failures. `config/swc.config.js` properly merges with Shakapacker's defaults.
77
+
78
+ #### 4. Update React configuration (if using React)
79
+
80
+ For React projects, ensure you have the correct refresh plugin:
81
+
82
+ ```bash
83
+ # For webpack
84
+ yarn add --dev @pmmmwh/react-refresh-webpack-plugin
85
+
86
+ # For rspack
87
+ yarn add --dev @rspack/plugin-react-refresh
88
+ ```
89
+
90
+ ### Performance Comparison
91
+
92
+ Typical build time improvements when migrating from Babel to SWC:
93
+
94
+ | Project Size | Babel | SWC | Improvement |
95
+ | ---------------------- | ----- | --- | ----------- |
96
+ | Small (<100 files) | 5s | 1s | 5x faster |
97
+ | Medium (100-500 files) | 20s | 3s | 6.7x faster |
98
+ | Large (500+ files) | 60s | 8s | 7.5x faster |
99
+
100
+ ### Compatibility Notes
101
+
102
+ #### Babel Features Not Yet in SWC
103
+
104
+ - Some experimental/stage-0 proposals
105
+ - Custom Babel plugins (need SWC equivalents)
106
+ - Babel macros
107
+
108
+ #### Migration Checklist
109
+
110
+ - [ ] Back up your current configuration
111
+ - [ ] Install SWC dependencies
112
+ - [ ] Update `shakapacker.yml`
113
+ - [ ] If using Stimulus, ensure `keepClassNames: true` is set in `config/swc.config.js` (automatically included in v9.1.0+)
114
+ - [ ] Test your build locally
115
+ - [ ] Run your test suite
116
+ - [ ] Check browser compatibility
117
+ - [ ] Deploy to staging environment
118
+ - [ ] Monitor for any runtime issues
119
+
120
+ #### Stimulus Compatibility
121
+
122
+ If you're using [Stimulus](https://stimulus.hotwired.dev/), you must configure SWC to preserve class names. See the [Using SWC with Stimulus](using_swc_loader.md#using-swc-with-stimulus) section for detailed instructions.
123
+
124
+ **Quick summary:** Add `keepClassNames: true` to your `config/swc.config.js`:
125
+
126
+ ```javascript
127
+ module.exports = {
128
+ options: {
129
+ jsc: {
130
+ keepClassNames: true // Required for Stimulus
131
+ }
132
+ }
133
+ }
134
+ ```
135
+
136
+ Starting with Shakapacker v9.1.0, running `rake shakapacker:migrate_to_swc` automatically creates a configuration with this setting.
137
+
138
+ ### Rollback Plan
139
+
140
+ If you encounter issues, rolling back is simple:
141
+
142
+ ```yaml
143
+ # config/shakapacker.yml
144
+ default: &default
145
+ javascript_transpiler: babel # Revert to babel
146
+ ```
147
+
148
+ Then rebuild your application:
149
+
150
+ ```bash
151
+ bin/shakapacker clobber
152
+ bin/shakapacker compile
153
+ ```
154
+
155
+ ## Environment Variables
156
+
157
+ You can also control the transpiler via environment variables:
158
+
159
+ ```bash
160
+ # Override config file setting
161
+ SHAKAPACKER_JAVASCRIPT_TRANSPILER=swc bin/shakapacker compile
162
+
163
+ # For debugging
164
+ SHAKAPACKER_DEBUG_CACHE=true bin/shakapacker compile
165
+ ```
166
+
167
+ ## Troubleshooting
168
+
169
+ ### Issue: Build fails after switching to SWC
170
+
171
+ **Solution**: Ensure all SWC dependencies are installed:
172
+
173
+ ```bash
174
+ yarn add --dev @swc/core swc-loader
175
+ ```
176
+
177
+ ### Issue: React Fast Refresh not working
178
+
179
+ **Solution**: Install the correct refresh plugin for your bundler:
180
+
181
+ ```bash
182
+ # Webpack
183
+ yarn add --dev @pmmmwh/react-refresh-webpack-plugin
184
+
185
+ # Rspack
186
+ yarn add --dev @rspack/plugin-react-refresh
187
+ ```
188
+
189
+ ### Issue: Decorators not working
190
+
191
+ **Solution**: Enable decorator support in `config/swc.config.js`:
192
+
193
+ ```javascript
194
+ // config/swc.config.js
195
+ module.exports = {
196
+ jsc: {
197
+ parser: {
198
+ decorators: true,
199
+ decoratorsBeforeExport: true
200
+ }
201
+ }
202
+ }
203
+ ```
204
+
205
+ ## Further Reading
206
+
207
+ - [SWC Documentation](https://swc.rs/docs/getting-started)
208
+ - [Babel to SWC Migration Guide](https://swc.rs/docs/migrating-from-babel)
209
+ - [Rspack Configuration](https://www.rspack.dev/config/index)