shakapacker 8.4.0 → 9.0.0.beta.2

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 (69) hide show
  1. checksums.yaml +4 -4
  2. data/.github/STATUS.md +1 -0
  3. data/.github/workflows/claude-code-review.yml +54 -0
  4. data/.github/workflows/claude.yml +50 -0
  5. data/.github/workflows/dummy.yml +1 -1
  6. data/.github/workflows/generator.yml +4 -14
  7. data/.github/workflows/node.yml +1 -1
  8. data/.rubocop.yml +1 -0
  9. data/CHANGELOG.md +8 -2
  10. data/Gemfile.lock +3 -3
  11. data/README.md +2 -2
  12. data/Rakefile +18 -1
  13. data/docs/css-modules-export-mode.md +288 -0
  14. data/docs/peer-dependencies.md +40 -0
  15. data/docs/rspack.md +190 -0
  16. data/docs/rspack_migration_guide.md +202 -0
  17. data/docs/troubleshooting.md +5 -0
  18. data/docs/using_esbuild_loader.md +3 -3
  19. data/docs/using_swc_loader.md +5 -3
  20. data/lib/install/bin/shakapacker +3 -5
  21. data/lib/install/config/rspack/rspack.config.js +6 -0
  22. data/lib/install/config/shakapacker.yml +6 -2
  23. data/lib/install/package.json +30 -0
  24. data/lib/install/template.rb +12 -2
  25. data/lib/shakapacker/configuration.rb +45 -0
  26. data/lib/shakapacker/dev_server_runner.rb +25 -5
  27. data/lib/shakapacker/manifest.rb +4 -2
  28. data/lib/shakapacker/rspack_runner.rb +19 -0
  29. data/lib/shakapacker/runner.rb +144 -4
  30. data/lib/shakapacker/utils/manager.rb +2 -0
  31. data/lib/shakapacker/version.rb +1 -1
  32. data/lib/shakapacker/version_checker.rb +1 -1
  33. data/lib/shakapacker/webpack_runner.rb +4 -42
  34. data/lib/tasks/shakapacker/install.rake +6 -2
  35. data/package/config.js +24 -0
  36. data/package/environments/base.js +20 -65
  37. data/package/environments/development.js +60 -5
  38. data/package/environments/production.js +29 -51
  39. data/package/environments/test.js +17 -1
  40. data/package/index.d.ts +62 -20
  41. data/package/index.js +4 -2
  42. data/package/optimization/rspack.js +29 -0
  43. data/package/optimization/webpack.js +49 -0
  44. data/package/plugins/rspack.js +88 -0
  45. data/package/plugins/webpack.js +62 -0
  46. data/package/rspack/index.js +57 -0
  47. data/package/rules/babel.js +2 -2
  48. data/package/rules/css.js +1 -1
  49. data/package/rules/esbuild.js +2 -2
  50. data/package/rules/file.js +11 -5
  51. data/package/rules/less.js +1 -1
  52. data/package/rules/raw.js +12 -2
  53. data/package/rules/rspack.js +162 -0
  54. data/package/rules/sass.js +6 -2
  55. data/package/rules/stylus.js +1 -1
  56. data/package/rules/swc.js +2 -2
  57. data/package/utils/debug.js +49 -0
  58. data/package/utils/getStyleRule.js +16 -3
  59. data/package/utils/requireOrError.js +15 -0
  60. data/package/utils/validateDependencies.js +61 -0
  61. data/package/webpackDevServerConfig.js +2 -0
  62. data/package.json +19 -31
  63. data/test/package/environments/base.test.js +1 -1
  64. data/test/package/rules/esbuild.test.js +1 -1
  65. data/test/package/rules/swc.test.js +1 -1
  66. data/test/package/rules/{index.test.js → webpack.test.js} +1 -1
  67. data/yarn.lock +2136 -726
  68. metadata +26 -11
  69. /data/package/rules/{index.js → webpack.js} +0 -0
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6ccbba3c39a550ae683e13c45e3ac4f79733ae6ffebabf2d6ab55f37b7427d99
4
- data.tar.gz: 569998bb9475e8ed2b8ba786d1ccdf2b84d562d61ba8ef78d08ad195c3ea2230
3
+ metadata.gz: 02da73fe458c789d3774f993cdc5d4ec082aec418d746bd96d279a6e636fb9dc
4
+ data.tar.gz: b0342e33b80c52751b7a63102492d9dbd3bcc88c485bd1b831ab902263d45404
5
5
  SHA512:
