shakapacker 9.3.0.beta.7 → 9.3.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 (55) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +46 -109
  3. data/Gemfile.lock +1 -1
  4. data/README.md +53 -2
  5. data/docs/configuration.md +28 -0
  6. data/docs/rspack_migration_guide.md +238 -2
  7. data/docs/troubleshooting.md +21 -21
  8. data/eslint.config.fast.js +8 -0
  9. data/eslint.config.js +47 -10
  10. data/knip.ts +8 -1
  11. data/lib/install/config/shakapacker.yml +6 -6
  12. data/lib/shakapacker/configuration.rb +227 -4
  13. data/lib/shakapacker/dev_server.rb +88 -1
  14. data/lib/shakapacker/doctor.rb +4 -4
  15. data/lib/shakapacker/instance.rb +85 -1
  16. data/lib/shakapacker/manifest.rb +85 -11
  17. data/lib/shakapacker/version.rb +1 -1
  18. data/lib/shakapacker.rb +143 -3
  19. data/lib/tasks/shakapacker/doctor.rake +1 -1
  20. data/lib/tasks/shakapacker/export_bundler_config.rake +4 -4
  21. data/package/config.ts +0 -1
  22. data/package/configExporter/buildValidator.ts +53 -29
  23. data/package/configExporter/cli.ts +81 -56
  24. data/package/configExporter/configFile.ts +33 -26
  25. data/package/configExporter/types.ts +64 -0
  26. data/package/configExporter/yamlSerializer.ts +118 -43
  27. data/package/dev_server.ts +2 -1
  28. data/package/env.ts +1 -1
  29. data/package/environments/base.ts +4 -4
  30. data/package/environments/development.ts +7 -6
  31. data/package/environments/production.ts +6 -7
  32. data/package/environments/test.ts +2 -1
  33. data/package/index.ts +28 -4
  34. data/package/loaders.d.ts +2 -2
  35. data/package/optimization/webpack.ts +29 -31
  36. data/package/rspack/index.ts +2 -1
  37. data/package/rules/file.ts +1 -0
  38. data/package/rules/jscommon.ts +1 -0
  39. data/package/utils/helpers.ts +0 -1
  40. data/package/utils/pathValidation.ts +68 -7
  41. data/package/utils/requireOrError.ts +10 -2
  42. data/package/utils/typeGuards.ts +43 -46
  43. data/package/webpack-types.d.ts +2 -2
  44. data/package/webpackDevServerConfig.ts +1 -0
  45. data/package.json +2 -3
  46. data/test/package/configExporter/cli.test.js +440 -0
  47. data/test/package/configExporter/types.test.js +163 -0
  48. data/test/package/configExporter.test.js +264 -0
  49. data/test/package/yamlSerializer.test.js +204 -0
  50. data/test/typescript/pathValidation.test.js +44 -0
  51. data/test/typescript/requireOrError.test.js +49 -0
  52. data/yarn.lock +0 -32
  53. metadata +11 -5
  54. data/.eslintrc.fast.js +0 -40
  55. data/.eslintrc.js +0 -84
@@ -21,7 +21,7 @@ If you're experiencing FOUC where content briefly appears unstyled before CSS lo
21
21
 
22
22
  4. You can also pass additional options to the command to run the webpack-dev-server and start the webpack-dev-server with the option `--debug-shakapacker`
23
23
 
24
- 5. **Export your full webpack/rspack configuration for analysis**: Use the `bin/export-bundler-config` utility to export your complete resolved configuration. This is especially helpful for:
24
+ 5. **Export your full webpack/rspack configuration for analysis**: Use the `bin/shakapacker-config` utility to export your complete resolved configuration. This is especially helpful for:
25
25
  - **Migrations**: Comparing configurations before and after migrating between webpack and rspack, or between different Shakapacker versions
26
26
  - **Debugging**: Inspecting the exact configuration webpack/rspack is using, including all merged settings
27
27
  - **AI Analysis**: Uploading the exported config to ChatGPT or other AI tools for troubleshooting
