shakapacker 9.3.0.beta.7 → 9.3.1

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 (85) hide show
  1. checksums.yaml +4 -4
  2. data/.claude/commands/update-changelog.md +224 -0
  3. data/.github/actionlint-matcher.json +17 -0
  4. data/.github/workflows/dummy.yml +9 -0
  5. data/.github/workflows/generator.yml +13 -0
  6. data/.github/workflows/node.yml +83 -0
  7. data/.github/workflows/ruby.yml +11 -0
  8. data/.github/workflows/test-bundlers.yml +10 -0
  9. data/CHANGELOG.md +55 -111
  10. data/CLAUDE.md +6 -10
  11. data/CONTRIBUTING.md +57 -0
  12. data/Gemfile.lock +1 -1
  13. data/README.md +84 -8
  14. data/docs/api-reference.md +519 -0
  15. data/docs/configuration.md +38 -4
  16. data/docs/css-modules-export-mode.md +40 -6
  17. data/docs/rspack_migration_guide.md +238 -2
  18. data/docs/transpiler-migration.md +12 -9
  19. data/docs/troubleshooting.md +21 -21
  20. data/docs/using_swc_loader.md +13 -10
  21. data/docs/v9_upgrade.md +11 -2
  22. data/eslint.config.fast.js +128 -8
  23. data/eslint.config.js +89 -33
  24. data/knip.ts +8 -1
  25. data/lib/install/config/shakapacker.yml +20 -7
  26. data/lib/shakapacker/configuration.rb +274 -8
  27. data/lib/shakapacker/dev_server.rb +88 -1
  28. data/lib/shakapacker/dev_server_runner.rb +4 -0
  29. data/lib/shakapacker/doctor.rb +5 -5
  30. data/lib/shakapacker/instance.rb +85 -1
  31. data/lib/shakapacker/manifest.rb +85 -11
  32. data/lib/shakapacker/version.rb +1 -1
  33. data/lib/shakapacker.rb +143 -3
  34. data/lib/tasks/shakapacker/doctor.rake +1 -1
  35. data/lib/tasks/shakapacker/export_bundler_config.rake +4 -4
  36. data/package/config.ts +2 -4
  37. data/package/configExporter/buildValidator.ts +53 -29
  38. data/package/configExporter/cli.ts +106 -76
  39. data/package/configExporter/configFile.ts +33 -26
  40. data/package/configExporter/types.ts +64 -0
  41. data/package/configExporter/yamlSerializer.ts +118 -43
  42. data/package/dev_server.ts +3 -2
  43. data/package/env.ts +2 -2
  44. data/package/environments/__type-tests__/rspack-plugin-compatibility.ts +6 -6
  45. data/package/environments/base.ts +6 -6
  46. data/package/environments/development.ts +7 -9
  47. data/package/environments/production.ts +7 -8
  48. data/package/environments/test.ts +4 -2
  49. data/package/esbuild/index.ts +0 -2
  50. data/package/index.d.ts +1 -0
  51. data/package/index.d.ts.template +1 -0
  52. data/package/index.ts +28 -5
  53. data/package/loaders.d.ts +2 -2
  54. data/package/optimization/webpack.ts +29 -31
  55. data/package/plugins/rspack.ts +3 -1
  56. data/package/plugins/webpack.ts +5 -3
  57. data/package/rspack/index.ts +5 -4
  58. data/package/rules/file.ts +2 -1
  59. data/package/rules/jscommon.ts +1 -0
  60. data/package/rules/raw.ts +3 -1
  61. data/package/rules/rspack.ts +0 -2
  62. data/package/rules/sass.ts +0 -2
  63. data/package/rules/webpack.ts +0 -1
  64. data/package/swc/index.ts +0 -2
  65. data/package/types.ts +8 -11
  66. data/package/utils/debug.ts +0 -4
  67. data/package/utils/getStyleRule.ts +17 -9
  68. data/package/utils/helpers.ts +8 -4
  69. data/package/utils/pathValidation.ts +78 -18
  70. data/package/utils/requireOrError.ts +14 -5
  71. data/package/utils/typeGuards.ts +43 -46
  72. data/package/webpack-types.d.ts +2 -2
  73. data/package/webpackDevServerConfig.ts +5 -4
  74. data/package.json +2 -3
  75. data/test/package/configExporter/cli.test.js +440 -0
  76. data/test/package/configExporter/types.test.js +163 -0
  77. data/test/package/configExporter.test.js +264 -0
  78. data/test/package/transpiler-defaults.test.js +42 -0
  79. data/test/package/yamlSerializer.test.js +204 -0
  80. data/test/typescript/pathValidation.test.js +44 -0
  81. data/test/typescript/requireOrError.test.js +49 -0
  82. data/yarn.lock +0 -32
  83. metadata +14 -5
  84. data/.eslintrc.fast.js +0 -40
  85. data/.eslintrc.js +0 -84