6
- metadata.gz: 2c529d5f970394ca40b79d7ac1ddb430c197cbd508bf533195f13d81937cca872232436bcb92c5a8f38eafc9968ef0d1a82c280120545e421d143dcf72d12f0c
7
- data.tar.gz: b341f56e92124b2418b56483dab20374aee03fca5de1e946e5b09ce1f2ca7d0daa16c47ed365a90f51a8f5bdf55235dbe9107cf95dc0a3b9b00e19056f72f343
6
+ metadata.gz: 9950e533356e907aa0e68202dfe40af8ed5d96f633ba4a0aeff28ddf214daaf1b9cd02bbb7b74ba0fa8d4bcea00c2c7b1cd6fdd7d14a8e0d333932c3ece79a7a
7
+ data.tar.gz: aeb7b646e6d07e7ed7dd056113b98521701161c7d2909ec18a4d0771b473e970d7006ccfec4b7a4da1e789da56be0d6ecb8d95db651d0fae8c7ef7cf70be951f
data/.github/STATUS.md ADDED
@@ -0,0 +1 @@
1
+ # CI Status Update
@@ -0,0 +1,54 @@
1
+ name: Claude Code Review
2
+
3
+ on:
4
+ pull_request:
5
+ types: [opened, synchronize]
6
+ # Optional: Only run on specific file changes
7
+ # paths:
8
+ # - "src/**/*.ts"
9
+ # - "src/**/*.tsx"
10
+ # - "src/**/*.js"
11
+ # - "src/**/*.jsx"
12
+
13
+ jobs:
14
+ claude-review:
15
+ # Optional: Filter by PR author
16
+ # if: |
17
+ # github.event.pull_request.user.login == 'external-contributor' ||
18
+ # github.event.pull_request.user.login == 'new-developer' ||
19
+ # github.event.pull_request.author_association == 'FIRST_TIME_CONTRIBUTOR'
20
+
21
+ runs-on: ubuntu-latest
22
+ permissions:
23
+ contents: read
24
+ pull-requests: read
25
+ issues: read
26
+ id-token: write
27
+
28
+ steps:
29
+ - name: Checkout repository
30
+ uses: actions/checkout@v4
31
+ with:
32
+ fetch-depth: 1
33
+
34
+ - name: Run Claude Code Review
35
+ id: claude-review
36
+ uses: anthropics/claude-code-action@v1
37
+ with:
38
+ claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
39
+ prompt: |
40
+ Please review this pull request and provide feedback on:
41
+ - Code quality and best practices
42
+ - Potential bugs or issues
43
+ - Performance considerations
44
+ - Security concerns
45
+ - Test coverage
46
+
47
+ Use the repository's CLAUDE.md for guidance on style and conventions. Be constructive and helpful in your feedback.
48
+
49
+ Use `gh pr comment` with your Bash tool to leave your review as a comment on the PR.
50
+
51
+ # See https://github.com/anthropics/claude-code-action/blob/main/docs/usage.md
52
+ # or https://docs.claude.com/en/docs/claude-code/sdk#command-line for available options
53
+ claude_args: '--allowed-tools "Bash(gh issue view:*),Bash(gh search:*),Bash(gh issue list:*),Bash(gh pr comment:*),Bash(gh pr diff:*),Bash(gh pr view:*),Bash(gh pr list:*)"'
54
+
@@ -0,0 +1,50 @@
1
+ name: Claude Code
2
+
3
+ on:
4
+ issue_comment:
5
+ types: [created]
6
+ pull_request_review_comment:
7
+ types: [created]
8
+ issues:
9
+ types: [opened, assigned]
10
+ pull_request_review:
11
+ types: [submitted]
12
+
13
+ jobs:
14
+ claude:
15
+ if: |
16
+ (github.event_name == 'issue_comment' && contains(github.event.comment.body, '@claude')) ||
17
+ (github.event_name == 'pull_request_review_comment' && contains(github.event.comment.body, '@claude')) ||
18
+ (github.event_name == 'pull_request_review' && contains(github.event.review.body, '@claude')) ||
19
+ (github.event_name == 'issues' && (contains(github.event.issue.body, '@claude') || contains(github.event.issue.title, '@claude')))
20
+ runs-on: ubuntu-latest
21
+ permissions:
22
+ contents: read
23
+ pull-requests: read
24
+ issues: read
25
+ id-token: write
26
+ actions: read # Required for Claude to read CI results on PRs
27
+ steps:
28
+ - name: Checkout repository
29
+ uses: actions/checkout@v4
30
+ with:
31
+ fetch-depth: 1
32
+
33
+ - name: Run Claude Code
34
+ id: claude
35
+ uses: anthropics/claude-code-action@v1
36
+ with:
37
+ claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
38
+
39
+ # This is an optional setting that allows Claude to read CI results on PRs
40
+ additional_permissions: |
41
+ actions: read
42
+
43
+ # Optional: Give a custom prompt to Claude. If this is not specified, Claude will perform the instructions specified in the comment that tagged it.
44
+ # prompt: 'Update the pull request description to include a summary of changes.'
45
+
46
+ # Optional: Add claude_args to customize behavior and configuration
47
+ # See https://github.com/anthropics/claude-code-action/blob/main/docs/usage.md
48
+ # or https://docs.claude.com/en/docs/claude-code/sdk#command-line for available options
49
+ # claude_args: '--model claude-opus-4-1-20250805 --allowed-tools Bash(gh pr:*)'
50
+
@@ -21,7 +21,7 @@ jobs:
21
21
  persist-credentials: false