@@ -35,7 +35,7 @@ If you're experiencing FOUC where content briefly appears unstyled before CSS lo
35
35
  rake shakapacker:binstubs
36
36
 
37
37
  # Export EVERYTHING for troubleshooting (dev + prod, annotated YAML)
38
- bin/export-bundler-config --doctor
38
+ bin/shakapacker-config --doctor
39
39
  # Creates: webpack-development-client.yaml, webpack-development-server.yaml,
40
40
  # webpack-production-client.yaml, webpack-production-server.yaml
41
41
  ```
@@ -44,28 +44,28 @@ If you're experiencing FOUC where content briefly appears unstyled before CSS lo
44
44
 
45
45
  ```bash
46
46
  # Save current environment configs with auto-generated names
47
- bin/export-bundler-config --save
47
+ bin/shakapacker-config --save
48
48
  # Creates: webpack-development-client.yaml, webpack-development-server.yaml
49
49
 
50
50
  # Save to specific directory
51
- bin/export-bundler-config --save --save-dir=./debug-configs
51
+ bin/shakapacker-config --save --save-dir=./debug-configs
52
52
 
53
53
  # Export only client config for production
54
- bin/export-bundler-config --save --env=production --client-only
54
+ bin/shakapacker-config --save --env=production --client-only
55
55
  # Creates: webpack-production-client.yaml
56
56
 
57
57
  # Compare development vs production configs
58
- bin/export-bundler-config --save --save-dir=./configs
58
+ bin/shakapacker-config --save --save-dir=./configs
59
59
  diff configs/webpack-development-client.yaml configs/webpack-production-client.yaml
60
60
 
61
61
  # View config in terminal (no files created)
62
- bin/export-bundler-config
62
+ bin/shakapacker-config
63
63
 
64
64
  # Export without inline documentation annotations
65
- bin/export-bundler-config --save --no-annotate
65
+ bin/shakapacker-config --save --no-annotate
66
66
 
67
67
  # Export in JSON format for programmatic analysis
68
- bin/export-bundler-config --save --format=json
68
+ bin/shakapacker-config --save --format=json
69
69
  ```
70
70
 
71
71
  **Config files are automatically named:** `{bundler}-{env}-{type}.{ext}`
@@ -73,9 +73,9 @@ If you're experiencing FOUC where content briefly appears unstyled before CSS lo
73
73
  - YAML format includes inline documentation explaining each config key
74
74
  - Separate files for client and server bundles (cleaner than combined)
75
75
 
76
- See `bin/export-bundler-config --help` for all available options.
76
+ See `bin/shakapacker-config --help` for all available options.
77
77
 
78
- 6. **Validate your webpack/rspack builds**: Use `bin/export-bundler-config --validate` to test that all your build configurations compile successfully. This is especially useful for:
78
+ 6. **Validate your webpack/rspack builds**: Use `bin/shakapacker-config --validate` to test that all your build configurations compile successfully. This is especially useful for:
79
79
  - **CI/CD pipelines**: Catch configuration errors before deployment
80
80
  - **Migration testing**: Verify builds work after upgrading webpack, rspack, or Shakapacker
81
81
  - **Multi-environment testing**: Ensure all build configurations (dev, prod, HMR) compile correctly
@@ -84,13 +84,13 @@ If you're experiencing FOUC where content briefly appears unstyled before CSS lo
84
84
 
85
85
  ```bash
86
86
  # Validate all builds defined in .bundler-config.yml
87
- bin/export-bundler-config --validate
87
+ bin/shakapacker-config --validate
88
88
 
89
89
  # Validate with full output logs (shows all webpack/rspack compilation output)
90
- bin/export-bundler-config --validate --verbose
90
+ bin/shakapacker-config --validate --verbose
91
91
 
92
92
  # Validate a specific build
93
- bin/export-bundler-config --validate-build=dev-hmr
93
+ bin/shakapacker-config --validate-build=dev-hmr
94
94
  ```
95
95
 
96
96
  **Verbose Mode:**
@@ -108,13 +108,13 @@ If you're experiencing FOUC where content briefly appears unstyled before CSS lo
108
108
 
109
109
  ```bash
