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,198 @@
1
+ # Optional Peer Dependencies in Shakapacker
2
+
3
+ ## Overview
4
+
5
+ As of Shakapacker v9, all peer dependencies are marked as optional via `peerDependenciesMeta`. This design provides maximum flexibility while maintaining clear version constraints.
6
+
7
+ ## Key Benefits
8
+
9
+ 1. **No Installation Warnings** - Package managers (npm, yarn, pnpm) won't warn about missing peer dependencies
10
+ 2. **Install Only What You Need** - Users only install packages for their chosen configuration
11
+ 3. **Clear Version Constraints** - When packages are installed, version compatibility is still enforced
12
+ 4. **Smaller Node Modules** - Reduced disk usage by not installing unnecessary packages
13
+
14
+ ## Implementation Details
15
+
16
+ ### Package.json Structure
17
+
18
+ ```json
19
+ {
20
+ "dependencies": {
21
+ "js-yaml": "^4.1.0",
22
+ "path-complete-extname": "^1.0.0",
23
+ "webpack-merge": "^5.8.0" // Direct dependency - always available
24
+ },
25
+ "peerDependencies": {
26
+ "webpack": "^5.76.0",
27
+ "@rspack/core": "^1.0.0",
28
+ // ... all build tools
29
+ },
30
+ "peerDependenciesMeta": {
31
+ "webpack": { "optional": true },
32
+ "@rspack/core": { "optional": true },
33
+ // ... all marked as optional
34
+ }
35
+ }
36
+ ```
37
+
38
+ ### TypeScript Type-Only Imports
39
+
40
+ To prevent runtime errors when optional packages aren't installed, all webpack imports use type-only syntax:
41
+
42
+ ```typescript
43
+ // @ts-ignore: webpack is an optional peer dependency (using type-only import)
44
+ import type { Configuration } from "webpack"
45
+ ```
46
+
47
+ Type-only imports are erased during compilation and don't trigger module resolution at runtime.
48
+
49
+ ## Configuration Examples
50
+
51
+ ### Webpack + Babel (Traditional)
52
+ ```json
53
+ {
54
+ "dependencies": {
55
+ "shakapacker": "^9.0.0",
56
+ "webpack": "^5.76.0",
57
+ "webpack-cli": "^5.0.0",
58
+ "babel-loader": "^8.2.4",
59
+ "@babel/core": "^7.17.9",
60
+ "@babel/preset-env": "^7.16.11"
61
+ }
62
+ }
63
+ ```
64
+
65
+ ### Webpack + SWC (20x Faster)
66
+ ```json
67
+ {
68
+ "dependencies": {
69
+ "shakapacker": "^9.0.0",
70
+ "webpack": "^5.76.0",
71
+ "webpack-cli": "^5.0.0",
72
+ "@swc/core": "^1.3.0",
73
+ "swc-loader": "^0.2.0"
74
+ }
75
+ }
76
+ ```
77
+
78
+ ### Rspack + SWC (10x Faster Bundling)
79
+ ```json
80
+ {
81
+ "dependencies": {
82
+ "shakapacker": "^9.0.0",
83
+ "@rspack/core": "^1.0.0",
84
+ "@rspack/cli": "^1.0.0",
85
+ "rspack-manifest-plugin": "^5.0.0"
86
+ }
87
+ }
88
+ ```
89
+
90
+ ## Migration Guide
91
+
92
+ ### From v8 to v9
93
+
94
+ If upgrading from Shakapacker v8:
95
+
96
+ 1. **No action required** - Your existing dependencies will continue to work
97
+ 2. **No more warnings** - Peer dependency warnings will disappear after upgrading
98
+ 3. **Option to optimize** - You can now remove unused dependencies (e.g., remove Babel if using SWC)
99
+
100
+ ### New Installations
101
+
102
+ The installer (`rails shakapacker:install`) only adds packages needed for your configuration:
103
+ - Detects your preferred bundler (webpack/rspack)
104
+ - Installs appropriate JavaScript transpiler (babel/swc/esbuild)
105
+ - Adds only required dependencies
106
+
107
+ ## Version Constraints
108
+
109
+ Version ranges are carefully chosen for compatibility:
110
+
111
+ - **Broader ranges for peer deps** - Allows flexibility (e.g., `^5.76.0` for webpack)
112
+ - **Specific versions in devDeps** - Ensures testing against known versions
113
+ - **Forward compatibility** - Ranges include future minor versions (e.g., `^5.0.0 || ^6.0.0`)
114
+
115
+ ## Testing
116
+
117
+ ### Installation Tests
118
+
119
+ Test that no warnings appear during installation:
120
+
121
+ ```bash
122
+ # Test script available at test/peer-dependencies.sh
123
+ ./test/peer-dependencies.sh
124
+ ```
125
+
126
+ ### Runtime Tests
127
+
128
+ Verify Shakapacker loads without optional dependencies:
129
+
130
+ ```javascript
131
+ // This works even without webpack installed (when using rspack)
132
+ const shakapacker = require('shakapacker');
133
+ ```
134
+
135
+ ### CI Integration
136
+
137
+ The test suite includes:
138
+ - `spec/shakapacker/optional_dependencies_spec.rb` - Package.json structure validation
139
+ - `spec/shakapacker/doctor_optional_peer_spec.rb` - Doctor command validation
140
+ - `test/peer-dependencies.sh` - Installation warning tests
141
+
142
+ ## Troubleshooting
143
+
144
+ ### Still seeing peer dependency warnings?
145
+
146
+ 1. Ensure you're using Shakapacker v9.0.0 or later
147
+ 2. Clear your package manager cache:
148
+ - npm: `npm cache clean --force`
149
+ - yarn: `yarn cache clean`
150
+ - pnpm: `pnpm store prune`
151
+ 3. Reinstall dependencies
152
+
153
+ ### Module not found errors?
154
+
155
+ 1. Check you've installed required dependencies for your configuration
156
+ 2. Refer to the configuration examples above
157
+ 3. Run `rails shakapacker:doctor` for diagnostics
158
+
159
+ ### TypeScript errors?
160
+
161
+ The `@ts-ignore` comments are intentional and necessary for optional dependencies.
162
+ They prevent TypeScript errors when optional packages aren't installed.
163
+
164
+ ## Contributing
165
+
166
+ When adding new dependencies:
167
+
168
+ 1. Add to `peerDependencies` with appropriate version range
169
+ 2. Mark as optional in `peerDependenciesMeta`
170
+ 3. Use type-only imports in TypeScript: `import type { ... }`
171
+ 4. Test with all package managers (npm, yarn, pnpm)
172
+ 5. Update this documentation if needed
173
+
174
+ ## Design Rationale
175
+
176
+ This approach balances several concerns:
177
+
178
+ 1. **User Experience** - No confusing warnings during installation
179
+ 2. **Flexibility** - Support multiple configurations without forcing unnecessary installs
180
+ 3. **Compatibility** - Maintain version constraints for safety
181
+ 4. **Performance** - Reduce installation time and disk usage
182
+ 5. **Type Safety** - TypeScript support without runtime dependencies
183
+
184
+ ## Future Improvements
185
+
186
+ Potential enhancements for future versions:
187
+
188
+ 1. **Conditional exports** - Use package.json exports field for better tree-shaking
189
+ 2. **Dynamic imports** - Load bundler-specific code only when needed
190
+ 3. **Doctor updates** - Enhance doctor command to better understand optional dependencies
191
+ 4. **Automated testing** - Add CI jobs testing each configuration combination
192
+
193
+ ## References
194
+
195
+ - [npm: peerDependenciesMeta](https://docs.npmjs.com/cli/v8/configuring-npm/package-json#peerdependenciesmeta)
196
+ - [TypeScript: Type-Only Imports](https://www.typescriptlang.org/docs/handbook/modules.html#type-only-imports-and-exports)
197
+ - [Shakapacker Issue #565](https://github.com/shakacode/shakapacker/issues/565)
198
+ - [Pull Request #615](https://github.com/shakacode/shakapacker/pull/615)
@@ -0,0 +1,60 @@
1
+ # Shakapacker's Peer Dependencies
2
+ ## Last updated for our 9.0.0 version — see lib/install/package.json
3
+
4
+ To simplify peer dependencies while supporting both webpack & rspack, we decided to document the dependencies here instead of creating two separate npm packages.
5
+
6
+ **Important Note**: Starting with v9, Babel dependencies are no longer included as peer dependencies. They will be installed automatically only if you're using Babel as your JavaScript transpiler.
7
+
8
+ ## Essential for Rspack
9
+ ```
10
+ "@rspack/cli": "^1.0.0",
11
+ "@rspack/core": "^1.0.0",
12
+ "rspack-manifest-plugin": "^5.0.0",
13
+ ```
14
+ ## Essential for Webpack
15
+ ```
16
+ "mini-css-extract-plugin": "^2.0.0",
17
+ "terser-webpack-plugin": "^5.3.1",
18
+ "webpack": "^5.76.0",
19
+ "webpack-assets-manifest": "^5.0.6 || ^6.0.0",
20
+ "webpack-cli": "^4.9.2 || ^5.0.0 || ^6.0.0",
21
+ "webpack-dev-server": "^4.15.2 || ^5.2.2",
22
+ "webpack-merge": "^5.8.0 || ^6.0.0",
23
+ "webpack-subresource-integrity": "^5.1.0"
24
+ ```
25
+
26
+ ## Highly recommended
27
+ ```
28
+ "compression-webpack-plugin": "^9.0.0 || ^10.0.0|| ^11.0.0",
29
+ "css-loader": "^6.0.0 || ^7.0.0",
30
+ "sass-loader": "^13.0.0 || ^14.0.0 || ^15.0.0 || ^16.0.0",
31
+ "style-loader": "^3.0.0 || ^4.0.0",
32
+ ```
33
+
34
+ ## Optional JavaScript Transpilers
35
+
36
+ ### Babel (installed automatically when `javascript_transpiler: 'babel'`)
37
+ ```
38
+ "@babel/core": "^7.17.9",
39
+ "@babel/plugin-transform-runtime": "^7.17.0",
40
+ "@babel/preset-env": "^7.16.11",
41
+ "@babel/runtime": "^7.17.9",
42
+ "babel-loader": "^8.2.4 || ^9.0.0 || ^10.0.0",
43
+ ```
44
+ Note: These dependencies are only installed if you're using Babel as your JavaScript transpiler. Consider using SWC or esbuild for better performance.
45
+
46
+ ### SWC (default - 20x faster than Babel)
47
+ ```
48
+ "@swc/core": "latest",
49
+ "swc-loader": "latest"
50
+ ```
51
+ - **For webpack**: Installed automatically when using default configuration
52
+ - **For rspack**: Built-in, no additional installation needed (rspack includes SWC natively)
53
+ - Manual install: `npm install @swc/core swc-loader`
54
+
55
+ ### esbuild
56
+ ```
57
+ "esbuild": "latest",
58
+ "esbuild-loader": "latest"
59
+ ```
60
+ Install manually with: `npm install esbuild esbuild-loader`
data/docs/react.md CHANGED
@@ -34,7 +34,7 @@ Update the Babel configuration in the `package.json` file:
34
34
  },
35
35
  ```
36
36
 
37
- And that's it. You can now create a React app using `app/javascript/application.js` as your entry point.
37
+ And that's it. You can now create a React app using `app/javascript/packs/application.js` as your entry point.
38
38
 
39
39
  ## Enabling Hot Module Replacement (HMR)
40
40
 
@@ -61,11 +61,7 @@ const webpackConfig = generateWebpackConfig();
61
61
 
62
62
  if (isDevelopment && inliningCss) {
63
63
  webpackConfig.plugins.push(
64
- new ReactRefreshWebpackPlugin({
65
- overlay: {
66
- sockPort: webpackConfig.devServer.port,
67
- },
68
- })
64
+ new ReactRefreshWebpackPlugin()
69
65
  );
70
66
  }
71
67
 
@@ -152,11 +148,11 @@ echo '<div id="root"></div>' > app/views/site/index.html.erb
152
148
  touch app/javascript/App.css app/javascript/App.js
153
149
  ```
154
150
 
155
- 4. Edit `app/javascript/application.js` like so:
151
+ 4. Edit `app/javascript/packs/application.js` like so:
156
152
  ```jsx
157
153
  import React from 'react';
158
154
  import { createRoot } from 'react-dom/client';
159
- import HelloMessage from './App';
155
+ import HelloMessage from '../App';
160
156
 
161
157
  const container = document.getElementById('root');
162
158
  const root = createRoot(container);
@@ -201,11 +197,7 @@ const webpackConfig = generateWebpackConfig();
201
197
 
202
198
  if (isDevelopment && inliningCss) {
203
199
  webpackConfig.plugins.push(
204
- new ReactRefreshWebpackPlugin({
205
- overlay: {
206
- sockPort: webpackConfig.devServer.port,
207
- },
208
- })
200
+ new ReactRefreshWebpackPlugin()
209
201
  );
210
202
  }
211
203
 
@@ -267,4 +259,4 @@ rails s
267
259
 
268
260
  11. Edit either the React component at `app/javascript/App.js` or the CSS file at `app/javascript/App.css` and observe the HMR goodness.
269
261
 
270
- Note that HMR will not work if you edit `app/javascript/application.js` and experience a full refresh with a warning in the console. For more info on this, see here: https://github.com/pmmmwh/react-refresh-webpack-plugin/issues/177
262
+ Note that HMR will not work if you edit `app/javascript/packs/application.js` and experience a full refresh with a warning in the console. For more info on this, see here: https://github.com/pmmmwh/react-refresh-webpack-plugin/issues/177
data/docs/releasing.md ADDED
@@ -0,0 +1,197 @@
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
+
16
+ - npm: You must be a collaborator on the [shakapacker npm package](https://www.npmjs.com/package/shakapacker)
17
+ - RubyGems: You must be an owner of the [shakapacker gem](https://rubygems.org/gems/shakapacker)
18
+
19
+ 3. **Enable 2FA on both platforms:**
20
+ - npm: 2FA is required for publishing
21
+ - RubyGems: 2FA is required for publishing
22
+
23
+ ## Release Process
24
+
25
+ ### 1. Prepare the Release
26
+
27
+ Before running the release task:
28
+
29
+ 1. Ensure all desired changes are merged to `main` branch
30
+ 2. Update `CHANGELOG.md` with the new version and release notes
31
+ 3. Commit the CHANGELOG changes
32
+ 4. Ensure your working directory is clean (`git status` shows no uncommitted changes)
33
+
34
+ ### 2. Run the Release Task
35
+
36
+ The automated release task handles the entire release process:
37
+
38
+ ```bash
39
+ # For a specific version (e.g., 9.1.0)
40
+ rake create_release[9.1.0]
41
+
42
+ # For a beta release (note: use period, not dash)
43
+ rake create_release[9.2.0.beta.1] # Creates npm package 9.2.0-beta.1
44
+
45
+ # For a patch version bump (auto-increments)
46
+ rake create_release
47
+
48
+ # Dry run to test without publishing
49
+ rake create_release[9.1.0,true]
50
+ ```
51
+
52
+ ### 3. What the Release Task Does
53
+
54
+ The `create_release` task automatically:
55
+
56
+ 1. **Pulls latest changes** from the repository
57
+ 2. **Bumps version numbers** in:
58
+ - `lib/shakapacker/version.rb` (Ruby gem version)
59
+ - `package.json` (npm package version - converted from Ruby format)
60
+ 3. **Publishes to npm:**
61
+ - Prompts for npm OTP (2FA code)
62
+ - Creates git tag
63
+ - Pushes to GitHub
64
+ 4. **Publishes to RubyGems:**
65
+ - Prompts for RubyGems OTP (2FA code)
66
+ 5. **Updates spec/dummy lockfiles:**
67
+ - Runs `bundle install` to update `Gemfile.lock`
68
+ - Runs `npm install` to update `package-lock.json` (yarn.lock may also be updated for multi-package-manager compatibility testing)
69
+ 6. **Commits and pushes lockfile changes** automatically
70
+
71
+ ### 4. Version Format
72
+
73
+ **Important:** Use Ruby gem version format (no dashes):
74
+
75
+ - ✅ Correct: `9.1.0`, `9.2.0.beta.1`, `9.0.0.rc.2`
76
+ - ❌ Wrong: `9.1.0-beta.1`, `9.0.0-rc.2`
77
+
78
+ The task automatically converts Ruby gem format to npm semver format:
79
+
80
+ - Ruby: `9.2.0.beta.1` → npm: `9.2.0-beta.1`
81
+ - Ruby: `9.0.0.rc.2` → npm: `9.0.0-rc.2`
82
+
83
+ **Examples:**
84
+
85
+ ```bash
86
+ # Regular release
87
+ rake create_release[9.1.0] # Gem: 9.1.0, npm: 9.1.0
88
+
89
+ # Beta release
90
+ rake create_release[9.2.0.beta.1] # Gem: 9.2.0.beta.1, npm: 9.2.0-beta.1
91
+
92
+ # Release candidate
93
+ rake create_release[10.0.0.rc.1] # Gem: 10.0.0.rc.1, npm: 10.0.0-rc.1
94
+ ```
95
+
96
+ ### 5. During the Release
97
+
98
+ 1. When prompted for **npm OTP**, enter your 2FA code from your authenticator app
99
+ 2. Accept defaults for release-it options
100
+ 3. When prompted for **RubyGems OTP**, enter your 2FA code
101
+ 4. The script will automatically commit and push lockfile updates
102
+
103
+ ### 6. After Release
104
+
105
+ 1. Verify the release on:
106
+
107
+ - [npm](https://www.npmjs.com/package/shakapacker)
108
+ - [RubyGems](https://rubygems.org/gems/shakapacker)
109
+ - [GitHub releases](https://github.com/shakacode/shakapacker/releases)
110
+
111
+ 2. Check that the lockfile commit was pushed:
112
+
113
+ ```bash
114
+ git log --oneline -5
115
+ # Should see "Update spec/dummy lockfiles after release"
116
+ ```
117
+
118
+ 3. Announce the release (if appropriate):
119
+ - Post in relevant Slack/Discord channels
120
+ - Tweet about major releases
121
+ - Update documentation if needed
122
+
123
+ ## Troubleshooting
124
+
125
+ ### Uncommitted Changes After Release
126
+
127
+ If you see uncommitted changes to lockfiles after a release, this means:
128
+
129
+ 1. The release was successful but the lockfile commit step may have failed
130
+ 2. **Solution:** Manually commit these files:
131
+ ```bash
132
+ git add spec/dummy/Gemfile.lock spec/dummy/package-lock.json spec/dummy/yarn.lock
133
+ git commit -m 'Update spec/dummy lockfiles after release'
134
+ git push
135
+ ```
136
+
137
+ ### Failed npm or RubyGems Publish
138
+
139
+ If publishing fails partway through:
140
+
141
+ 1. Check which step failed (npm or RubyGems)
142
+ 2. If npm failed: Fix the issue and manually run `npm publish`
143
+ 3. If RubyGems failed: Fix the issue and manually run `gem release`
144
+ 4. Then manually update and commit spec/dummy lockfiles
145
+
146
+ ### Wrong Version Format
147
+
148
+ If you accidentally use npm format (with dashes):
149
+
150
+ 1. The gem will be created with an invalid version
151
+ 2. **Solution:** Don't push the changes, reset your branch:
152
+ ```bash
153
+ git reset --hard HEAD
154
+ ```
155
+ 3. Re-run with correct Ruby gem format
156
+
157
+ ## Manual Release Steps
158
+
159
+ If you need to release manually (not recommended):
160
+
161
+ 1. **Bump version:**
162
+
163
+ ```bash
164
+ gem bump --version 9.1.0
165
+ bundle install
166
+ ```
167
+
168
+ 2. **Publish to npm:**
169
+
170
+ ```bash
171
+ release-it 9.1.0 --npm.publish
172
+ ```
173
+
174
+ 3. **Publish to RubyGems:**
175
+
176
+ ```bash
177
+ gem release
178
+ ```
179
+
180
+ 4. **Update lockfiles:**
181
+ ```bash
182
+ cd spec/dummy
183
+ bundle install
184
+ npm install
185
+ cd ../..
186
+ git add spec/dummy/Gemfile.lock spec/dummy/package-lock.json spec/dummy/yarn.lock
187
+ git commit -m 'Update spec/dummy lockfiles after release'
188
+ git push
189
+ ```
190
+
191
+ ## Questions?
192
+
193
+ If you encounter issues not covered here, please:
194
+
195
+ 1. Check the [CONTRIBUTING.md](../CONTRIBUTING.md) guide
196
+ 2. Ask in the maintainers channel
197
+ 3. Update this documentation for future releases
data/docs/rspack.md ADDED
@@ -0,0 +1,190 @@
1
+ # Rspack Integration
2
+
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
+
5
+ ## Installation
6
+
7
+ First, install the required Rspack dependencies:
8
+
9
+ ```bash
10
+ npm install @rspack/core @rspack/cli -D
11
+ # or
12
+ yarn add @rspack/core @rspack/cli -D
13
+ # or
14
+ pnpm add @rspack/core @rspack/cli -D
15
+ # or
16
+ bun add @rspack/core @rspack/cli -D
17
+ ```
18
+
19
+ Note: These packages are already listed as optional peer dependencies in Shakapacker, so you may see warnings if they're not installed.
20
+
21
+ ## Configuration
22
+
23
+ To enable Rspack, update your `config/shakapacker.yml`:
24
+
25
+ ```yaml
26
+ default: &default
27
+ # ... other config options
28
+ assets_bundler: 'rspack' # Change from 'webpack' to 'rspack'
29
+ ```
30
+
31
+ ### Configuration Files
32
+
33
+ Rspack uses its own configuration directory to keep things organized. Create your Rspack configuration file at `config/rspack/rspack.config.js`:
34
+
35
+ ```javascript
36
+ const { generateRspackConfig } = require('shakapacker/rspack')
37
+
38
+ module.exports = generateRspackConfig()
39
+ ```
40
+
41
+ ### Custom Configuration
42
+
43
+ If you need to customize your Rspack configuration:
44
+
45
+ ```javascript
46
+ const { generateRspackConfig } = require('shakapacker/rspack')
47
+
48
+ const rspackConfig = generateRspackConfig({
49
+ plugins: [
50
+ new SomeRspackCompatiblePlugin()
51
+ ],
52
+ resolve: {
53
+ extensions: ['.ts', '.tsx', '.js', '.jsx']
54
+ }
55
+ })
56
+
57
+ module.exports = rspackConfig
58
+ ```
59
+
60
+ ### Migration from Webpack Config
61
+
62
+ If you have an existing `config/webpack/webpack.config.js`, you can migrate it to `config/rspack/rspack.config.js`:
63
+
64
+ **Old (webpack.config.js):**
65
+ ```javascript
66
+ const { generateWebpackConfig } = require('shakapacker')
67
+ module.exports = generateWebpackConfig()
68
+ ```
69
+
70
+ **New (rspack.config.js):**
71
+ ```javascript
72
+ const { generateRspackConfig } = require('shakapacker/rspack')
73
+ module.exports = generateRspackConfig()
74
+ ```
75
+
76
+ > **Note:** Shakapacker will show a deprecation warning if you use `config/webpack/webpack.config.js` with `assets_bundler: 'rspack'`. Please migrate to `config/rspack/rspack.config.js`.
77
+
78
+ ## Key Differences from Webpack
79
+
80
+ ### Built-in Loaders
81
+
82
+ Rspack has built-in loaders that are faster than their webpack counterparts:
83
+
84
+ - **JavaScript/TypeScript**: Uses `builtin:swc-loader` instead of `babel-loader`
85
+ - **CSS Extraction**: Uses `rspack.CssExtractRspackPlugin` instead of `mini-css-extract-plugin`
86
+ - **Asset Handling**: Uses built-in asset modules instead of `file-loader`/`url-loader`
87
+
88
+ ### Plugin Compatibility
89
+
90
+ Most webpack plugins work with Rspack, but some have Rspack-specific alternatives:
91
+
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 |
97
+
98
+ ### Minification
99
+
100
+ Rspack uses SWC for minification by default, which is significantly faster than Terser:
101
+
102
+ ```javascript
103
+ optimization: {
104
+ minimize: true,
105
+ minimizer: [
106
+ new rspack.SwcJsMinimizerRspackPlugin(),
107
+ new rspack.SwcCssMinimizerRspackPlugin()
108
+ ]
109
+ }
110
+ ```
111
+
112
+ ## Limitations
113
+
114
+ - **CoffeeScript**: Not supported with Rspack
115
+ - **Some Webpack Plugins**: May not be compatible; check Rspack documentation
116
+
117
+ ## Commands
118
+
119
+ All existing Shakapacker commands work the same way and automatically use Rspack when configured:
120
+
121
+ ```bash
122
+ # Build (automatically uses rspack when assets_bundler: 'rspack')
123
+ ./bin/shakapacker
124
+
125
+ # Development server (automatically uses rspack when assets_bundler: 'rspack')
126
+ ./bin/shakapacker-dev-server
127
+
128
+ # Watch mode
129
+ ./bin/shakapacker --watch
130
+ ```
131
+
132
+ The same dev server configuration in `shakapacker.yml` applies to both webpack and rspack.
133
+
134
+ ## Performance Benefits
135
+
136
+ Rspack typically provides:
137
+
138
+ - **2-10x faster** cold builds
139
+ - **5-20x faster** incremental builds
140
+ - **Faster HMR** (Hot Module Replacement)
141
+ - **Lower memory usage**
142
+
143
+ ## Migration Checklist
144
+
145
+ 1. **Install Rspack dependencies:**
146
+ ```bash
147
+ npm install @rspack/core @rspack/cli -D
148
+ ```
149
+
150
+ 2. **Update configuration:**
151
+ ```yaml
152
+ # config/shakapacker.yml
153
+ default: &default
154
+ assets_bundler: 'rspack'
155
+ ```
156
+
157
+ 3. **Create Rspack config:**
158
+ ```javascript
159
+ // config/rspack/rspack.config.js
160
+ const { generateRspackConfig } = require('shakapacker/rspack')
161
+ module.exports = generateRspackConfig()
162
+ ```
163
+
164
+ 4. **Remove CoffeeScript files** (if any) - not supported by Rspack
165
+
166
+ 5. **Test your application** - same commands work automatically
167
+
168
+ ## Troubleshooting
169
+
170
+ ### Configuration Issues
171
+
172
+ If you encounter configuration issues:
173
+
174
+ 1. Check that all plugins are Rspack-compatible
175
+ 2. Verify custom loaders work with Rspack
176
+ 3. Review the [Rspack migration guide](https://rspack.rs/guide/migration/webpack)
177
+
178
+ ### Performance Issues
179
+
180
+ If builds are unexpectedly slow:
181
+
182
+ 1. Ensure you're using built-in Rspack loaders
183
+ 2. Check for webpack-specific plugins that should be replaced
184
+ 3. Review your asset optimization settings
185
+
186
+ ## Further Reading
187
+
188
+ - [Rspack Official Documentation](https://rspack.rs)
189
+ - [Rspack Migration Guide](https://rspack.rs/guide/migration/webpack)
190
+ - [Rspack Plugins](https://rspack.rs/plugins/webpack/)