22
22
  - uses: actions/setup-node@v4
23
23
  with:
24
- node-version: '16'
24
+ node-version: '20'
25
25
  - uses: ruby/setup-ruby@v1
26
26
  with:
27
27
  ruby-version: '3.1.2'
@@ -20,8 +20,6 @@ jobs:
20
20
  os: [ubuntu-latest]
21
21
  ruby: ['2.7', '3.0', '3.1', '3.2', '3.3', '3.4']
22
22
  gemfile:
23
- - gemfiles/Gemfile-rails.6.0.x
24
- - gemfiles/Gemfile-rails.6.1.x
25
23
  - gemfiles/Gemfile-rails.7.0.x
26
24
  - gemfiles/Gemfile-rails.7.1.x
27
25
  - gemfiles/Gemfile-rails.7.2.x
@@ -38,20 +36,8 @@ jobs:
38
36
  gemfile: gemfiles/Gemfile-rails.7.2.x
39
37
  - ruby: '3.0'
40
38
  gemfile: gemfiles/Gemfile-rails.8.0.x
41
- - ruby: '3.1'
42
- gemfile: gemfiles/Gemfile-rails.6.0.x
43
39
  - ruby: '3.1'
44
40
  gemfile: gemfiles/Gemfile-rails.8.0.x
45
- - ruby: '3.2'
46
- gemfile: gemfiles/Gemfile-rails.6.0.x
47
- - ruby: '3.3'
48
- gemfile: gemfiles/Gemfile-rails.6.0.x
49
- - ruby: '3.3'
50
- gemfile: gemfiles/Gemfile-rails.6.1.x
51
- - ruby: '3.4'
52
- gemfile: gemfiles/Gemfile-rails.6.0.x
53
- - ruby: '3.4'
54
- gemfile: gemfiles/Gemfile-rails.6.1.x
55
41
  - ruby: '3.4'
56
42
  gemfile: gemfiles/Gemfile-rails.7.0.x
57
43
 
@@ -67,4 +53,8 @@ jobs:
67
53
  ruby-version: ${{ matrix.ruby }}
68
54
  rubygems: latest
69
55
  bundler-cache: true
56
+ - uses: actions/setup-node@v4
57
+ with:
58
+ node-version: 20.x
59
+ cache: yarn
70
60
  - run: bundle exec rake run_spec:generator
@@ -35,7 +35,7 @@ jobs:
35
35
  strategy:
36
36
  matrix:
37
37
  os: [ubuntu-latest]