110
110
  # Create a .bundler-config.yml file with example builds
111
- bin/export-bundler-config --init
111
+ bin/shakapacker-config --init
112
112
 
113
113
  # List all available builds
114
- bin/export-bundler-config --list-builds
114
+ bin/shakapacker-config --list-builds
115
115
 
116
116
  # Validate all builds
117
- bin/export-bundler-config --validate
117
+ bin/shakapacker-config --validate
118
118
  ```
119
119
 
120
120
  **Advanced options:**
@@ -177,9 +177,9 @@ If you're experiencing FOUC where content briefly appears unstyled before CSS lo
177
177
  💡 Debugging Tips:
178
178
  To get more details, run individual builds with --verbose:
179
179
 
180
- bin/export-bundler-config --validate-build prod --verbose
180
+ bin/shakapacker-config --validate-build prod --verbose
181
181
 
182
- Or validate all builds with full output: bin/export-bundler-config --validate --verbose
182
+ Or validate all builds with full output: bin/shakapacker-config --validate --verbose
183
183
  ================================================================================
184
184
  ```
185
185
 
@@ -189,13 +189,13 @@ If you're experiencing FOUC where content briefly appears unstyled before CSS lo
189
189
  1. **Run a specific build with verbose output** to see full webpack/rspack logs:
190
190
 
191
191
  ```bash
192
- bin/export-bundler-config --validate-build prod --verbose
192
+ bin/shakapacker-config --validate-build prod --verbose
193
193
  ```
194
194
 
195
195
  2. **Validate all builds with verbose output** to see everything:
196
196
 
197
197
  ```bash
198
- bin/export-bundler-config --validate --verbose
198
+ bin/shakapacker-config --validate --verbose
199
199
  ```
200
200
 
201
201
  3. **Test individual builds manually** using the same configuration:
@@ -25,6 +25,14 @@ module.exports = [
25
25
  ]
26
26
  },
27
27
 
28
+ // Global linter options
29
+ {
30
+ linterOptions: {
31
+ reportUnusedDisableDirectives: "error",
32
+ reportUnusedInlineConfigs: "error"
33
+ }
34
+ },
35
+
28
36
  // Base config for all JS files
29
37
  ...compat.extends("airbnb"),
30
38
  {
data/eslint.config.js CHANGED
@@ -23,10 +23,20 @@ module.exports = [
23
23
  // Temporarily ignore TypeScript files until technical debt is resolved
24
24
  // See ESLINT_TECHNICAL_DEBT.md for tracking
25
25
  // TODO: Remove this once ESLint issues are fixed (tracked in #723)
26
- "package/**/*.ts"
26
+ // Exception: configExporter is being fixed in #707
27
+ "package/**/*.ts",
28
+ "!package/configExporter/**/*.ts" // Enable linting for configExporter (issue #707)
27
29
  ]
28
30
  },
29
31
 
32
+ // Global linter options
33
+ {
34
+ linterOptions: {
35
+ reportUnusedDisableDirectives: "error",
36
+ reportUnusedInlineConfigs: "error"
37
+ }
38
+ },
39
+
30
40
  // Base config for all JS files
31
41
  ...compat.extends("airbnb"),
32
42
  {
@@ -181,21 +191,48 @@ module.exports = [
181
191
  }
182
192
  },