@@ -0,0 +1,519 @@
1
+ # Shakapacker API Reference
2
+
3
+ This document provides a comprehensive reference for Shakapacker's public Ruby API. For JavaScript/webpack configuration, see [Webpack Configuration](./webpack-configuration.md).
4
+
5
+ ## Table of Contents
6
+
7
+ - [Overview](#overview)
8
+ - [Main Module: Shakapacker](#main-module-shakapacker)
9
+ - [Configuration API](#configuration-api)
10
+ - [View Helpers](#view-helpers)
11
+ - [Manifest API](#manifest-api)
12
+ - [Dev Server API](#dev-server-api)
13
+ - [Compiler API](#compiler-api)
14
+ - [Advanced Usage](#advanced-usage)
15
+
16
+ ## Overview
17
+
18
+ Shakapacker provides a Ruby API for integrating webpack/rspack with Rails applications. The API is divided into several key areas:
19
+
20
+ - **Configuration**: Access to `config/shakapacker.yml` settings
21
+ - **View Helpers**: Rails helpers for rendering script/link tags
22
+ - **Manifest**: Asset lookup and resolution
23
+ - **Compilation**: Programmatic asset compilation
24
+ - **Dev Server**: Development server status and management
25
+
26
+ ### What's Public API?
27
+
28
+ Methods and classes marked with `@api public` in the source code are considered stable public API. Other methods may change between minor versions.
29
+
30
+ ## Main Module: Shakapacker
31
+
32
+ The `Shakapacker` module provides singleton-style access to all major functionality.
33
+
34
+ ### Configuration Access
35
+
36
+ ```ruby
37
+ # Get the configuration object
38
+ Shakapacker.config
39
+ # => #<Shakapacker::Configuration>
40
+
41
+ # Access configuration values
42
+ Shakapacker.config.source_path
43
+ # => #<Pathname:/path/to/app/javascript>
44
+
45
+ Shakapacker.config.public_output_path
46
+ # => "packs"
47
+ ```
48
+
49
+ ### Compilation
50
+
51
+ ```ruby
52
+ # Compile all packs
53
+ Shakapacker.compile
54
+ # => true
55
+
56
+ # Check if compilation is needed
57
+ Shakapacker.compiler.stale?
58
+ # => false
59
+
60
+ # Get compiler output
61
+ Shakapacker.compiler.compile
62
+ ```
63
+
64
+ ### Manifest Lookup
65
+
66
+ ```ruby
67
+ # Look up compiled asset path
68
+ Shakapacker.manifest.lookup("application.js")
69
+ # => "/packs/application-abc123.js"
70
+
71
+ # Look up with error if not found
72
+ Shakapacker.manifest.lookup!("application.js")
73
+ # => "/packs/application-abc123.js" (or raises Shakapacker::Manifest::MissingEntryError)
74
+ ```
75
+
76
+ ### Dev Server Status
77
+
78
+ ```ruby
79
+ # Check if dev server is running
80
+ Shakapacker.dev_server.running?
81
+ # => true
82
+
83
+ # Get dev server host
84
+ Shakapacker.dev_server.host
85
+ # => "localhost"
86
+
87
+ # Get dev server port
88
+ Shakapacker.dev_server.port
89
+ # => 3035
90
+ ```
91
+
92
+ ### Environment Management
93
+
94
+ ```ruby
95
+ # Get current environment
96
+ Shakapacker.env
97
+ # => #<ActiveSupport::StringInquirer "development">
98
+
99
+ # Temporarily use different NODE_ENV
100
+ Shakapacker.with_node_env("production") do
101
+ Shakapacker.compile
102
+ end
103
+ ```
104
+
105
+ ### Logging
106
+
107
+ ```ruby
108
+ # Access logger
109
+ Shakapacker.logger
110
+ # => #<Logger>
111
+
112
+ # Redirect to STDOUT temporarily
113
+ Shakapacker.ensure_log_goes_to_stdout do
114
+ Shakapacker.compile
115
+ end
116
+ ```
117
+
118
+ ## Configuration API
119
+
120
+ The `Shakapacker::Configuration` class provides access to all settings from `config/shakapacker.yml`.
121
+
122
+ ### Accessing Configuration Data
123
+
124
+ ```ruby
125
+ config = Shakapacker.config
126
+
127
+ # Get raw configuration hash (public API as of v9.1.0)
128
+ config.data
129
+ # => { "source_path" => "app/javascript", ... }
130
+
131
+ # Access specific values
132
+ config.data["source_path"]
133
+ # => "app/javascript"
134
+ ```
135
+
136
+ **See Also:** [Configuration Guide](./configuration.md) for all available options.
137
+
138
+ ### Path Configuration
139
+
140
+ ```ruby
141
+ # Source paths
142
+ config.source_path # => #<Pathname:/app/app/javascript>
143
+ config.source_entry_path # => #<Pathname:/app/app/javascript/packs>
144
+ config.additional_paths # => [#<Pathname:/app/app/assets>, ...]
145
+
146
+ # Output paths
147
+ config.public_path # => #<Pathname:/app/public>
148
+ config.public_output_path # => "packs"
149
+ config.public_manifest_path # => #<Pathname:/app/public/packs/manifest.json>
150
+ ```
151
+
152
+ ### Bundler Detection
153
+
154
+ ```ruby
155
+ # Check which bundler is configured
156
+ config.webpack? # => true
157
+ config.rspack? # => false
158
+ config.bundler # => "webpack"
159
+
160
+ # Get bundler config path
161
+ config.assets_bundler_config_path
162
+ # => #<Pathname:/app/config/webpack/webpack.config.js>
163
+ ```
164
+
165
+ ### Compilation Settings
166
+
167
+ ```ruby
168
+ config.compile? # => true (auto-compile enabled?)
169
+ config.cache_manifest? # => false
170
+ config.extract_css? # => false (use MiniCssExtractPlugin?)
171
+ config.nested_entries? # => false
172
+ ```
173
+
174
+ ### Dev Server Configuration
175
+
176
+ ```ruby
177
+ dev_server = config.dev_server
178
+ dev_server["host"] # => "localhost"
179
+ dev_server["port"] # => 3035
180
+ dev_server["hmr"] # => true
181
+ dev_server["https"] # => false
182
+ ```
183
+
184
+ ## View Helpers
185
+
186
+ Shakapacker provides Rails view helpers in the `Shakapacker::Helper` module, automatically included in ActionView.
187
+
188
+ ### JavaScript Pack Tag
189
+
190
+ ```ruby
191
+ # Basic usage
192
+ <%= javascript_pack_tag 'application' %>
193
+ # => <script src="/packs/application-abc123.js" defer></script>
194
+
195
+ # Multiple packs (handles chunk deduplication)
196
+ <%= javascript_pack_tag 'calendar', 'map' %>
197
+
198
+ # Custom attributes
199
+ <%= javascript_pack_tag 'application', 'data-turbo-track': 'reload' %>
200
+
201
+ # Async loading
202
+ <%= javascript_pack_tag 'application', async: true %>
203
+
204
+ # Disable defer
205
+ <%= javascript_pack_tag 'application', defer: false %>
206
+
207
+ # Early hints configuration
208
+ <%= javascript_pack_tag 'application', early_hints: 'preload' %>
209
+ <%= javascript_pack_tag 'application', early_hints: false %>
210
+ ```
211
+
212
+ **Important:** Call `javascript_pack_tag` only once per page to avoid duplicate chunks.
213
+
214
+ ### Stylesheet Pack Tag
215
+
216
+ ```ruby
217
+ # Basic usage
218
+ <%= stylesheet_pack_tag 'application' %>
219
+ # => <link rel="stylesheet" href="/packs/application-abc123.css">
220
+
221
+ # Multiple packs with attributes
222
+ <%= stylesheet_pack_tag 'application', 'calendar', media: 'screen' %>
223
+
224
+ # Early hints
225
+ <%= stylesheet_pack_tag 'application', early_hints: 'preload' %>
226
+ ```
227
+
228
+ ### Dynamic Pack Loading
229
+
230
+ ```ruby
231
+ # In view or partial - queue packs
232
+ <% append_javascript_pack_tag 'calendar' %>
233
+ <% append_stylesheet_pack_tag 'calendar' %>
234
+
235
+ # Prepend to queue
236
+ <% prepend_javascript_pack_tag 'critical' %>
237
+
238
+ # In layout - render all queued packs
239
+ <%= javascript_pack_tag 'application' %>
240
+ <%= stylesheet_pack_tag 'application' %>
241
+ ```
242
+
243
+ ### Asset Helpers
244
+
245
+ ```ruby
246
+ # Get pack path
247
+ <%= asset_pack_path 'logo.svg' %>
248
+ # => "/packs/logo-abc123.svg"
249
+
250
+ # Get pack URL
251
+ <%= asset_pack_url 'logo.svg' %>
252
+ # => "https://cdn.example.com/packs/logo-abc123.svg"
253
+
254
+ # Image pack tag
255
+ <%= image_pack_tag 'logo.png', size: '16x10', alt: 'Logo' %>
256
+ # => <img src="/packs/logo-abc123.png" width="16" height="10" alt="Logo">
257
+
258
+ # With srcset
259
+ <%= image_pack_tag 'photo.png', srcset: { 'photo-2x.png' => '2x' } %>
260
+
261
+ # Favicon
262
+ <%= favicon_pack_tag 'icon.png', rel: 'apple-touch-icon' %>
263
+
264
+ # Preload asset
265
+ <%= preload_pack_asset 'fonts/custom.woff2' %>
266
+ ```
267
+
268
+ ## Manifest API
269
+
270
+ The `Shakapacker::Manifest` class handles asset lookup from the compiled manifest.
271
+
272
+ ### Basic Lookup
273
+
274
+ ```ruby
275
+ manifest = Shakapacker.manifest
276
+
277
+ # Look up an asset (returns nil if not found)
278
+ manifest.lookup("application.js")
279
+ # => "/packs/application-abc123.js"
280
+
281
+ # Look up with error on missing
282
+ manifest.lookup!("application.js")
283
+ # => "/packs/application-abc123.js" (raises if missing)
284
+ ```
285
+
286
+ ### Lookup with Type
287
+
288
+ ```ruby
289
+ # Lookup stylesheets
290
+ manifest.lookup("application.css")
291
+ # => "/packs/application-abc123.css"
292
+
293
+ # Lookup images
294
+ manifest.lookup("logo.svg")
295
+ # => "/packs/static/logo-abc123.svg"
296
+ ```
297
+
298
+ ### Full Manifest Access
299
+
300
+ ```ruby
301
+ # Get all entries
302
+ manifest.data
303
+ # => { "application.js" => "/packs/application-abc123.js", ... }
304
+
305
+ # Refresh manifest from disk
306
+ manifest.refresh
307
+ ```
308
+
309
+ ## Dev Server API
310
+
311
+ The `Shakapacker::DevServer` class provides status and configuration for the development server.
312
+
313
+ ### Status Checking
314
+
315
+ ```ruby
316
+ dev_server = Shakapacker.dev_server
317
+
318
+ # Check if running
319
+ dev_server.running?
320
+ # => true
321
+
322
+ # Get full status URL
323
+ dev_server.status_url
324
+ # => "http://localhost:3035"
325
+ ```
326
+
327
+ ### Configuration
328
+
329
+ ```ruby
330
+ dev_server.host
331
+ # => "localhost"
332
+
333
+ dev_server.port
334
+ # => 3035
335
+
336
+ dev_server.https?
337
+ # => false
338
+
339
+ dev_server.hmr?
340
+ # => true
341
+ ```
342
+
343
+ ### Proxying
344
+
345
+ ```ruby
346
+ # Get asset URL (uses dev server if running, otherwise public path)
347
+ dev_server.asset_url("application.js")
348
+ # => "http://localhost:3035/packs/application.js" (or "/packs/application.js")
349
+ ```
350
+
351
+ ## Compiler API
352
+
353
+ The `Shakapacker::Compiler` class handles compilation of webpack/rspack assets.
354
+
355
+ ### Compilation
356
+
357
+ ```ruby
358
+ compiler = Shakapacker.compiler
359
+
360
+ # Compile all packs
361
+ compiler.compile
362
+ # => true
363
+
364
+ # Check if compilation needed
365
+ compiler.stale?
366
+ # => false
367
+
368
+ # Get last compilation time
369
+ compiler.last_compilation_digest
370
+ # => "abc123..."
371
+ ```
372
+
373
+ ### Configuration
374
+
375
+ ```ruby
376
+ # Get watched paths
377
+ compiler.watched_paths
378
+ # => [#<Pathname:/app/app/javascript>, ...]
379
+
380
+ # Get config files
381
+ compiler.config_files
382
+ # => [#<Pathname:/app/config/webpack/webpack.config.js>, ...]
383
+ ```
384
+
385
+ ## Advanced Usage
386
+
387
+ ### Multiple Shakapacker Instances
388
+
389
+ For advanced scenarios like Rails engines with separate webpack configs:
390
+
391
+ ```ruby
392
+ # Create custom instance
393
+ custom_instance = Shakapacker::Instance.new(
394
+ root_path: Rails.root,
395
+ config_path: Rails.root.join("config/custom_shakapacker.yml")
396
+ )
397
+
398
+ # Use in view helper
399
+ def current_shakapacker_instance
400
+ @custom_instance ||= Shakapacker::Instance.new(...)
401
+ end
402
+ ```
403
+
404
+ ### Testing
405
+
406
+ ```ruby
407
+ # In tests, you can stub the instance
408
+ RSpec.describe "my feature" do
409
+ let(:mock_manifest) { instance_double(Shakapacker::Manifest) }
410
+ let(:mock_instance) { instance_double(Shakapacker::Instance, manifest: mock_manifest) }
411
+
412
+ before do
413
+ allow(Shakapacker).to receive(:instance).and_return(mock_instance)
414
+ end
415
+ end
416
+ ```
417
+
418
+ ### Programmatic Configuration Access
419
+
420
+ ```ruby
421
+ # Access raw configuration for custom tooling
422
+ config_data = Shakapacker.config.data
423
+
424
+ # Use in custom rake task
425
+ namespace :assets do
426
+ task :analyze do
427
+ config = Shakapacker.config
428
+ puts "Source: #{config.source_path}"
429
+ puts "Output: #{config.public_output_path}"
430
+ puts "Bundler: #{config.bundler}"
431
+ end
432
+ end
433
+ ```
434
+
435
+ ### Custom Webpack Configuration
436
+
437
+ Access Shakapacker config from your webpack config:
438
+
439
+ ```javascript
440
+ // config/webpack/webpack.config.js
441
+ const { generateWebpackConfig } = require("shakapacker")
442
+
443
+ // The shakapacker.yml is automatically loaded
444
+ const config = generateWebpackConfig()
445
+
446
+ console.log(config.output.path) // Uses public_output_path from shakapacker.yml
447
+ ```
448
+
449
+ ## Environment Variables
450
+
451
+ Shakapacker respects these environment variables:
452
+
453
+ | Variable | Purpose | Example |
454
+ | ---------------------------- | ----------------------------- | ------------------------- |
455
+ | `SHAKAPACKER_CONFIG` | Custom config file path | `/custom/shakapacker.yml` |
456
+ | `SHAKAPACKER_PRECOMPILE` | Enable/disable precompilation | `false` |
457
+ | `SHAKAPACKER_ASSET_HOST` | CDN hostname | `https://cdn.example.com` |
458
+ | `SHAKAPACKER_ASSETS_BUNDLER` | Override bundler selection | `rspack` |
459
+ | `RAILS_ENV` | Rails environment | `production` |
460
+ | `NODE_ENV` | Node environment | `production` |
461
+
462
+ ## Error Handling
463
+
464
+ ```ruby
465
+ # Manifest lookup errors
466
+ begin
467
+ path = Shakapacker.manifest.lookup!("missing.js")
468
+ rescue Shakapacker::Manifest::MissingEntryError => e
469
+ Rails.logger.error "Missing pack: #{e.message}"
470
+ end
471
+
472
+ # Compilation errors
473
+ begin
474
+ Shakapacker.compiler.compile
475
+ rescue Shakapacker::Compiler::CompilationError => e
476
+ Rails.logger.error "Compilation failed: #{e.message}"
477
+ end
478
+
479
+ # Configuration errors
480
+ begin
481
+ config = Shakapacker::Configuration.new(...)
482
+ rescue Shakapacker::Configuration::InvalidConfigurationError => e
483
+ Rails.logger.error "Invalid config: #{e.message}"
484
+ end
485
+ ```
486
+
487
+ ## Deprecations
488
+
489
+ Shakapacker follows semantic versioning. Deprecated methods will:
490
+
491
+ 1. Issue warnings in the current major version
492
+ 2. Be removed in the next major version
493
+
494
+ Check the [CHANGELOG](../CHANGELOG.md) for deprecation notices.
495
+
496
+ ## See Also
497
+
498
+ - [Configuration Guide](./configuration.md) - All `shakapacker.yml` options
499
+ - [View Helpers](../README.md#view-helpers) - Detailed view helper usage
500
+ - [Webpack Configuration](../README.md#webpack-configuration) - JavaScript API
501
+ - [TypeScript](./typescript.md) - Type definitions for Shakapacker
502
+ - [Troubleshooting](./troubleshooting.md) - Common issues
503
+
504
+ ## Generating Full API Documentation
505
+
506
+ For complete API documentation with all methods and parameters:
507
+
508
+ ```bash
509
+ # Using YARD (recommended)
510
+ gem install yard
511
+ yard doc
512
+ yard server # View at http://localhost:8808
513
+
514
+ # Using RDoc
515
+ rdoc lib/
516
+ open doc/index.html
517
+ ```
518
+
519
+ The generated documentation includes all public and private methods with detailed parameter descriptions.
@@ -4,6 +4,7 @@ This guide covers all configuration options available in `config/shakapacker.yml
4
4
 
5
5
  ## Table of Contents
6
6
 
7
+ - [Quick Reference](#quick-reference)
7
8
  - [Basic Configuration](#basic-configuration)
8
9
  - [Source Configuration](#source-configuration)
9
10
  - [Output Configuration](#output-configuration)
@@ -16,6 +17,35 @@ This guide covers all configuration options available in `config/shakapacker.yml
16
17
  - [Environment-Specific Configuration](#environment-specific-configuration)
17
18
  - [Build Configurations (config/shakapacker-builds.yml)](#build-configurations-configshakapacker-buildsyml)
18
19
 
20
+ ## Quick Reference
21
+
22
+ Common configuration options with their defaults:
23
+
24
+ | Option | Type | Default | Description |
25
+ | ------------------------------ | ------- | --------------------------------------- | ---------------------------------------------------------- |
26
+ | `assets_bundler` | string | `"webpack"` | Bundler to use: `"webpack"` or `"rspack"` |
27
+ | `assets_bundler_config_path` | string | `"config/webpack"` or `"config/rspack"` | Directory containing bundler config files |
28
+ | `javascript_transpiler` | string | `"swc"`\* | Transpiler: `"swc"`, `"babel"`, or `"esbuild"` |
29
+ | `source_path` | string | `"app/javascript"` | Root directory for JavaScript source files |
30
+ | `source_entry_path` | string | `"packs"` | Subdirectory within `source_path` for entry points |
31
+ | `nested_entries` | boolean | `true` | Discover entry points in subdirectories |
32
+ | `public_output_path` | string | `"packs"` | Subdirectory within `public_root_path` for compiled assets |
33
+ | `private_output_path` | string | `nil` | Directory for private server-side bundles (e.g., SSR) |
34
+ | `compile` | boolean | env-specific | Compile assets on-demand when requests are made |
35
+ | `cache_manifest` | boolean | `false` (dev), `true` (prod) | Cache manifest.json in memory |
36
+ | `compiler_strategy` | string | `"mtime"` (dev), `"digest"` (prod) | How to determine if recompilation is needed |
37
+ | `useContentHash` | boolean | `false` (dev), `true` (prod) | Include content hashes in asset filenames |
38
+ | `webpack_compile_output` | boolean | `true` | Show webpack/rspack compilation output |
39
+ | `shakapacker_precompile` | boolean | `true` | Include in `rails assets:precompile` |
40
+ | `ensure_consistent_versioning` | boolean | `true` | Enforce gem/npm version matching |
41
+ | `dev_server.host` | string | `"localhost"` | Development server host |
42
+ | `dev_server.port` | number | `3035` | Development server port |
43
+ | `dev_server.hmr` | boolean | `false` | Enable Hot Module Replacement |
44
+
45
+ For detailed explanations, examples, and additional options, see the sections below.
46
+
47
+ **\*Note on `javascript_transpiler` default**: The installation template sets this to `"swc"` for new projects. However, at runtime, if no explicit value is configured, webpack defaults to `"babel"` (for backward compatibility) while rspack defaults to `"swc"`.
48
+
19
49
  ## Basic Configuration
20
50
 
21
51
  ### `assets_bundler`
@@ -63,23 +93,27 @@ assets_bundler_config_path: "."
63
93
  ### `javascript_transpiler`
64
94
 
65
95
  **Type:** `string`
66
- **Default:** `"swc"` (or `"babel"` for webpack when not specified)
96
+ **Default:** `"swc"` (new installations), `"babel"` (webpack runtime), `"swc"` (rspack runtime)
67
97
  **Options:** `"swc"`, `"babel"`, or `"esbuild"`
68
98
 
69
99
  Specifies which transpiler to use for JavaScript/TypeScript.
70
100
 
71
101
  ```yaml
72
- # Use SWC (recommended - 20x faster than Babel)
102
+ # Use SWC (recommended - 20x faster than Babel, set by default in new installations)
73
103
  javascript_transpiler: "swc"
74
104
 
75
- # Use Babel (for maximum compatibility)
105
+ # Use Babel (for maximum compatibility, webpack runtime default if not configured)
76
106
  javascript_transpiler: "babel"
77
107
 
78
108
  # Use esbuild (fastest, but may have compatibility issues)
79
109
  javascript_transpiler: "esbuild"
80
110
  ```
81
111
 
82
- **Note:** When using rspack, swc is used automatically regardless of this setting due to built-in support.
112
+ **Important default behavior:**
113
+
114
+ - **New installations**: The installation template explicitly sets `javascript_transpiler: "swc"`
115
+ - **Webpack runtime default**: If not explicitly configured, defaults to `"babel"` for backward compatibility
116
+ - **Rspack runtime default**: If not explicitly configured, defaults to `"swc"` as rspack is a newer bundler
83
117
 
84
118
  See [Transpiler Performance Guide](transpiler-performance.md) for benchmarks and migration guides.
85
119
 
@@ -150,11 +150,45 @@ If you prefer to keep the v8 default export behavior during migration, you can o
150
150
 
151
151
  ## Reverting to Default Exports (v8 Behavior)
152
152
 
153
- To use the v8-style default exports instead of v9's named exports:
153
+ To use the v8-style default exports instead of v9's named exports, you have several options:
154
154
 
155
- ### Option 1: Update `config/webpack/commonWebpackConfig.js` (Recommended)
155
+ ### Option 1: Configuration File (Easiest - Recommended)
156
156
 
157
- This approach modifies the common webpack configuration that applies to all environments:
157
+ The simplest way to restore v8 behavior is to set the `css_modules_export_mode` option in your `config/shakapacker.yml`:
158
+
159
+ ```yaml
160
+ # config/shakapacker.yml
161
+ default: &default
162
+ # ... other settings ...
163
+
164
+ # CSS Modules export mode
165
+ # named (default) - Use named exports with camelCase conversion (v9 default)
166
+ # default - Use default export with both original and camelCase names (v8 behavior)
167
+ css_modules_export_mode: default
168
+ ```
169
+
170
+ This configuration automatically adjusts the CSS loader settings:
171
+
172
+ - Sets `namedExport: false` to enable default exports
173
+ - Sets `exportLocalsConvention: 'camelCase'` to export both original and camelCase versions
174
+
175
+ **Restart your development server** after changing this setting for the changes to take effect.
176
+
177
+ With this configuration, you can continue using v8-style imports:
178
+
179
+ ```js
180
+ // Works with css_modules_export_mode: default
181
+ import styles from "./Component.module.css"
182
+ ;<div className={styles.container}>
183
+ <button className={styles.button}>Click me</button>
184
+ <button className={styles["my-button"]}>Kebab-case</button>
185
+ <button className={styles.myButton}>Also available</button>
186
+ </div>
187
+ ```
188
+
189
+ ### Option 2: Manual Webpack Configuration (Advanced)
190
+
191
+ If you need more control or can't use the configuration file approach, you can manually modify the webpack configuration that applies to all environments:
158
192
 
159
193
  ```js
160
194
  // config/webpack/commonWebpackConfig.js
@@ -198,7 +232,7 @@ const commonWebpackConfig = () => {
198
232
  module.exports = commonWebpackConfig
199
233
  ```
200
234
 
201
- ### Option 2: Create `config/webpack/environment.js` (Alternative)
235
+ ### Option 3: Create `config/webpack/environment.js` (Alternative)
202
236
 
203
237
  If you prefer using a separate environment file:
204
238
 
@@ -239,12 +273,12 @@ module.exports = environment
239
273
 
240
274
  Then reference this in your environment-specific configs (development.js, production.js, etc.).
241
275
 
242
- ### Option 3: (Optional) Sass Modules
276
+ ### Option 4: (Optional) Sass Modules
243
277
 
244
278
  If you also use Sass modules, add similar configuration for SCSS files:
245
279
 
246
280
  ```js
247
- // For Option 1 approach, extend the overrideCssModulesConfig function:
281
+ // For Option 2 approach (manual webpack config), extend the overrideCssModulesConfig function:
248
282
  const overrideCssModulesConfig = (config) => {
249
283
  // Handle both CSS and SCSS rules
250
284
  const styleRules = config.module.rules.filter(