38
- node: [14.x, 16.x, 18.x, 20.x]
38
+ node: [18.x, 20.x, 22.x]
39
39
 
40
40
  runs-on: ${{ matrix.os }}
41
41
 
data/.rubocop.yml CHANGED
@@ -9,6 +9,7 @@ AllCops:
9
9
  - "vendor/**/*"
10
10
  - "node_modules/**/*"
11
11
  - "_actions/**/*"
12
+ - "spec/dummy-rspack/**/*"
12
13
 
13
14
  # Prefer &&/|| over and/or.
14
15
  Style/AndOr:
data/CHANGELOG.md CHANGED
@@ -8,11 +8,17 @@
8
8
  ## [Unreleased]
9
9
  Changes since the last non-beta release.
10
10
 
11
- ## [v8.4.0] - September 8, 2025
11
+ ### Added
12
+ - Rspack support as an alternative assets bundler to webpack. Configure `assets_bundler: 'rspack'` in `shakapacker.yml` to use Rspack's faster Rust-based bundling with webpack-compatible APIs, built-in SWC loader, and CSS extraction. Automatic assets bundler detection in `bin/shakapacker` with fallback support for webpack configurations.
12
13
 
14
+ ### Changed
15
+ - Configuration option renamed from `bundler` to `assets_bundler` to avoid confusion with Ruby's Bundler gem manager. The old `bundler` option is deprecated but still supported with a warning (not a breaking change).
16
+ - BREAKING CHANGE: Configuration option renamed from `webpack_loader` to `javascript_transpiler` to better reflect its purpose of configuring JavaScript transpilation regardless of the bundler used. The old `webpack_loader` option is deprecated but still supported with a warning.
17
+
18
+ ## [v8.4.0] - September 8, 2025
13
19
  ### Added
14
20
 
15
- - Support for subresource integrity. [PR 570](https://github.com/shakacode/shakapacker/pull/570) by [panagiotisplytas](https://github.com/panagiotisplytas)
21
+ * Support for subresource integrity. [PR 570](https://github.com/shakacode/shakapacker/pull/570) by [panagiotisplytas](https://github.com/panagiotisplytas)
16
22
 
17
23
  ### Fixed
18
24
 
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.beta.2)
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
@@ -1018,8 +1018,8 @@ The following companies support our Open Source projects, and ShakaCode uses the
1018
1018
  <br />
1019
1019
  <br />
1020
1020
 
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">
1021
+ <a href="https://jb.gg/OpenSource" style="margin-right: 20px;">
1022
+ <img src="https://resources.jetbrains.com/storage/products/company/brand/logos/jetbrains.png" alt="JetBrains" height="120px">
1023
1023
  </a>
1024
1024
  <a href="https://scoutapp.com">
1025
1025
  <picture>
data/Rakefile CHANGED
@@ -24,6 +24,23 @@ namespace :run_spec do
24
24
  "bundle install",
25
25
  "yalc link shakapacker",
26
26
  "yarn install",
27
+ "NODE_ENV=test RAILS_ENV=test yarn run webpack --config config/webpack/webpack.config.js",
28
+ "bundle exec rspec"
29
+ ])
30
+ end
31
+ end
32
+
33
+ desc "Run specs in the dummy-rspack app"
34
+ task :dummy_rspack do
35
+ puts "Running dummy-rspack app specs"
36
+ spec_dummy_dir = Pathname.new(File.join("spec", "dummy-rspack")).realpath
37
+ Bundler.with_unbundled_env do
38
+ sh_in_dir(".", "yalc publish")
39
+ sh_in_dir(spec_dummy_dir, [
40
+ "bundle install",
41
+ "yalc link shakapacker",
42
+ "yarn install",
43
+ "NODE_ENV=test RAILS_ENV=test yarn run rspack build --config config/webpack/webpack.config.js",
27
44
  "bundle exec rspec"
28
45
  ])
29
46
  end
@@ -35,7 +52,7 @@ namespace :run_spec do
35
52
  end
36
53
 
37
54
  desc "Run all specs"
38
- task all_specs: %i[gem dummy generator] do
55
+ task all_specs: %i[gem dummy dummy_rspack generator] do
39
56
  puts "Completed all RSpec tests"
40
57
  end