183
193
  {
194
+ // #707: Significant type safety improvements in configExporter module!
195
+ // - configFile.ts: ✅ Fully type-safe (0 type errors)
196
+ // - buildValidator.ts: ✅ Fully type-safe (0 type errors)
197
+ // - yamlSerializer.ts: ✅ Fully type-safe (0 type errors)
198
+ // - cli.ts: ⚠️ Partial (dynamic webpack config loading requires some `any`)
199
+ //
200
+ // Remaining overrides are for:
201
+ // 1. Code style/organization (not type safety)
202
+ // 2. Dynamic require() in cli.ts for webpack config loading
184
203
  files: ["package/configExporter/**/*.ts"],
204
+ rules: {
205
+ // Code organization (functions before use due to large file)
206
+ "@typescript-eslint/no-use-before-define": "off",
207
+ // Import style (CommonJS require for dynamic imports)
208
+ "@typescript-eslint/no-require-imports": "off",
209
+ "import/no-dynamic-require": "off",
210
+ "global-require": "off",
211
+ // Class methods that are part of public API
212
+ "class-methods-use-this": "off",
213
+ // Template expressions (valid use cases with union types)
214
+ "@typescript-eslint/restrict-template-expressions": "off",
215
+ // Style preferences
216
+ "no-continue": "off",
217
+ "import/prefer-default-export": "off",
218
+ "no-await-in-loop": "off",
219
+ "no-underscore-dangle": "off",
220
+ "no-shadow": "off",
221
+ "no-restricted-globals": "off",
222
+ "@typescript-eslint/no-unused-vars": "off",
223
+ "@typescript-eslint/require-await": "off"
224
+ }
225
+ },
226
+ {
227
+ // cli.ts: Dynamic webpack config loading requires `any` types
228
+ // This is acceptable as webpack configs can have any shape
229
+ files: ["package/configExporter/cli.ts"],
185
230
  rules: {
186
231
  "@typescript-eslint/no-explicit-any": "off",
187
232
  "@typescript-eslint/no-unsafe-assignment": "off",
188
233
  "@typescript-eslint/no-unsafe-member-access": "off",
189
234
  "@typescript-eslint/no-unsafe-call": "off",
190
- "@typescript-eslint/no-unsafe-return": "off",
191
- "@typescript-eslint/no-unsafe-argument": "off",
192
- "@typescript-eslint/no-unsafe-function-type": "off",
193
- "@typescript-eslint/no-unused-vars": "off",
194
- "@typescript-eslint/require-await": "off",
195
- "no-await-in-loop": "off",
196
- "import/prefer-default-export": "off",
197
- "global-require": "off",
198
- "no-underscore-dangle": "off"
235
+ "@typescript-eslint/no-unsafe-return": "off"
199
236
  }
200
237
  },
201
238
  {
data/knip.ts CHANGED
@@ -47,7 +47,14 @@ const config: KnipConfig = {
47
47
  "css-loader",
48
48
  "esbuild-loader",
49
49
  "swc-loader",
50
- "webpack"
50
+ "webpack",
51
+ // eslint-config-airbnb isn't detected because it's used by compat.extends("airbnb"),
52
+ // the rest are its peerDependencies
53
+ "eslint-config-airbnb",
54
+ "eslint-plugin-import",
55
+ "eslint-plugin-jsx-a11y",
56
+ "eslint-plugin-react",
57
+ "eslint-plugin-react-hooks"
51
58
  ]
52
59
  }
53
60
 
@@ -67,9 +67,8 @@ default: &default
67
67
  compiler_strategy: digest
68
68
 
69
69
  # Select whether the compiler will always use a content hash and not just in production
70
- # Don't use contentHash except for production for performance
71
- # https://webpack.js.org/guides/build-performance/#avoid-production-specific-tooling
72
- useContentHash: false
70
+ # Content hashes are recommended for production cache busting
71
+ useContentHash: true
73
72
 
74
73
  # Setting the asset host here will override Rails.application.config.asset_host.
75
74
  # Here, you can set different asset_host per environment. Note that
@@ -101,6 +100,10 @@ development:
101
100
  compile: true
102
101
  compiler_strategy: mtime
103
102
 
103
+ # Disable content hashes in development for faster builds
104
+ # https://webpack.js.org/guides/caching/
105
+ useContentHash: false
106
+
104
107
  # Early hints disabled by default in development
105
108
  # To enable: Set enabled: true AND start Puma with: bundle exec puma --early-hints
106
109
  # See docs/early_hints_new_api.md for setup instructions
