shakapacker 8.4.0 → 9.0.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 (166) 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 +8 -4
  9. data/.github/workflows/generator.yml +17 -14
  10. data/.github/workflows/node.yml +23 -1
  11. data/.github/workflows/ruby.yml +11 -0
  12. data/.github/workflows/test-bundlers.yml +170 -0
  13. data/.gitignore +17 -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 +156 -18
  20. data/CLAUDE.md +29 -0
  21. data/CONTRIBUTING.md +138 -20
  22. data/Gemfile.lock +3 -3
  23. data/README.md +130 -5
  24. data/Rakefile +39 -4
  25. data/TODO.md +50 -0
  26. data/TODO_v9.md +87 -0
  27. data/conductor-setup.sh +70 -0
  28. data/conductor.json +7 -0
  29. data/docs/cdn_setup.md +379 -0
  30. data/docs/css-modules-export-mode.md +512 -0
  31. data/docs/deployment.md +10 -1
  32. data/docs/optional-peer-dependencies.md +198 -0
  33. data/docs/peer-dependencies.md +60 -0
  34. data/docs/rspack.md +190 -0
  35. data/docs/rspack_migration_guide.md +202 -0
  36. data/docs/transpiler-migration.md +188 -0
  37. data/docs/transpiler-performance.md +179 -0
  38. data/docs/troubleshooting.md +5 -0
  39. data/docs/typescript-migration.md +378 -0
  40. data/docs/typescript.md +99 -0
  41. data/docs/using_esbuild_loader.md +3 -3
  42. data/docs/using_swc_loader.md +5 -3
  43. data/docs/v6_upgrade.md +10 -0
  44. data/docs/v9_upgrade.md +413 -0
  45. data/lib/install/bin/shakapacker +3 -5
  46. data/lib/install/config/rspack/rspack.config.js +6 -0
  47. data/lib/install/config/rspack/rspack.config.ts +7 -0
  48. data/lib/install/config/shakapacker.yml +12 -2
  49. data/lib/install/config/webpack/webpack.config.ts +7 -0
  50. data/lib/install/package.json +38 -0
  51. data/lib/install/template.rb +194 -44
  52. data/lib/shakapacker/configuration.rb +141 -0
  53. data/lib/shakapacker/dev_server_runner.rb +25 -5
  54. data/lib/shakapacker/doctor.rb +844 -0
  55. data/lib/shakapacker/manifest.rb +4 -2
  56. data/lib/shakapacker/rspack_runner.rb +19 -0
  57. data/lib/shakapacker/runner.rb +144 -4
  58. data/lib/shakapacker/swc_migrator.rb +376 -0
  59. data/lib/shakapacker/utils/manager.rb +2 -0
  60. data/lib/shakapacker/version.rb +1 -1
  61. data/lib/shakapacker/version_checker.rb +1 -1
  62. data/lib/shakapacker/webpack_runner.rb +4 -42
  63. data/lib/shakapacker.rb +2 -1
  64. data/lib/tasks/shakapacker/doctor.rake +8 -0
  65. data/lib/tasks/shakapacker/install.rake +12 -2
  66. data/lib/tasks/shakapacker/migrate_to_swc.rake +13 -0
  67. data/lib/tasks/shakapacker.rake +1 -0
  68. data/package/.npmignore +4 -0
  69. data/package/babel/preset.ts +56 -0
  70. data/package/config.ts +175 -0
  71. data/package/{dev_server.js → dev_server.ts} +8 -5
  72. data/package/env.ts +92 -0
  73. data/package/environments/base.ts +138 -0
  74. data/package/environments/development.ts +90 -0
  75. data/package/environments/production.ts +80 -0
  76. data/package/environments/test.ts +53 -0
  77. data/package/environments/types.ts +90 -0
  78. data/package/esbuild/index.ts +42 -0
  79. data/package/index.d.ts +3 -97
  80. data/package/index.ts +52 -0
  81. data/package/loaders.d.ts +28 -0
  82. data/package/optimization/rspack.ts +36 -0
  83. data/package/optimization/webpack.ts +57 -0
  84. data/package/plugins/rspack.ts +103 -0
  85. data/package/plugins/webpack.ts +62 -0
  86. data/package/rspack/index.ts +64 -0
  87. data/package/rules/{babel.js → babel.ts} +2 -2
  88. data/package/rules/{coffee.js → coffee.ts} +1 -1
  89. data/package/rules/css.ts +3 -0
  90. data/package/rules/{erb.js → erb.ts} +1 -1
  91. data/package/rules/esbuild.ts +10 -0
  92. data/package/rules/file.ts +40 -0
  93. data/package/rules/{jscommon.js → jscommon.ts} +4 -4
  94. data/package/rules/{less.js → less.ts} +4 -4
  95. data/package/rules/raw.ts +25 -0
  96. data/package/rules/rspack.ts +176 -0
  97. data/package/rules/{sass.js → sass.ts} +7 -3
  98. data/package/rules/{stylus.js → stylus.ts} +4 -8
  99. data/package/rules/swc.ts +10 -0
  100. data/package/rules/{index.js → webpack.ts} +1 -1
  101. data/package/swc/index.ts +54 -0
  102. data/package/types/README.md +87 -0
  103. data/package/types/index.ts +60 -0
  104. data/package/types.ts +108 -0
  105. data/package/utils/configPath.ts +6 -0
  106. data/package/utils/debug.ts +49 -0
  107. data/package/utils/defaultConfigPath.ts +4 -0
  108. data/package/utils/errorCodes.ts +219 -0
  109. data/package/utils/errorHelpers.ts +143 -0
  110. data/package/utils/getStyleRule.ts +64 -0
  111. data/package/utils/helpers.ts +85 -0
  112. data/package/utils/{inliningCss.js → inliningCss.ts} +3 -3
  113. data/package/utils/pathValidation.ts +139 -0
  114. data/package/utils/requireOrError.ts +15 -0
  115. data/package/utils/snakeToCamelCase.ts +5 -0
  116. data/package/utils/typeGuards.ts +342 -0
  117. data/package/utils/validateDependencies.ts +61 -0
  118. data/package/webpack-types.d.ts +33 -0
  119. data/package/webpackDevServerConfig.ts +117 -0
  120. data/package.json +134 -9
  121. data/scripts/remove-use-strict.js +45 -0
  122. data/scripts/type-check-no-emit.js +27 -0
  123. data/test/package/config.test.js +3 -0
  124. data/test/package/env.test.js +42 -7
  125. data/test/package/environments/base.test.js +5 -1
  126. data/test/package/rules/babel.test.js +16 -0
  127. data/test/package/rules/esbuild.test.js +1 -1
  128. data/test/package/rules/raw.test.js +40 -7
  129. data/test/package/rules/swc.test.js +1 -1
  130. data/test/package/rules/webpack.test.js +35 -0
  131. data/test/package/staging.test.js +4 -3
  132. data/test/package/transpiler-defaults.test.js +127 -0
  133. data/test/peer-dependencies.sh +85 -0
  134. data/test/scripts/remove-use-strict.test.js +125 -0
  135. data/test/typescript/build.test.js +118 -0
  136. data/test/typescript/environments.test.js +107 -0
  137. data/test/typescript/pathValidation.test.js +142 -0
  138. data/test/typescript/securityValidation.test.js +182 -0
  139. data/tools/README.md +124 -0
  140. data/tools/css-modules-v9-codemod.js +179 -0
  141. data/tsconfig.eslint.json +16 -0
  142. data/tsconfig.json +38 -0
  143. data/yarn.lock +2704 -767
  144. metadata +111 -41
  145. data/package/babel/preset.js +0 -48
  146. data/package/config.js +0 -56
  147. data/package/env.js +0 -48
  148. data/package/environments/base.js +0 -171
  149. data/package/environments/development.js +0 -13
  150. data/package/environments/production.js +0 -88
  151. data/package/environments/test.js +0 -3
  152. data/package/esbuild/index.js +0 -40
  153. data/package/index.js +0 -40
  154. data/package/rules/css.js +0 -3
  155. data/package/rules/esbuild.js +0 -10
  156. data/package/rules/file.js +0 -29
  157. data/package/rules/raw.js +0 -5
  158. data/package/rules/swc.js +0 -10
  159. data/package/swc/index.js +0 -50
  160. data/package/utils/configPath.js +0 -4
  161. data/package/utils/defaultConfigPath.js +0 -2
  162. data/package/utils/getStyleRule.js +0 -40
  163. data/package/utils/helpers.js +0 -62
  164. data/package/utils/snakeToCamelCase.js +0 -5
  165. data/package/webpackDevServerConfig.js +0 -71
  166. data/test/package/rules/index.test.js +0 -16