41
58
  end
@@ -0,0 +1,288 @@
1
+ # CSS Modules Export Mode
2
+
3
+ Most React guides and tutorials expect to import CSS Modules using a **default export object**:
4
+
5
+ ```js
6
+ import styles from './Foo.module.css';
7
+ <button className={styles.bright} />
8
+ ```
9
+
10
+ However, depending on configuration, `css-loader` may instead emit **named exports**:
11
+
12
+ ```js
13
+ import { bright } from './Foo.module.css';
14
+ <button className={bright} />
15
+ ```
16
+
17
+ By default, Shakapacker currently leaves `css-loader`'s `modules.namedExport` option unset, which leads to **named exports** being used in many cases. This can surprise developers expecting the `import styles ...` pattern.
18
+
19
+ ---
20
+
21
+ ## How to Configure Shakapacker for Default Exports
22
+
23
+ To force the more familiar `import styles ...` behavior (i.e. `namedExport: false`), update your webpack configuration as follows.
24
+
25
+ ### Option 1: Update `config/webpack/commonWebpackConfig.js` (Recommended)
26
+
27
+ This approach modifies the common webpack configuration that applies to all environments:
28
+
29
+ ```js
30
+ // config/webpack/commonWebpackConfig.js
31
+ const { generateWebpackConfig, merge } = require('shakapacker');
32
+
33
+ const baseClientWebpackConfig = generateWebpackConfig();
34
+
35
+ // Override CSS Modules configuration to use default exports instead of named exports
36
+ const overrideCssModulesConfig = (config) => {
37
+ // Find the CSS rule in the module rules
38
+ const cssRule = config.module.rules.find(rule =>
39
+ rule.test && rule.test.toString().includes('css')
40
+ );
41
+
42
+ if (cssRule && cssRule.use) {
43
+ const cssLoaderUse = cssRule.use.find(use =>
44
+ use.loader && use.loader.includes('css-loader')
45
+ );
46
+
47
+ if (cssLoaderUse && cssLoaderUse.options && cssLoaderUse.options.modules) {
48
+ // Set namedExport to false for default export behavior
49
+ cssLoaderUse.options.modules.namedExport = false;
50
+ cssLoaderUse.options.modules.exportLocalsConvention = 'asIs';
51
+ }
52
+ }
53
+
54
+ return config;
55
+ };
56
+
57
+ const commonOptions = {
58
+ resolve: {
59
+ extensions: ['.css', '.ts', '.tsx'],
60
+ },
61
+ };
62
+
63
+ const commonWebpackConfig = () => {
64
+ const config = merge({}, baseClientWebpackConfig, commonOptions);
65
+ return overrideCssModulesConfig(config);
66
+ };
67
+
68
+ module.exports = commonWebpackConfig;
69
+ ```
70
+
71
+ ### Option 2: Create `config/webpack/environment.js` (Alternative)
72
+
73
+ If you prefer using a separate environment file:
74
+
75
+ ```js
76
+ // config/webpack/environment.js
77
+ const { environment } = require('@shakacode/shakapacker');
78
+ const getStyleRule = require('@shakacode/shakapacker/package/utils/getStyleRule');
79
+
80
+ // CSS Modules rule for *.module.css with default export enabled
81
+ const cssModulesRule = getStyleRule(/\.module\.css$/i, [], {
82
+ sourceMap: true,
83
+ importLoaders: 2,
84
+ modules: {
85
+ auto: true,
86
+ namedExport: false, // <-- key: enable default export object
87
+ exportLocalsConvention: 'asIs' // keep your class names as-is
88
+ }
89
+ });
90
+
91
+ // Ensure this rule wins for *.module.css
92
+ if (cssModulesRule) {
93
+ environment.loaders.prepend('css-modules', cssModulesRule);
94
+ }
95
+
96
+ // Plain CSS rule for non-modules
97
+ const plainCssRule = getStyleRule(/(?<!\.module)\.css$/i, [], {
98
+ sourceMap: true,
99
+ importLoaders: 2,
100
+ modules: false
101
+ });
102
+
103
+ if (plainCssRule) {
104
+ environment.loaders.append('css', plainCssRule);
105
+ }
106
+
107
+ module.exports = environment;
108
+ ```
109
+
110
+ Then reference this in your environment-specific configs (development.js, production.js, etc.).
111
+
112
+ ### Option 3: (Optional) Sass Modules
113
+
114
+ If you also use Sass modules, add similar configuration for SCSS files:
115
+
116
+ ```js
117
+ // For Option 1 approach, extend the overrideCssModulesConfig function:
118
+ const overrideCssModulesConfig = (config) => {
119
+ // Handle both CSS and SCSS rules
120
+ const styleRules = config.module.rules.filter(rule =>
121
+ rule.test && (rule.test.toString().includes('css') || rule.test.toString().includes('scss'))
122
+ );
123
+
124
+ styleRules.forEach(rule => {
125
+ if (rule.use) {
126
+ const cssLoaderUse = rule.use.find(use =>
127
+ use.loader && use.loader.includes('css-loader')
128
+ );
129
+
130
+ if (cssLoaderUse && cssLoaderUse.options && cssLoaderUse.options.modules) {
131
+ cssLoaderUse.options.modules.namedExport = false;
132
+ cssLoaderUse.options.modules.exportLocalsConvention = 'asIs';
133
+ }
134
+ }
135
+ });
136
+
137
+ return config;
138
+ };
139
+ ```
140
+
141
+ ---
142
+
143
+ ## Verifying the Configuration
144
+
145
+ ### 1. Rebuild Your Packs
146
+
147
+ After making the configuration changes, rebuild your webpack bundles:
148
+
149
+ ```bash
150
+ # For development
151
+ NODE_ENV=development bin/shakapacker
152
+
153
+ # Or with the dev server
154
+ bin/shakapacker-dev-server
155
+ ```
156
+
157
+ ### 2. Test in Your React Component
158
+
159
+ Update your component to use default imports:
160
+
161
+ ```js
162
+ // Before (named exports)
163
+ import { bright } from './Foo.module.css';
164
+
165
+ // After (default export)
166
+ import styles from './Foo.module.css';
167
+ console.log(styles); // { bright: 'Foo_bright__hash' }
168
+ ```
169
+
170
+ ### 3. Debug Webpack Configuration (Optional)
171
+
172
+ To inspect the final webpack configuration:
173
+
174
+ ```bash
175
+ NODE_ENV=development bin/shakapacker --profile --json > /tmp/webpack-stats.json
176
+ ```
177
+
178
+ Then search for `css-loader` options in the generated JSON file.
179
+
180
+ ---
181
+
182
+ ## Benefits of Default Export Approach
183
+
184
+ 1. **Better Developer Experience**: Matches most React tutorials and documentation
185
+ 2. **IDE Support**: Better autocomplete and IntelliSense for CSS class names
186
+ 3. **Type Safety**: Easier to add TypeScript definitions for CSS modules
187
+ 4. **Consistency**: Aligns with common React ecosystem practices
188
+
189
+ ---
190
+
191
+ ## Migration Guide
192
+
193
+ If you're migrating from named exports to default exports:
194
+
195
+ ### 1. Update Import Statements
196
+
197
+ ```js
198
+ // Old (named exports)
199
+ import { bright, container, button } from './Component.module.css';
200
+
201
+ // New (default export)
202
+ import styles from './Component.module.css';
203
+ ```
204
+
205
+ ### 2. Update Class References
206
+
207
+ ```js
208
+ // Old
209
+ <div className={container}>
210
+ <button className={button}>Click me</button>
211
+ <span className={bright}>Highlighted text</span>
212
+ </div>
213
+
214
+ // New
215
+ <div className={styles.container}>
216
+ <button className={styles.button}>Click me</button>
217
+ <span className={styles.bright}>Highlighted text</span>
218
+ </div>
219
+ ```
220
+
221
+ ### 3. Consider Using a Codemod
222
+
223
+ For large codebases, consider writing a codemod to automate the migration:
224
+
225
+ ```bash
226
+ # Example using jscodeshift (pseudocode)
227
+ npx jscodeshift -t css-modules-migration.js src/
228
+ ```
229
+
230
+ ---
231
+
232
+ ## Future Shakapacker Configuration
233
+
234
+ In future versions of Shakapacker, this configuration may be exposed via `config/shakapacker.yml`:
235
+
236
+ ```yml
237
+ # Future configuration (not yet implemented)
238
+ css_modules:
239
+ # true -> named exports (import { bright } ...)
240
+ # false -> default export (import styles ...)
241
+ named_export: false
242
+ ```
243
+
244
+ - **Current behavior:** Uses named exports when unset
245
+ - **Future behavior:** New app templates will default to `false`
246
+ - **Next major release:** The default will change to `false` when unset
247
+
248
+ ---
249
+
250
+ ## Troubleshooting
251
+
252
+ ### CSS Classes Not Applying
253
+
254
+ If your CSS classes aren't applying after the change:
255
+
256
+ 1. **Check import syntax**: Ensure you're using `import styles from ...`
257
+ 2. **Verify class names**: Use `console.log(styles)` to see available classes
258
+ 3. **Rebuild webpack**: Clear cache and rebuild: `rm -rf tmp/cache && bin/shakapacker`
259
+
260
+ ### TypeScript Support
261
+
262
+ For TypeScript projects, create type definitions for your CSS modules:
263
+
264
+ ```typescript
265
+ // src/types/css-modules.d.ts
266
+ declare module '*.module.css' {
267
+ const classes: { [key: string]: string };
268
+ export default classes;
269
+ }
270
+ ```
271
+
272
+ ### Build Performance
273
+
274
+ The configuration changes should not impact build performance significantly. If you experience issues:
275
+
276
+ 1. Check webpack stats: `bin/shakapacker --profile`
277
+ 2. Verify only necessary rules are being modified
278
+ 3. Consider using webpack bundle analyzer for deeper insights
279
+
280
+ ---
281
+
282
+ ## Summary
283
+
284
+ - **Current default**: Named exports (`import { bright } ...`)
285
+ - **Recommended for DX**: Default export (`import styles ...`)
286
+ - **Implementation**: Override CSS loader configuration in `commonWebpackConfig.js`
287
+ - **Migration**: Update imports and class references systematically
288
+ - **Future**: Shakapacker will provide native configuration options
@@ -0,0 +1,40 @@
1
+ # Shakapacker's Peer Dependencies
2
+ #### last updated for our 8.4.0 version
3
+ #### see lib/install/peerDependencies.json
4
+
5
+ To simplify peer dependencies while supporting both webpack & rspack, we decided to document the dependencies here instead of creating two separate npm packages.
6
+
7
+ ## Essential for Rspack
8
+ ```
9
+ "@rspack/cli": "^1.0.0",
10
+ "@rspack/core": "^1.0.0",
11
+ "rspack-manifest-plugin": "^5.0.0",
12
+ ```
13
+ ## Essential for Webpack
14
+ ```
15
+ "mini-css-extract-plugin": "^2.0.0",
16
+ "terser-webpack-plugin": "^5.3.1",
17
+ "webpack": "^5.76.0",
18
+ "webpack-assets-manifest": "^5.0.6 || ^6.0.0",
19
+ "webpack-cli": "^4.9.2 || ^5.0.0 || ^6.0.0",
20
+ "webpack-dev-server": "^4.15.2 || ^5.2.2",
21
+ "webpack-merge": "^5.8.0 || ^6.0.0",
22
+ "webpack-subresource-integrity": "^5.1.0"
23
+ ```
24
+
25
+ ## Highly recommended
26
+ ```
27
+ "compression-webpack-plugin": "^9.0.0 || ^10.0.0|| ^11.0.0",
28
+ "css-loader": "^6.0.0 || ^7.0.0",
29
+ "sass-loader": "^13.0.0 || ^14.0.0 || ^15.0.0 || ^16.0.0",
30
+ "style-loader": "^3.0.0 || ^4.0.0",
31
+ ```
32
+
33
+ ## Babel (avoid if at all possible)
34
+ ```
35
+ "@babel/core": "^7.17.9",
36
+ "@babel/plugin-transform-runtime": "^7.17.0",
37
+ "@babel/preset-env": "^7.16.11",
38
+ "@babel/runtime": "^7.17.9",
39
+ "babel-loader": "^8.2.4 || ^9.0.0 || ^10.0.0",
40
+ ```