@@ -164,9 +167,6 @@ production:
164
167
  # Production depends on precompilation of packs prior to booting for performance.
165
168
  compile: false
166
169
 
167
- # Use content hash for naming assets. Cannot be overridden in production.
168
- useContentHash: true
169
-
170
170
  # Cache manifest.json for performance
171
171
  cache_manifest: true
172
172
 
@@ -3,13 +3,62 @@ require "json"
3
3
  require "active_support/core_ext/hash/keys"
4
4
  require "active_support/core_ext/hash/indifferent_access"
5
5
 
6
+ # Configuration management for Shakapacker
7
+ #
8
+ # Loads and provides access to settings from +config/shakapacker.yml+, including:
9
+ # - Source and output paths
10
+ # - Compilation settings
11
+ # - Dev server configuration
12
+ # - Asset bundler selection (webpack vs rspack)
13
+ # - JavaScript transpiler configuration (babel, swc, esbuild)
14
+ #
15
+ # Configuration values can be overridden via environment variables:
16
+ # - +SHAKAPACKER_CONFIG+ - path to config file
17
+ # - +SHAKAPACKER_PRECOMPILE+ - whether to precompile assets
18
+ # - +SHAKAPACKER_ASSETS_BUNDLER+ - which bundler to use
19
+ # - +SHAKAPACKER_ASSET_HOST+ - CDN or asset host URL
20
+ #
21
+ # @example Accessing configuration
22
+ # config = Shakapacker.config
23
+ # config.source_path
24
+ # #=> #<Pathname:/app/app/packs>
25
+ # config.webpack?
26
+ # #=> true
27
+ #
28
+ # @see https://github.com/shakacode/shakapacker/blob/main/docs/shakapacker.yml.md
6
29
  class Shakapacker::Configuration
7
30
  class << self
31
+ # Flag indicating whether Shakapacker is currently being installed
32
+ # Used to suppress certain validations during installation
33
+ # @return [Boolean] true if installation is in progress
34
+ # @api private
8
35
  attr_accessor :installing
9
36
  end
10
37
 
11
- attr_reader :root_path, :config_path, :env, :bundler_override
12
-
38
+ # The application root path
39
+ # @return [Pathname] the root path
40
+ attr_reader :root_path
41
+
42
+ # The path to the shakapacker.yml configuration file
43
+ # @return [Pathname] the config file path
44
+ attr_reader :config_path
45
+
46
+ # The current Rails environment
47
+ # @return [ActiveSupport::StringInquirer] the environment
48
+ attr_reader :env
49
+
50
+ # Override for the assets bundler (set via CLI flag)
51
+ # @return [String, nil] the bundler override or nil
52
+ # @api private
53
+ attr_reader :bundler_override
54
+
55
+ # Creates a new configuration instance
56
+ #
57
+ # @param root_path [Pathname] the application root path
58
+ # @param config_path [Pathname] the path to shakapacker.yml
59
+ # @param env [ActiveSupport::StringInquirer] the Rails environment
60
+ # @param bundler_override [String, nil] optional bundler override (webpack or rspack)
61
+ # @return [Shakapacker::Configuration] the new configuration instance
13
62
  def initialize(root_path:, config_path:, env:, bundler_override: nil)
14
63
  @root_path = root_path
15
64
  @env = env
@@ -17,22 +66,52 @@ class Shakapacker::Configuration
17
66
  @bundler_override = bundler_override
18
67
  end
19
68
 
69
+ # Returns the dev server configuration hash
70
+ #
71
+ # Contains settings like host, port, https, hmr, etc. for the webpack-dev-server.
72
+ #
73
+ # @return [Hash] the dev server configuration
20
74
  def dev_server
21
75
  fetch(:dev_server)
22
76
  end
23
77
 
78
+ # Returns whether automatic compilation is enabled
79
+ #
80
+ # When true, Shakapacker will automatically compile assets when they're requested
81
+ # and are stale. This is typically enabled in development and disabled in production.
82
+ #
83
+ # @return [Boolean] true if automatic compilation is enabled
24
84
  def compile?