data/CONTRIBUTING.md CHANGED
@@ -3,6 +3,7 @@
3
3
  Thank you for your interest in contributing to Shakapacker! We welcome all contributions that align with our project goals and values. To ensure a smooth and productive collaboration, please follow these guidelines.
4
4
 
5
5
  ## Contents
6
+
6
7
  - [Reporting Issues](#reporting-issues)
7
8
  - [Submitting Pull Requests](#submitting-pull-requests)
8
9
  - [Setting Up a Development Environment](#setting-up-a-development-environment)
@@ -10,46 +11,121 @@ Thank you for your interest in contributing to Shakapacker! We welcome all contr
10
11
  - [Testing the generator](#testing-the-generator)
11
12
 
12
13
  ## Reporting Issues
14
+
13
15
  If you encounter any issues with the project, please first check the existing issues (including closed ones). If the issues is not reported before, please opening an issue on our GitHub repository. Please provide a clear and detailed description of the issue, including steps to reproduce it. Creating a demo repository to demonstrate the issue would be ideal (and in some cases necessary).
14
16
 
15
17
  If looking to contribute to the project by fixing existing issues, we recommend looking at issues, particularly with the "[help wanted](https://github.com/shakacode/shakapacker/issues?q=is%3Aissue+label%3A%22help+wanted%22)" label.
16
18
 
17
19
  ## Submitting Pull Requests
20
+
18
21
  We welcome pull requests that fix bugs, add new features, or improve existing ones. Before submitting a pull request, please make sure to:
19
22
 
20
- - Open an issue about what you want to propose before start working on.
21
- - Fork the repository and create a new branch for your changes.
22
- - Write clear and concise commit messages.
23
- - Follow our code style guidelines.
24
- - Write tests for your changes and [make sure all tests pass](#making-sure-your-changes-pass-all-tests).
25
- - Update the documentation as needed.
26
- - Update CHANGELOG.md if the changes affect public behavior of the project.
23
+ - Open an issue about what you want to propose before start working on.
24
+ - Fork the repository and create a new branch for your changes.
25
+ - Write clear and concise commit messages.
26
+ - Follow our code style guidelines.
27
+ - Write tests for your changes and [make sure all tests pass](#making-sure-your-changes-pass-all-tests).
28
+ - Update the documentation as needed.
29
+ - Update CHANGELOG.md if the changes affect public behavior of the project.
30
+
31
+ ---
32
+
33
+ ## Git Hooks (Optional)
34
+
35
+ This project includes configuration for git hooks via `husky` and `lint-staged`, but they are **opt-in for contributors**.
36
+
37
+ **Why are hooks optional?** As a library project, we don't enforce git hooks because:
38
+
39
+ - Different contributors may have different workflows
40
+ - Forcing hooks can interfere with contributor tooling
41
+ - CI/CD handles the final validation
42
+
43
+ To enable pre-commit hooks locally:
44
+
45
+ ```bash
46
+ npx husky install
47
+ npx husky add .husky/pre-commit "npx lint-staged"
48
+ ```
49
+
50
+ ---
51
+
52
+ ## Linting and Code Quality
53
+
54
+ ### Running Linters
55
+
56
+ ```bash
57
+ # Full linting with type checking (slower but thorough)
58
+ yarn lint
59
+
60
+ # Fast linting without type checking (for quick feedback)
61
+ yarn lint:fast
62
+
63
+ # With caching for better performance
64
+ yarn lint --cache
65
+ ```
66
+
67
+ **Performance Note:** TypeScript ESLint uses type-aware linting for better type safety, which can be slower on large codebases. Use `yarn lint:fast` during development for quick feedback.
27
68
 
28
69
  ---
70
+
29
71
  ## Setting Up a Development Environment
30
72
 
31
73
  1. Install [Yarn](https://classic.yarnpkg.com/)
32
74
  2. To test your changes on a Rails test project do the following steps:
75
+
33
76
  - For Ruby gem, update `Gemfile` and point the `shakapacker` to the locally developing Shakapacker project:
34
- ```ruby
35
- gem 'shakapacker', path: "relative_or_absolute_path_to_local_shakapacker"
36
- ```
77
+ ```ruby
78
+ gem 'shakapacker', path: "relative_or_absolute_path_to_local_shakapacker"
79
+ ```
37
80
  - For npm package, use `yalc` with following steps:
38
- ```bash
39
- # In Shakapacker root directory
40
- yalc publish
41
- # In Rails app for testing
42
- yalc link shakapacker
43
-
44
- # After every change in shakapacker, run the following in Shakapacker directory
45
- yalc push # or yalc publish --push
46
- ```
81
+
82
+ ```bash
83
+ # In Shakapacker root directory
84
+ yalc publish
85
+ # In Rails app for testing
86
+ yalc link shakapacker
87
+
88
+ # After every change in shakapacker, run the following in Shakapacker directory
89
+ yalc push # or yalc publish --push
90
+ ```
91
+
47
92
  3. Run the following commands to set up the development environment.
48
93
  ```
49
94
  bundle install
50
95
  yarn install
96
+ yarn prepare:husky # Set up pre-commit hooks for linting
51
97
  ```
52
98
 
99
+ ## Understanding Optional Peer Dependencies
100
+
101
+ Shakapacker uses optional peer dependencies (via `peerDependenciesMeta`) for maximum flexibility:
102
+
103
+ - **All peer dependencies are optional** - Users only install what they need
104
+ - **No installation warnings** - Package managers won't warn about missing optional dependencies
105
+ - **Version constraints still apply** - When a package is installed, version compatibility is enforced
106
+
107
+ ### When modifying dependencies:
108
+
109
+ 1. Add new peer dependencies to both `peerDependencies` and `peerDependenciesMeta` (marking as optional)
110
+ 2. Keep version ranges synchronized between `devDependencies` and `peerDependencies`
111
+ 3. Test with multiple package managers: `npm`, `yarn`, and `pnpm`
112
+
113
+ ### Testing peer dependency changes:
114
+
115
+ ```bash
116
+ # Test with npm (no warnings expected)
117
+ cd /tmp && mkdir test-npm && cd test-npm
118
+ npm init -y && npm install /path/to/shakapacker
119
+
120
+ # Test with yarn (no warnings expected)
121
+ cd /tmp && mkdir test-yarn && cd test-yarn
122
+ yarn init -y && yarn add /path/to/shakapacker
123
+
124
+ # Test with pnpm (no warnings expected)
125
+ cd /tmp && mkdir test-pnpm && cd test-pnpm
126
+ pnpm init && pnpm add /path/to/shakapacker
127
+ ```
128
+
53
129
  ## Making sure your changes pass all tests
54
130
 
55
131
  There are several specs, covering different aspects of Shakapacker gem. You may run them locally or rely on GitHub CI actions configured to test the gem functionality if different Ruby, Rails, and Node environment.
@@ -101,6 +177,7 @@ bundle exec rake run_spec:gem
101
177
  ```
102
178
 
103
179
  #### 4.4 Run only Shakapacker gem specs for backward compatibility
180
+
104
181
  These specs are to check Shakapacker v7 backward compatibility with v6.x
105
182
 
106
183
  ```
@@ -108,6 +185,7 @@ bundle exec rake run_spec:gem_bc
108
185
  ```
109
186
 
110
187
  #### 4.5 Run dummy app test
188
+
111
189
  For this, you need `yalc` to be installed on your local machine
112
190
 
113
191
  ```
@@ -115,6 +193,7 @@ bundle exec rake run_spec:dummy
115
193
  ```
116
194
 
117
195
  #### 4.6 Testing the installer
196
+
118
197
  To ensure that your installer works as expected, either you can run `bundle exec rake run_spec:install`, or take the following manual testing steps:
119
198
 
120
199
  1. Update the `Gemfile` so that gem `shakapacker` has a line like this, pointing to your developing Shakapacker:
@@ -124,4 +203,43 @@ To ensure that your installer works as expected, either you can run `bundle exec
124
203
  2. Run `bundle install` to install the updated gem.
125
204
  3. Run `bundle exec rails shakapacker:install` to confirm that you got the right changes.
126
205
 
127
- **Note:** Ensure that you use bundle exec otherwise the installed shakapacker gem will run and not the one you are working on.
206
+ **Note:** Ensure that you use bundle exec otherwise the installed shakapacker gem will run and not the one you are working on.
207
+
208
+ ## CI Workflows
209
+
210
+ Shakapacker uses GitHub Actions for continuous integration. The CI workflows use **Yarn** as the package manager for consistency and reliability.
211
+
212
+ ### Package Manager Choice
213
+
214
+ The project uses Yarn in CI workflows for the following reasons:
215
+
216
+ - Deterministic dependency resolution with `yarn.lock`
217
+ - Faster installation with offline mirror support
218
+ - Better workspace support for monorepo-style testing
219
+ - Consistent behavior across different Node.js versions
220
+
221
+ ### Key CI Workflow Files
222
+
223
+ - `.github/workflows/test-bundlers.yml` - Tests webpack, rspack, and bundler switching
224
+ - `.github/workflows/ruby.yml` - Ruby test suite across Ruby/Rails versions
225
+ - `.github/workflows/node.yml` - Node.js test suite across Node versions
226
+ - `.github/workflows/generator.yml` - Generator installation tests
227
+
228
+ All workflows use:
229
+
230
+ ```yaml
231
+ - uses: actions/setup-node@v4
232
+ with:
233
+ cache: "yarn"
234
+ cache-dependency-path: spec/dummy/yarn.lock
235
+ ```
236
+
237
+ And install dependencies with:
238
+
239
+ ```bash
240
+ yarn install
241
+ ```
242
+
243
+ ### Testing with Other Package Managers
244
+
245
+ While CI uses Yarn, the gem supports all major package managers (npm, yarn, pnpm, bun). Generator specs test against all package managers to ensure compatibility.
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- shakapacker (8.4.0)
4
+ shakapacker (9.0.0)
5
5
  activesupport (>= 5.2)
6
6
  package_json
7
7
  rack-proxy (>= 0.6.1)
@@ -217,7 +217,7 @@ GEM
217
217
  rubocop-ast (>= 1.31.1, < 2.0)
218
218
  ruby-progressbar (1.13.0)
219
219
  securerandom (0.3.1)
220
- semantic_range (3.0.0)
220
+ semantic_range (3.1.0)
221
221
  stringio (3.1.1)
222
222
  thor (1.3.2)
223
223
  timeout (0.4.1)
@@ -248,4 +248,4 @@ DEPENDENCIES
248
248
  shakapacker!
249
249
 
250
250
  BUNDLED WITH
251
- 2.5.18
251
+ 2.5.23
data/README.md CHANGED
@@ -1,8 +1,14 @@
1
- # Shakapacker (v8)
1
+ # Shakapacker (v9)
2
+ ---
3
+
4
+ _🚀 Shakapacker 9 supports [Rspack](https://rspack.rs/)! 10x faster than webpack!_
5
+
6
+ ---
2
7
 
3
8
  _Official, actively maintained successor to [rails/webpacker](https://github.com/rails/webpacker). ShakaCode stands behind the long-term maintenance and development of this project for the Rails community._
4
9
 
5
10
  * ⚠️ See the [6-stable](https://github.com/shakacode/shakapacker/tree/6-stable) branch for Shakapacker v6.x code and documentation. :warning:
11
+ * **See [V9 Upgrade](./docs/v9_upgrade.md) for upgrading from the v8 release.**
6
12
  * See [V8 Upgrade](./docs/v8_upgrade.md) for upgrading from the v7 release.
7
13
  * See [V7 Upgrade](./docs/v7_upgrade.md) for upgrading from the v6 release.
8
14
  * See [V6 Upgrade](./docs/v6_upgrade.md) for upgrading from v5 or prior v6 releases.
@@ -194,6 +200,83 @@ Note, in v6+, most JS packages are peer dependencies. Thus, the installer will a
194
200
  Previously, these "webpack" and "babel" packages were direct dependencies for `shakapacker`. By
195
201
  making these peer dependencies, you have control over the versions used in your webpack and babel configs.
196
202
 
203
+ ### Optional Peer Dependencies
204
+
205
+ All peer dependencies in Shakapacker are marked as optional via `peerDependenciesMeta`. This design decision ensures:
206
+ - **No warnings during package installation** when dependencies are not needed
207
+ - **Clear visibility of supported package versions** for upgrades
208
+ - **Flexibility to choose only the tools you need** (webpack vs rspack, babel vs swc vs esbuild)
209
+
210
+ The optional peer dependencies approach means you only install what you actually use, while still maintaining
211
+ version compatibility constraints when you do install those packages.
212
+
213
+ #### Required Dependencies by Configuration
214
+
215
+ Depending on your setup, you'll need different subsets of the optional peer dependencies:
216
+
217
+ **For Webpack + Babel (traditional setup):**
218
+ ```json
219
+ {
220
+ "dependencies": {
221
+ "shakapacker": "^9.0.0",
222
+ "@babel/core": "^7.17.9",
223
+ "@babel/plugin-transform-runtime": "^7.17.0",
224
+ "@babel/preset-env": "^7.16.11",
225
+ "@babel/runtime": "^7.17.9",
226
+ "babel-loader": "^8.2.4",
227
+ "compression-webpack-plugin": "^9.0.0",
228
+ "terser-webpack-plugin": "^5.3.1",
229
+ "webpack": "^5.76.0",
230
+ "webpack-assets-manifest": "^5.0.6",
231
+ "webpack-cli": "^5.0.0",
232
+ "webpack-dev-server": "^5.0.0"
233
+ }
234
+ }
235
+ ```
236
+
237
+ **For Webpack + SWC (faster alternative):**
238
+ ```json
239
+ {
240
+ "dependencies": {
241
+ "shakapacker": "^9.0.0",
242
+ "@swc/core": "^1.3.0",
243
+ "swc-loader": "^0.2.0",
244
+ "compression-webpack-plugin": "^9.0.0",
245
+ "terser-webpack-plugin": "^5.3.1",
246
+ "webpack": "^5.76.0",
247
+ "webpack-assets-manifest": "^5.0.6",
248
+ "webpack-cli": "^5.0.0",
249
+ "webpack-dev-server": "^5.0.0"
250
+ }
251
+ }
252
+ ```
253
+
254
+ **For Rspack + SWC (10x faster bundling):**
255
+ ```json
256
+ {
257
+ "dependencies": {
258
+ "shakapacker": "^9.0.0",
259
+ "@rspack/core": "^1.0.0",
260
+ "@rspack/cli": "^1.0.0",
261
+ "@swc/core": "^1.3.0",
262
+ "swc-loader": "^0.2.0",
263
+ "rspack-manifest-plugin": "^5.0.0"
264
+ }
265
+ }
266
+ ```
267
+
268
+ **For CSS/Sass processing (add to any config above):**
269
+ ```json
270
+ {
271
+ "dependencies": {
272
+ "css-loader": "^6.8.1",
273
+ "mini-css-extract-plugin": "^2.0.0",
274
+ "sass": "^1.50.0",
275
+ "sass-loader": "^13.0.0"
276
+ }
277
+ }
278
+ ```
279
+
197
280
  ## Concepts
198
281
 
199
282
  At its core, Shakapacker's essential function is to:
@@ -640,6 +723,10 @@ You can try out experimental integration with the esbuild-loader. You can read m
640
723
 
641
724
  Please note that if you want opt-in to use esbuild-loader, you can skip [React](#react) integration instructions as it is supported out of the box.
642
725
 
726
+ ### Switching between transpilers
727
+
728
+ To switch between Babel, SWC, or esbuild, or to configure environment-specific transpiler settings, see the [Transpiler Migration Guide](./docs/transpiler-migration.md).
729
+
643
730
  ### Integrations
644
731
 
645
732
  Shakapacker out of the box supports JS and static assets (fonts, images etc.) compilation. To enable support for CoffeeScript or TypeScript install relevant packages:
@@ -652,11 +739,13 @@ See also [Customizing Babel Config](./docs/customizing_babel_config.md) for an e
652
739
 
653
740
  #### TypeScript
654
741
 
742
+ **📚 TypeScript Support:** See the **[TypeScript Documentation](./docs/typescript.md)** for type-safe configuration.
743
+
655
744
  ```bash
656
745
  npm install typescript @babel/preset-typescript
657
746
  ```
658
747
 
659
- Babel wont perform any type-checking on TypeScript code. To optionally use type-checking run:
748
+ Babel won't perform any type-checking on TypeScript code. To optionally use type-checking run:
660
749
 
661
750
  ```bash
662
751
  npm install fork-ts-checker-webpack-plugin
@@ -926,6 +1015,30 @@ source_path: frontend # packs are the files in frontend/
926
1015
  public_output_path: assets/packs # outputs to => public/assets/packs
927
1016
  ```
928
1017
 
1018
+ For server-side rendering (SSR) scenarios where you need to generate bundles that should not be served publicly, you can use the `private_output_path` configuration:
1019
+
1020
+ ```yml
1021
+ # config/shakapacker.yml
1022
+ private_output_path: ssr-generated # outputs to => ssr-generated/
1023
+ ```
1024
+
1025
+ This is particularly useful when working with libraries like React on Rails where server bundles need to be kept separate from client bundles.
1026
+
1027
+ #### Migration Guide for React on Rails Users
1028
+
1029
+ If you're using React on Rails with separate client and server bundles, you can now leverage the `private_output_path` configuration instead of using custom webpack configurations:
1030
+
1031
+ 1. Update your `config/shakapacker.yml`:
1032
+ ```yml
1033
+ # Before: both client and server bundles in public/
1034
+ # After: separate directories
1035
+ public_output_path: packs # Client bundles (publicly served)
1036
+ private_output_path: ssr-bundles # Server bundles (not publicly served)
1037
+ ```
1038
+
1039
+ 2. Update your webpack configuration to use the appropriate output path based on the bundle type
1040
+ 3. The validation ensures `private_output_path` and `public_output_path` are different to prevent configuration errors
1041
+
929
1042
  Similarly, you can also control and configure `webpack-dev-server` settings from `config/shakapacker.yml` file:
930
1043
 
931
1044
  ```yml
@@ -993,7 +1106,19 @@ pnpm install --frozen-lockfile
993
1106
  bun install --frozen-lockfile
994
1107
  ```
995
1108
 
996
- If you are using a CDN setup, Shakapacker does NOT use the `ASSET_HOST` environment variable to prefix URLs for assets during bundle compilation. You must use the `SHAKAPACKER_ASSET_HOST` environment variable instead (`WEBPACKER_ASSET_HOST` if you're using any version of Webpacker or Shakapacker before Shakapacker v7).
1109
+ ### CDN
1110
+
1111
+ Shakapacker supports serving JavaScript bundles and assets from a CDN. The key configuration is setting the `SHAKAPACKER_ASSET_HOST` environment variable (NOT the Rails `ASSET_HOST` variable).
1112
+
1113
+ For detailed CDN setup instructions, including CloudFlare configuration, troubleshooting, and advanced setups, see the [CDN Setup Guide](./docs/cdn_setup.md).
1114
+
1115
+ **Quick example:**
1116
+ ```bash
1117
+ export SHAKAPACKER_ASSET_HOST=https://cdn.example.com
1118
+ RAILS_ENV=production bundle exec rails assets:precompile
1119
+ ```
1120
+
1121
+ For more deployment documentation, see [Deployment](./docs/deployment.md).
997
1122
 
998
1123
  ## Example Apps
999
1124
  * [React on Rails Tutorial With SSR, HMR fast refresh, and TypeScript](https://github.com/shakacode/react_on_rails_tutorial_with_ssr_and_hmr_fast_refresh)
@@ -1018,8 +1143,8 @@ The following companies support our Open Source projects, and ShakaCode uses the
1018
1143
  <br />
1019
1144
  <br />
1020
1145
 
1021
- <a href="https://www.jetbrains.com">
1022
- <img src="https://user-images.githubusercontent.com/4244251/184881139-42e4076b-024b-4b30-8c60-c3cd0e758c0a.png" alt="JetBrains" height="120px">
1146
+ <a href="https://jb.gg/OpenSource" style="margin-right: 20px;">
1147
+ <img src="https://resources.jetbrains.com/storage/products/company/brand/logos/jetbrains.png" alt="JetBrains" height="120px">
1023
1148
  </a>
1024
1149
  <a href="https://scoutapp.com">
1025
1150
  <picture>
data/Rakefile CHANGED
@@ -14,16 +14,51 @@ namespace :run_spec do
14
14
  sh("bundle exec rspec spec/shakapacker/*_spec.rb")
15
15
  end
16
16
 
17
- desc "Run specs in the dummy app"
17
+ desc "Run specs in the dummy app with webpack"
18
18
  task :dummy do
19
- puts "Running dummy app specs"
19
+ puts "Running dummy app specs with webpack"
20
20
  spec_dummy_dir = Pathname.new(File.join("spec", "dummy")).realpath
21
21
  Bundler.with_unbundled_env do
22
22
  sh_in_dir(".", "yalc publish")
23
23
  sh_in_dir(spec_dummy_dir, [
24
24
  "bundle install",
25
25
  "yalc link shakapacker",
26
- "yarn install",
26
+ "npm install",
27
+ "bin/test-bundler webpack",
28
+ "NODE_ENV=test RAILS_ENV=test bin/shakapacker",
29
+ "bundle exec rspec"
30
+ ])
31
+ end
32
+ end
33
+
34
+ desc "Run specs in the dummy app with rspack"
35
+ task :dummy_with_rspack do
36
+ puts "Running dummy app specs with rspack"
37
+ spec_dummy_dir = Pathname.new(File.join("spec", "dummy")).realpath
38
+ Bundler.with_unbundled_env do
39
+ sh_in_dir(".", "yalc publish")
40
+ sh_in_dir(spec_dummy_dir, [
41
+ "bundle install",
42
+ "yalc link shakapacker",
43
+ "npm install",
44
+ "bin/test-bundler rspack",
45
+ "NODE_ENV=test RAILS_ENV=test bin/shakapacker",
46
+ "bundle exec rspec"
47
+ ])
48
+ end
49
+ end
50
+
51
+ desc "Run specs in the dummy-rspack app"
52
+ task :dummy_rspack do
53
+ puts "Running dummy-rspack app specs"
54
+ spec_dummy_dir = Pathname.new(File.join("spec", "dummy-rspack")).realpath
55
+ Bundler.with_unbundled_env do
56
+ sh_in_dir(".", "yalc publish")
57
+ sh_in_dir(spec_dummy_dir, [
58
+ "bundle install",
59
+ "yalc link shakapacker",
60
+ "npm install",
61
+ "NODE_ENV=test RAILS_ENV=test npm exec --no -- rspack build --config config/rspack/rspack.config.js",
27
62
  "bundle exec rspec"
28
63
  ])
29
64
  end
@@ -35,7 +70,7 @@ namespace :run_spec do
35
70
  end
36
71
 
37
72
  desc "Run all specs"
38
- task all_specs: %i[gem dummy generator] do
73
+ task all_specs: %i[gem dummy dummy_with_rspack dummy_rspack generator] do
39
74
  puts "Completed all RSpec tests"
40
75
  end
41
76
  end
data/TODO.md ADDED
@@ -0,0 +1,50 @@
1
+ # TypeScript Migration Status
2
+
3
+ ## ✅ Completed (PR #602)
4
+ - Enhanced `package/index.d.ts` with comprehensive type definitions
5
+ - Added TypeScript type packages for better IDE support
6
+ - Improved Config and DevServerConfig interfaces
7
+ - Added missing properties (private_output_path, inline_css, env_prefix, etc.)
8
+ - All tests passing
9
+ - Zero JavaScript modifications (no whitespace changes)
10
+ - Full backward compatibility maintained
11
+
12
+ ## 📋 Next Steps (Issue #605)
13
+
14
+ ### Phase 2: Core Module Conversion
15
+ - [ ] Convert `package/config.js` to TypeScript
16
+ - [ ] Convert `package/env.js` to TypeScript
17
+ - [ ] Convert `package/index.js` to TypeScript
18
+ - [ ] Convert `package/utils/helpers.js` to TypeScript
19
+
20
+ ### Phase 3: Environment & Build System
21
+ - [ ] Convert environment files (base, development, production, test)
22
+ - [ ] Convert dev_server.js
23
+ - [ ] Convert webpackDevServerConfig.js
24
+
25
+ ### Phase 4: Rules & Loaders (PR #620) ✅
26
+ - [x] Convert all files in `package/rules/`
27
+ - [x] Convert all files in `package/plugins/`
28
+ - [x] Convert all files in `package/optimization/`
29
+
30
+ ### Phase 5: Framework-Specific Modules ✅
31
+ - [x] Convert rspack support files
32
+ - [x] Convert swc support files
33
+ - [x] Convert esbuild support files
34
+ - [x] Convert babel preset
35
+
36
+ ### Phase 6: Final Cleanup ✅
37
+ - [x] Add TypeScript linting with @typescript-eslint
38
+ - [x] Verify strict mode is enabled (already configured)
39
+ - [x] Update documentation
40
+
41
+ ## Why Gradual Migration?
42
+ - **Lower risk**: Each phase can be tested independently
43
+ - **Team learning**: Get familiar with TypeScript incrementally
44
+ - **Immediate value**: Type definitions already provide IDE benefits
45
+ - **No breaking changes**: Users unaffected during migration
46
+
47
+ ## Related Links
48
+ - Original issue: #200
49
+ - Initial PR: #602
50
+ - Next steps issue: #605
data/TODO_v9.md ADDED
@@ -0,0 +1,87 @@
1
+ # Shakapacker v9 TODO List
2
+
3
+ ## CSS Modules Configuration Alignment
4
+
5
+ ### Problem
6
+ Current CSS modules configuration causes TypeScript/webpack warnings because of default vs named export mismatch.
7
+
8
+ ### Current Behavior (v8)
9
+ - CSS modules use default export: `import styles from './styles.module.css'`
10
+ - This causes warnings but works at runtime
11
+ - Warning example: `export 'default' (imported as 'style') was not found in './HelloWorld.module.css'`
12
+
13
+ ### Proposed v9 Change
14
+ Align with Next.js and modern tooling by using named exports:
15
+
16
+ 1. **Update css-loader configuration:**
17
+ ```javascript
18
+ {
19
+ loader: 'css-loader',
20
+ options: {
21
+ modules: {
22
+ namedExport: true,
23
+ exportLocalsConvention: 'camelCaseOnly' // Must be 'camelCaseOnly' or 'dashesOnly' with namedExport: true
24
+ }
25
+ }
26
+ }
27
+ ```
28
+
29
+ **Note:** Using `exportLocalsConvention: 'camelCase'` with `namedExport: true` will cause a build error.
30
+ css-loader only allows `'camelCaseOnly'` or `'dashesOnly'` when named exports are enabled.
31
+
32
+ 2. **Update TypeScript types:**
33
+ - Ensure proper typing for CSS modules with named exports
34
+ - May need to update or generate `.d.ts` files for CSS modules
35
+
36
+ 3. **Migration guide for users:**
37
+ - Document the breaking change
38
+ - Provide codemod or migration script to update imports from:
39
+ ```javascript
40
+ import styles from './styles.module.css'
41
+ styles.className
42
+ ```
43
+ to:
44
+ ```javascript
45
+ import * as styles from './styles.module.css'
46
+ // or
47
+ import { className } from './styles.module.css'
48
+ ```
49
+
50
+ ### Benefits
51
+ - Eliminates webpack/TypeScript warnings
52
+ - Better tree-shaking potential
53
+ - More explicit about what CSS classes are being used
54
+ - Easier interoperability with frameworks that support named exports
55
+
56
+ ### Implementation Notes
57
+ - This is a BREAKING CHANGE and appropriate for major version bump
58
+ - Need to test with both webpack and rspack
59
+ - Consider providing a compatibility mode via configuration option
60
+
61
+ ---
62
+
63
+ ## Related Issues from PR #597
64
+
65
+ ### React Component Not Rendering (spec/dummy) - RESOLVED ✅
66
+ - **Issue**: React component was not rendering due to CSS module import mismatch
67
+ - **Symptoms**:
68
+ - Component wasn't rendering "Hello, Stranger!"
69
+ - Input field not rendered, making interactive test fail
70
+ - Only the static H1 "Hello, World!" was visible
71
+ - **Resolution**:
72
+ - Fixed CSS module import syntax from `import style from` to `import * as style from`
73
+ - This matched webpack's named exports configuration for CSS modules
74
+ - Tests now pass with both React 18.3.1 and webpack/rspack configurations
75
+ - **Root Cause**: CSS module import/export mismatch
76
+ - Webpack was configured to use named exports for CSS modules
77
+ - TypeScript code was using default import syntax
78
+ - This caused `style` to be undefined, breaking SSR and client rendering
79
+ - **Status**: FIXED
80
+ - All tests re-enabled and passing
81
+ - Both SSR and client-side rendering working
82
+ - Interactive functionality restored
83
+
84
+ ### Test Infrastructure
85
+ - Successfully implemented dual bundler support (webpack/rspack)
86
+ - test-bundler script working well with status command
87
+ - Consider adding more comprehensive tests for both bundlers