25
85
  fetch(:compile)
26
86
  end
27
87
 
88
+ # Returns whether nested entries are enabled
89
+ #
90
+ # When true, allows organizing entry points in subdirectories within the
91
+ # source entry path.
92
+ #
93
+ # @return [Boolean] true if nested entries are allowed
28
94
  def nested_entries?
29
95
  fetch(:nested_entries)
30
96
  end
31
97
 
98
+ # Returns whether consistent versioning check is enabled
99
+ #
100
+ # When true, verifies that package.json and Gemfile versions of shakapacker match.
101
+ #
102
+ # @return [Boolean] true if version consistency checking is enabled
32
103
  def ensure_consistent_versioning?
33
104
  fetch(:ensure_consistent_versioning)
34
105
  end
35
106
 
107
+ # Returns whether Shakapacker should precompile assets
108
+ #
109
+ # Checks in order:
110
+ # 1. SHAKAPACKER_PRECOMPILE environment variable (yes/true/y/t or no/false/n/f)
111
+ # 2. shakapacker_precompile setting in config file
112
+ # 3. Defaults to false if config file doesn't exist
113
+ #
114
+ # @return [Boolean] true if assets should be precompiled
36
115
  def shakapacker_precompile?
37
116
  # ENV of false takes precedence
38
117
  return false if %w(no false n f).include?(ENV["SHAKAPACKER_PRECOMPILE"])
@@ -42,18 +121,40 @@ class Shakapacker::Configuration
42
121
  fetch(:shakapacker_precompile)
43
122
  end
44
123
 
124
+ # Returns the absolute path to the source directory
125
+ #
126
+ # This is where your JavaScript/CSS source files live (e.g., app/packs).
127
+ #
128
+ # @return [Pathname] the absolute source path
45
129
  def source_path
46
130
  root_path.join(fetch(:source_path))
47
131
  end
48
132
 
133
+ # Returns additional paths to include in compilation
134
+ #
135
+ # These paths are added to webpack/rspack's resolve configuration to allow
136
+ # importing modules from additional directories.
137
+ #
138
+ # @return [Array<String>] array of additional paths
49
139
  def additional_paths
50
140
  fetch(:additional_paths)
51
141
  end
52
142
 
143
+ # Returns the absolute path to the source entry directory
144
+ #
145
+ # Entry points (application.js, etc.) are found in this directory.
146
+ #
147
+ # @return [Pathname] the absolute entry path
53
148
  def source_entry_path
54
149
  source_path.join(relative_path(fetch(:source_entry_path)))
55
150
  end
56
151
 
152
+ # Returns the absolute path to the manifest.json file
153
+ #
154
+ # The manifest maps source file names to their compiled output paths with digests.
155
+ # Defaults to manifest.json in the public output directory if not configured.
156
+ #
157
+ # @return [Pathname] the absolute manifest path
57
158
  def manifest_path
58
159
  if data.has_key?(:manifest_path)
59
160
  root_path.join(fetch(:manifest_path))
@@ -62,14 +163,30 @@ class Shakapacker::Configuration
62
163
  end
63
164
  end
64
165
 
166
+ # Alias for {#manifest_path}
167
+ #
168
+ # @return [Pathname] the absolute manifest path
169
+ # @see #manifest_path
65
170
  def public_manifest_path
66
171
  manifest_path
67
172
  end
68
173
 
174
+ # Returns the absolute path to the public root directory
175
+ #
176
+ # This is typically the Rails +public/+ directory where compiled assets
177
+ # are served from.
178
+ #
179
+ # @return [Pathname] the absolute public path
69
180
  def public_path
70
181
  root_path.join(fetch(:public_root_path))
71
182
  end
72
183
 
184
+ # Returns the absolute path to the private output directory
185
+ #
186
+ # The private output path is for server-side bundles (e.g., SSR) that should
187
+ # not be publicly accessible. Returns nil if not configured.
188
+ #
189
+ # @return [Pathname, nil] the absolute private output path or nil
73
190
  def private_output_path
74
191
  private_path = fetch(:private_output_path)
75
192
  return nil unless private_path
@@ -77,26 +194,66 @@ class Shakapacker::Configuration
77
194
  root_path.join(private_path)
78
195
  end
79
196
 
197
+ # Returns the absolute path to the public output directory
198
+ #
199
+ # This is where compiled assets are written for public serving
200
+ # (typically +public/packs+).
201
+ #
202
+ # @return [Pathname] the absolute public output path
80
203
  def public_output_path
81
204
  public_path.join(fetch(:public_output_path))
82
205
  end
83
206
 
207
+ # Returns whether manifest caching is enabled
208
+ #
209
+ # When true, the manifest.json file is cached in memory and only reloaded
210
+ # when it changes. This improves performance in production.
211
+ #
212
+ # @return [Boolean] true if manifest should be cached
84
213
  def cache_manifest?
85
214
  fetch(:cache_manifest)
86
215
  end
87
216
 
217
+ # Returns the absolute path to the compilation cache directory
218
+ #
219
+ # Webpack/rspack uses this directory to cache compilation results for faster
220
+ # subsequent builds.
221
+ #
222
+ # @return [Pathname] the absolute cache path
88
223
  def cache_path
89
224
  root_path.join(fetch(:cache_path))
90
225
  end
91
226
 
227
+ # Returns whether webpack/rspack compilation output should be shown
228
+ #
229
+ # When true, displays webpack/rspack's compilation progress and results.
230
+ #
231
+ # @return [Boolean] true if compilation output should be displayed
92
232
  def webpack_compile_output?
93
233
  fetch(:webpack_compile_output)
94
234
  end
95
235
 
236
+ # Returns the compiler strategy for determining staleness
237
+ #
238
+ # Options:
239
+ # - +"mtime"+ - use file modification times (faster, less accurate)
240
+ # - +"digest"+ - use file content digests (slower, more accurate)
241
+ #
242
+ # @return [String] the compiler strategy ("mtime" or "digest")
96
243
  def compiler_strategy
97
244
  fetch(:compiler_strategy)
98
245
  end
99
246
 
247
+ # Returns the assets bundler to use (webpack or rspack)
248
+ #
249
+ # Resolution order:
250
+ # 1. CLI --bundler flag (via bundler_override)
251
+ # 2. SHAKAPACKER_ASSETS_BUNDLER environment variable
252
+ # 3. assets_bundler setting in config file
253
+ # 4. bundler setting in config file (deprecated)
254
+ # 5. Defaults to "webpack"
255
+ #
256
+ # @return [String] "webpack" or "rspack"
100
257
  def assets_bundler
101
258
  # CLI --bundler flag takes highest precedence
102
259
  return @bundler_override if @bundler_override
@@ -108,19 +265,35 @@ class Shakapacker::Configuration
108
265
  ENV["SHAKAPACKER_ASSETS_BUNDLER"] || fetch(:assets_bundler) || fetch(:bundler) || "webpack"
109
266
  end
110
267
 
111
- # Deprecated: Use assets_bundler instead
268
+ # Deprecated alias for {#assets_bundler}
269
+ #
270
+ # @deprecated Use {#assets_bundler} instead
271
+ # @return [String] the assets bundler
272
+ # @see #assets_bundler
112
273
  def bundler
113
274
  assets_bundler
114
275
  end
115
276
 
277
+ # Returns whether rspack is the configured bundler
278
+ #
279
+ # @return [Boolean] true if using rspack
116
280
  def rspack?
117
281
  assets_bundler == "rspack"
118
282
  end
119
283
 
284
+ # Returns whether webpack is the configured bundler
285
+ #
286
+ # @return [Boolean] true if using webpack
120
287
  def webpack?
121
288
  assets_bundler == "webpack"
122
289
  end
123
290
 
291
+ # Returns the precompile hook command to run after compilation
292
+ #
293
+ # The hook is a shell command that runs after successful compilation,
294
+ # useful for post-processing tasks.
295
+ #
296
+ # @return [String, nil] the hook command or nil if not configured
124
297
  def precompile_hook
125
298
  hook = fetch(:precompile_hook)
126
299
  return nil if hook.nil? || (hook.is_a?(String) && hook.strip.empty?)
@@ -132,6 +305,16 @@ class Shakapacker::Configuration
132
305
  hook.strip
133
306
  end
134
307
 
308
+ # Returns the JavaScript transpiler to use (babel, swc, or esbuild)
309
+ #
310
+ # Resolution order:
311
+ # 1. javascript_transpiler setting in config file
312
+ # 2. webpack_loader setting in config file (deprecated)
313
+ # 3. Default based on bundler (swc for rspack, babel for webpack)
314
+ #
315
+ # Validates that the configured transpiler matches installed packages.
316
+ #
317
+ # @return [String] "babel", "swc", or "esbuild"
135
318
  def javascript_transpiler
136
319
  # Show deprecation warning if using old 'webpack_loader' key
137
320
  if data.has_key?(:webpack_loader) && !data.has_key?(:javascript_transpiler)
@@ -147,11 +330,21 @@ class Shakapacker::Configuration
147
330
  transpiler
148
331
  end
149
332
 
150
- # Deprecated: Use javascript_transpiler instead
333
+ # Deprecated alias for {#javascript_transpiler}
334
+ #
335
+ # @deprecated Use {#javascript_transpiler} instead
336
+ # @return [String] the JavaScript transpiler
337
+ # @see #javascript_transpiler
151
338
  def webpack_loader
152
339
  javascript_transpiler
153
340
  end
154
341
 
342
+ # Returns the path to the bundler configuration directory
343
+ #
344
+ # This is where webpack.config.js or rspack.config.js should be located.
345
+ # Defaults to config/webpack for webpack or config/rspack for rspack.
346
+ #
347
+ # @return [String] the relative path to the bundler config directory
155
348
  def assets_bundler_config_path
156
349
  custom_path = fetch(:assets_bundler_config_path)
157
350
  return custom_path if custom_path
@@ -220,10 +413,28 @@ class Shakapacker::Configuration
220
413
 
221
414
  public
222
415
 
416
+ # Fetches a configuration value
417
+ #
418
+ # Looks up the value in the loaded configuration data, falling back to
419
+ # the default configuration if not found.
420
+ #
421
+ # @param key [Symbol] the configuration key to fetch
422
+ # @return [Object] the configuration value
423
+ # @api private
223
424
  def fetch(key)
224
425
  data.fetch(key, defaults[key])
225
426
  end
226
427
 
428
+ # Returns the asset host URL for serving assets
429
+ #
430
+ # Resolution order:
431
+ # 1. SHAKAPACKER_ASSET_HOST environment variable
432
+ # 2. asset_host setting in config file
433
+ # 3. Rails ActionController::Base.helpers.compute_asset_host
434
+ #
435
+ # Used to serve assets from a CDN or different domain.
436
+ #
437
+ # @return [String, nil] the asset host URL or nil
227
438
  def asset_host
228
439
  ENV.fetch(
229
440
  "SHAKAPACKER_ASSET_HOST",
@@ -231,10 +442,22 @@ class Shakapacker::Configuration
231
442
  )
232
443
  end
233
444
 
445
+ # Returns whether subresource integrity (SRI) is enabled
446
+ #
447
+ # When true, generates integrity hashes for script and link tags to
448
+ # protect against compromised CDNs or man-in-the-middle attacks.
449
+ #
450
+ # @return [Boolean] true if integrity checking is enabled
234
451
  def integrity
235
452
  fetch(:integrity)
236
453
  end
237
454
 
455
+ # Returns whether HTTP/2 Early Hints are enabled
456
+ #
457
+ # When true, sends Early Hints headers to start loading assets before
458
+ # the full response is ready.
459
+ #
460
+ # @return [Boolean] true if early hints are enabled
238
461
  def early_hints
239
462
  fetch(:early_hints)
240
463
  end