shakapacker 9.3.0.beta.4 → 9.3.0.beta.5

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.
@@ -95,13 +95,45 @@ module Shakapacker::Helper
95
95
  #
96
96
  # <%= javascript_pack_tag 'calendar' %>
97
97
  # <%= javascript_pack_tag 'map' %>
98
- def javascript_pack_tag(*names, defer: true, async: false, **options)
98
+ #
99
+ # Early Hints:
100
+ # By default, HTTP 103 Early Hints are sent automatically when this helper is called,
101
+ # allowing browsers to preload JavaScript assets in parallel with Rails rendering.
102
+ #
103
+ # <%= javascript_pack_tag 'application' %>
104
+ # # Automatically sends early hints for 'application' pack
105
+ #
106
+ # # Customize handling per pack:
107
+ # <%= javascript_pack_tag 'application', 'vendor',
108
+ # early_hints: { 'application' => 'preload', 'vendor' => 'prefetch' } %>
109
+ #
110
+ # # Disable early hints:
111
+ # <%= javascript_pack_tag 'application', early_hints: false %>
112
+ def javascript_pack_tag(*names, defer: true, async: false, early_hints: nil, **options)
99
113
  if @javascript_pack_tag_loaded
100
114
  raise "To prevent duplicated chunks on the page, you should call javascript_pack_tag only once on the page. " \
101
115
  "Please refer to https://github.com/shakacode/shakapacker/blob/main/README.md#view-helpers-javascript_pack_tag-and-stylesheet_pack_tag for the usage guide"
102
116
  end
103
117
 
118
+ # Collect all packs (queue + direct args)
104
119
  append_javascript_pack_tag(*names, defer: defer, async: async)
120
+ all_packs = javascript_pack_tag_queue.values.flatten.uniq
121
+
122
+ # Resolve effective early hints value (nil = use config default)
123
+ effective_hints = resolve_early_hints_value(early_hints, :javascript)
124
+
125
+ # Send early hints automatically if enabled
126
+ if early_hints_enabled? && effective_hints && effective_hints != "none"
127
+ hints_config = normalize_pack_hints(all_packs, effective_hints)
128
+ send_javascript_early_hints_internal(hints_config)
129
+ # Flush accumulated hints (sends the single 103 response)
130
+ flush_early_hints
131
+ elsif early_hints_debug_enabled?
132
+ store = early_hints_store
133
+ store[:debug_buffer] ||= []
134
+ store[:debug_buffer] << "<!-- Shakapacker Early Hints (JS): SKIPPED (early_hints: #{effective_hints.inspect}) -->"
135
+ end
136
+
105
137
  sync = sources_from_manifest_entrypoints(javascript_pack_tag_queue[:sync], type: :javascript)
106
138
  async = sources_from_manifest_entrypoints(javascript_pack_tag_queue[:async], type: :javascript) - sync
107
139
  deferred = sources_from_manifest_entrypoints(javascript_pack_tag_queue[:deferred], type: :javascript) - sync - async
@@ -109,6 +141,15 @@ module Shakapacker::Helper
109
141
  @javascript_pack_tag_loaded = true
110
142
 
111
143
  capture do
144
+ # Output debug buffer first
145
+ if early_hints_debug_enabled?
146
+ store = early_hints_store
147
+ if store[:debug_buffer] && store[:debug_buffer].any?
148
+ concat store[:debug_buffer].join("\n").html_safe
149
+ concat "\n"
150
+ end
151
+ end
152
+
112
153
  render_tags(async, :javascript, **options.dup.tap { |o| o[:async] = true })
113
154
  concat "\n" if async.any? && deferred.any?
114
155
  render_tags(deferred, :javascript, **options.dup.tap { |o| o[:defer] = true })
@@ -133,6 +174,80 @@ module Shakapacker::Helper
133
174
  end
134
175
  end
135
176
 
177
+ # Sends HTTP 103 Early Hints for specified packs with fine-grained control over
178
+ # JavaScript and CSS handling. This is the "raw" method for maximum flexibility.
179
+ #
180
+ # Use this in controller actions BEFORE expensive work (database queries, API calls)
181
+ # to maximize parallelism - the browser downloads assets while Rails processes the request.
182
+ #
183
+ # For simpler cases, use javascript_pack_tag and stylesheet_pack_tag which automatically
184
+ # send hints when called (combining queued + direct pack names).
185
+ #
186
+ # HTTP 103 Early Hints allows the server to send preliminary responses with Link headers
187
+ # before the final HTTP 200 response, enabling browsers to start downloading critical
188
+ # assets during the server's "think time".
189
+ #
190
+ # Timeline:
191
+ # 1. Browser requests page
192
+ # 2. Controller calls send_pack_early_hints (this method)
193
+ # 3. Server sends HTTP 103 with Link: headers
194
+ # 4. Browser starts downloading assets IN PARALLEL with step 5
195
+ # 5. Rails continues expensive work (queries, rendering)
196
+ # 6. Server sends HTTP 200 with full HTML
197
+ # 7. Assets already downloaded = faster page load
198
+ #
199
+ # Requires Rails 5.2+, HTTP/2, and server support (Puma 5+, nginx 1.13+).
200
+ # Gracefully degrades if not supported.
201
+ #
202
+ # References:
203
+ # - Rails API: https://api.rubyonrails.org/classes/ActionDispatch/Request.html#method-i-send_early_hints
204
+ # - HTTP 103 Spec: https://datatracker.ietf.org/doc/html/rfc8297
205
+ #
206
+ # Examples:
207
+ #
208
+ # # Controller pattern: send hints BEFORE expensive work
209
+ # def show
210
+ # send_pack_early_hints({
211
+ # "application" => { js: "preload", css: "preload" },
212
+ # "vendor" => { js: "prefetch", css: "none" }
213
+ # })
214
+ #
215
+ # # Browser now downloading assets while we do expensive work
216
+ # @posts = Post.includes(:comments, :author).where(complex_conditions)
217
+ # # ... more expensive work ...
218
+ # end
219
+ #
220
+ # # Supported handling values:
221
+ # # - "preload": High-priority, browser downloads immediately
222
+ # # - "prefetch": Low-priority, browser may download when idle
223
+ # # - "none" or false: Skip this asset type for this pack
224
+ def send_pack_early_hints(config)
225
+ return nil unless early_hints_supported? && early_hints_enabled?
226
+
227
+ # Accumulate both JS and CSS hints, then send ONCE
228
+ config.each do |pack_name, handlers|
229
+ # Accumulate JavaScript hints
230
+ js_handling = handlers[:js] || handlers["js"]
231
+ normalized_js = normalize_hint_value(js_handling)
232
+ if normalized_js
233
+ send_early_hints_internal({ pack_name.to_s => normalized_js }, type: :javascript)
234
+ end
235
+
236
+ # Accumulate CSS hints
237
+ css_handling = handlers[:css] || handlers["css"]
238
+ normalized_css = normalize_hint_value(css_handling)
239
+ if normalized_css
240
+ send_early_hints_internal({ pack_name.to_s => normalized_css }, type: :stylesheet)
241
+ end
242
+ end
243
+
244
+ # Flush the accumulated hints as a SINGLE 103 response
245
+ # (Browsers only process the first 103)
246
+ flush_early_hints
247
+
248
+ nil
249
+ end
250
+
136
251
  # Creates link tags that reference the css chunks from entrypoints when using split chunks API,
137
252
  # as compiled by webpack per the entries list in package/environments/base.js.
138
253
  # By default, this list is auto-generated to match everything in
@@ -158,15 +273,56 @@ module Shakapacker::Helper
158
273
  #
159
274
  # <%= stylesheet_pack_tag 'calendar' %>
160
275
  # <%= stylesheet_pack_tag 'map' %>
161
- def stylesheet_pack_tag(*names, **options)
276
+ #
277
+ # Early Hints:
278
+ # By default, HTTP 103 Early Hints are sent automatically when this helper is called,
279
+ # allowing browsers to preload CSS assets in parallel with Rails rendering.
280
+ #
281
+ # <%= stylesheet_pack_tag 'application' %>
282
+ # # Automatically sends early hints for 'application' pack
283
+ #
284
+ # # Customize handling per pack:
285
+ # <%= stylesheet_pack_tag 'application', 'vendor',
286
+ # early_hints: { 'application' => 'preload', 'vendor' => 'prefetch' } %>
287
+ #
288
+ # # Disable early hints:
289
+ # <%= stylesheet_pack_tag 'application', early_hints: false %>
290
+ def stylesheet_pack_tag(*names, early_hints: nil, **options)
162
291
  return "" if Shakapacker.inlining_css?
163
292
 
293
+ # Collect all packs (queue + direct args)
294
+ all_packs = ((@stylesheet_pack_tag_queue || []) + names).uniq
295
+
296
+ # Resolve effective early hints value (nil = use config default)
297
+ effective_hints = resolve_early_hints_value(early_hints, :stylesheet)
298
+
299
+ # Send early hints automatically if enabled
300
+ if early_hints_enabled? && effective_hints && effective_hints != "none"
301
+ hints_config = normalize_pack_hints(all_packs, effective_hints)
302
+ send_stylesheet_early_hints_internal(hints_config)
303
+ # Flush accumulated hints (sends the single 103 response)
304
+ flush_early_hints
305
+ elsif early_hints_debug_enabled?
306
+ store = early_hints_store
307
+ store[:debug_buffer] ||= []
308
+ store[:debug_buffer] << "<!-- Shakapacker Early Hints (CSS): SKIPPED (early_hints: #{effective_hints.inspect}) -->"
309
+ end
310
+
164
311
  requested_packs = sources_from_manifest_entrypoints(names, type: :stylesheet)
165
312
  appended_packs = available_sources_from_manifest_entrypoints(@stylesheet_pack_tag_queue || [], type: :stylesheet)
166
313
 
167
314
  @stylesheet_pack_tag_loaded = true
168
315
 
169
316
  capture do
317
+ # Output debug buffer first
318
+ if early_hints_debug_enabled?
319
+ store = early_hints_store
320
+ if store[:debug_buffer] && store[:debug_buffer].any?
321
+ concat store[:debug_buffer].join("\n").html_safe
322
+ concat "\n"
323
+ end
324
+ end
325
+
170
326
  render_tags(requested_packs | appended_packs, :stylesheet, options)
171
327
  end
172
328
  end
@@ -253,25 +409,264 @@ module Shakapacker::Helper
253
409
  def render_tags(sources, type, options)
254
410
  return unless sources.present? || type.present?
255
411
 
256
- sources.each.with_index do |source, index|
257
- tag_source = lookup_source(source)
412
+ # Temporarily disable Rails' built-in early hints for ALL tags
413
+ # Rails' javascript_include_tag and stylesheet_link_tag call request.send_early_hints
414
+ # We handle early hints ourselves before render_tags is called
415
+ patched = false
416
+ if respond_to?(:request) && request&.respond_to?(:send_early_hints)
417
+ request.define_singleton_method(:send_early_hints) { |*args| nil }
418
+ patched = true
419
+ end
420
+
421
+ begin
422
+ sources.each.with_index do |source, index|
423
+ # Duplicate options per iteration to avoid leaking integrity/crossorigin between tags
424
+ local_options = options.dup
425
+ tag_source = lookup_source(source)
426
+
427
+ if current_shakapacker_instance.config.integrity[:enabled]
428
+ integrity = lookup_integrity(source)
258
429
 
259
- if current_shakapacker_instance.config.integrity[:enabled]
260
- integrity = lookup_integrity(source)
430
+ if integrity.present?
431
+ local_options[:integrity] = integrity
432
+ local_options[:crossorigin] = current_shakapacker_instance.config.integrity[:cross_origin]
433
+ end
434
+ end
261
435
 
262
- if integrity.present?
263
- options[:integrity] = integrity
264
- options[:crossorigin] = current_shakapacker_instance.config.integrity[:cross_origin]
436
+ if type == :javascript
437
+ concat javascript_include_tag(tag_source, **local_options)
438
+ else
439
+ concat stylesheet_link_tag(tag_source, **local_options)
265
440
  end
441
+
442
+ concat "\n" unless index == sources.size - 1
443
+ end
444
+ ensure
445
+ # Restore original method by removing the singleton method
446
+ if patched
447
+ request.singleton_class.send(:remove_method, :send_early_hints)
266
448
  end
449
+ end
450
+ end
451
+
452
+ # Check if early hints are supported by Rails and the request object
453
+ def early_hints_supported?
454
+ request.respond_to?(:send_early_hints)
455
+ end
456
+
457
+ # Check if early hints are enabled in configuration
458
+ def early_hints_enabled?
459
+ config = current_shakapacker_instance.config.early_hints rescue nil
460
+ return false unless config
461
+ # Handle both symbol and string keys from YAML config
462
+ enabled = config[:enabled] || config["enabled"]
463
+ enabled == true
464
+ end
267
465
 
268
- if type == :javascript
269
- concat javascript_include_tag(tag_source, **options)
270
- else
271
- concat stylesheet_link_tag(tag_source, **options)
466
+ # Check if early hints debug mode is enabled
467
+ def early_hints_debug_enabled?
468
+ config = current_shakapacker_instance.config.early_hints rescue nil
469
+ return false unless config
470
+ # Handle both symbol and string keys from YAML config
471
+ debug = config[:debug] || config["debug"]
472
+ debug == true
473
+ end
474
+
475
+ # Resolve the effective early hints value
476
+ # If nil or true, read from config; otherwise use the provided value
477
+ def resolve_early_hints_value(early_hints, asset_type)
478
+ # If explicitly set to false or "none", use that
479
+ return "none" if early_hints == false || early_hints == "none"
480
+
481
+ # If nil or true, read from config
482
+ if early_hints.nil? || early_hints == true
483
+ config = current_shakapacker_instance.config.early_hints rescue nil
484
+ return "preload" unless config # Default fallback
485
+
486
+ # Get type-specific config (js/css), handling both symbol and string keys
487
+ type_key = asset_type == :javascript ? "js" : "css"
488
+ value = config[type_key.to_sym] || config[type_key]
489
+ return value || "preload" # Default to preload if not configured
490
+ end
491
+
492
+ # Return provided value as-is (will be normalized later)
493
+ early_hints
494
+ end
495
+
496
+ # Normalize pack hints into a hash mapping pack names to validated hint values
497
+ # Converts booleans, validates strings, and ensures only valid values are used
498
+ def normalize_pack_hints(packs, early_hints)
499
+ # Normalize the hint value(s)
500
+ if early_hints.is_a?(Hash)
501
+ # Per-pack configuration
502
+ packs.each_with_object({}) do |pack, result|
503
+ hint_value = early_hints[pack] || early_hints[pack.to_s] || early_hints[pack.to_sym]
504
+ result[pack] = normalize_hint_value(hint_value || "preload")
272
505
  end
506
+ else
507
+ # Single value for all packs
508
+ normalized_value = normalize_hint_value(early_hints)
509
+ packs.each_with_object({}) do |pack, result|
510
+ result[pack] = normalized_value
511
+ end
512
+ end
513
+ end
273
514
 
274
- concat "\n" unless index == sources.size - 1
515
+ # Normalize and validate a single hint value
516
+ # Converts false/nil to "none", downcases strings, validates against allowed values
517
+ def normalize_hint_value(value)
518
+ # Convert booleans and nil
519
+ return "none" if value == false || value.nil?
520
+ return "preload" if value == true
521
+
522
+ # Downcase and validate string
523
+ str_value = value.to_s.downcase.strip
524
+
525
+ # Only allow valid values
526
+ valid_values = ["preload", "prefetch", "none"]
527
+ valid_values.include?(str_value) ? str_value : "none"
528
+ end
529
+
530
+ # Generate reason why early hints were skipped
531
+ def early_hints_skip_reason
532
+ unless early_hints_supported?
533
+ return "Rails request.send_early_hints not available (requires Rails 5.2+)"
534
+ end
535
+ unless early_hints_enabled?
536
+ return "early_hints.enabled is false in config/shakapacker.yml"
537
+ end
538
+ "Unknown reason"
539
+ end
540
+
541
+ # Build a Link header value for early hints
542
+ # Takes the already-resolved source_path to avoid duplicate lookup_source calls
543
+ def build_link_header(source_path, source, as:, rel: "preload")
544
+ parts = ["<#{source_path}>", "rel=#{rel}", "as=#{as}"]
545
+
546
+ # Add crossorigin and integrity if enabled (consistent with render_tags)
547
+ if current_shakapacker_instance.config.integrity[:enabled]
548
+ integrity = lookup_integrity(source)
549
+ if integrity.present?
550
+ parts << "integrity=\"#{integrity}\""
551
+ # Use configured cross_origin value, consistent with render_tags
552
+ cross_origin = current_shakapacker_instance.config.integrity[:cross_origin]
553
+ parts << "crossorigin=\"#{cross_origin}\""
554
+ end
555
+ elsif ["script", "style", "font"].include?(as)
556
+ # When integrity not enabled, scripts, styles, and fonts still need crossorigin for CORS
557
+ parts << "crossorigin=\"anonymous\""
275
558
  end
559
+
560
+ parts.join("; ")
561
+ end
562
+
563
+ # Returns the shared early hints storage from request.env
564
+ # This ensures state is shared across controller/view contexts
565
+ def early_hints_store
566
+ request.env["shakapacker.early_hints"] ||= {}
567
+ end
568
+
569
+ # Internal method to accumulate and send early hints
570
+ # Sends only ONE 103 response (browsers ignore subsequent ones)
571
+ # config: { "application" => "preload", "vendor" => "prefetch" }
572
+ # type: :javascript or :stylesheet
573
+ def send_early_hints_internal(config, type:)
574
+ return unless early_hints_supported?
575
+
576
+ # Use request.env as shared storage across controller/view contexts
577
+ # This prevents duplicate packs and ensures debug info is preserved
578
+ store = early_hints_store
579
+ store[:sent_packs] ||= { javascript: {}, stylesheet: {} }
580
+ store[:link_buffer] ||= []
581
+ store[:debug_buffer] ||= []
582
+
583
+ # If we've already sent the 103 response, just track for debug
584
+ if store[:http_103_sent]
585
+ if early_hints_debug_enabled?
586
+ store[:debug_buffer] << "<!-- Shakapacker Early Hints (#{type.upcase}): Not sent (103 already sent) -->"
587
+ store[:debug_buffer] << "<!-- Packs: #{config.keys.join(', ')} -->"
588
+ end
589
+ return
590
+ end
591
+
592
+ # Filter to only new packs for THIS type, and skip "none" values
593
+ new_hints = config.reject { |pack, handling| store[:sent_packs][type].key?(pack) || handling == "none" }
594
+
595
+ if early_hints_debug_enabled? && new_hints.empty?
596
+ store[:debug_buffer] << "<!-- Shakapacker Early Hints (#{type.upcase}): All packs already queued -->"
597
+ end
598
+
599
+ # Accumulate Link headers for this type
600
+ asset_type = type == :javascript ? "script" : "style"
601
+ new_hints.each do |pack_name, handling|
602
+ # Skip if handling is "none" (extra safety check)
603
+ next if handling == "none"
604
+
605
+ begin
606
+ sources = available_sources_from_manifest_entrypoints([pack_name], type: type)
607
+ sources.each do |source|
608
+ source_path = lookup_source(source)
609
+ store[:link_buffer] << build_link_header(source_path, source, as: asset_type, rel: handling)
610
+ end
611
+ # Mark pack as queued for THIS type
612
+ store[:sent_packs][type][pack_name] = handling
613
+ rescue Shakapacker::Manifest::MissingEntryError, NoMethodError => e
614
+ Rails.logger.debug { "Early hints: skipping pack '#{pack_name}' - #{e.class}: #{e.message}" }
615
+ end
616
+ end
617
+
618
+ # Note: We DON'T flush here - caller must call flush_early_hints explicitly
619
+ # This allows accumulating multiple calls (JS + CSS) before sending ONE 103
620
+ end
621
+
622
+ # Send accumulated early hints as a SINGLE 103 response
623
+ # Browsers only process the first 103, so we send everything at once
624
+ def flush_early_hints
625
+ store = early_hints_store
626
+
627
+ # Guard against multiple flushes - only send once per request
628
+ return if store[:http_103_sent]
629
+ return if store[:link_buffer].nil? || store[:link_buffer].empty?
630
+
631
+ # Check if response is already committed (headers already sent)
632
+ if respond_to?(:response) && response&.committed?
633
+ Rails.logger.debug { "Early hints: Cannot send 103 - response already committed" }
634
+ return
635
+ end
636
+
637
+ # Set flag BEFORE sending to prevent race conditions
638
+ store[:http_103_sent] = true
639
+
640
+ # Send the 103 response with error handling
641
+ begin
642
+ request.send_early_hints({ "Link" => store[:link_buffer].join(", ") })
643
+ rescue => e
644
+ Rails.logger.error { "Early hints: Failed to send 103 - #{e.class}: #{e.message}" }
645
+ end
646
+
647
+ if early_hints_debug_enabled?
648
+ all_packs = (store[:sent_packs][:javascript].keys + store[:sent_packs][:stylesheet].keys).uniq
649
+ store[:debug_buffer] << "<!-- Shakapacker Early Hints: HTTP/1.1 103 SENT -->"
650
+ store[:debug_buffer] << "<!-- Total Links: #{store[:link_buffer].size} -->"
651
+ store[:debug_buffer] << "<!-- Packs: #{all_packs.join(', ')} -->"
652
+ store[:debug_buffer] << "<!-- JS Packs: #{store[:sent_packs][:javascript].keys.join(', ')} -->"
653
+ store[:debug_buffer] << "<!-- CSS Packs: #{store[:sent_packs][:stylesheet].keys.join(', ')} -->"
654
+ store[:debug_buffer] << "<!-- Headers: -->"
655
+ store[:link_buffer].each do |link|
656
+ store[:debug_buffer] << "<!-- #{link} -->"
657
+ end
658
+ store[:debug_buffer] << "<!-- Note: Browsers only process the FIRST 103 response -->"
659
+ store[:debug_buffer] << "<!-- Note: Puma only supports HTTP/1.1 Early Hints (not HTTP/2) -->"
660
+ end
661
+ end
662
+
663
+ # Wrapper for JavaScript early hints
664
+ def send_javascript_early_hints_internal(config)
665
+ send_early_hints_internal(config, type: :javascript)
666
+ end
667
+
668
+ # Wrapper for stylesheet early hints
669
+ def send_stylesheet_early_hints_internal(config)
670
+ send_early_hints_internal(config, type: :stylesheet)
276
671
  end
277
672
  end
@@ -39,6 +39,10 @@ class Shakapacker::Engine < ::Rails::Engine
39
39
  end
40
40
  end
41
41
 
42
+ # Early hints are handled automatically by javascript_pack_tag and stylesheet_pack_tag helpers
43
+ # when early_hints.enabled: true in shakapacker.yml
44
+ # See docs/early_hints_new_api.md for usage
45
+
42
46
  initializer "shakapacker.logger" do
43
47
  config.after_initialize do
44
48
  if ::Rails.logger.respond_to?(:tagged)
@@ -1,4 +1,4 @@
1
1
  module Shakapacker
2
2
  # Change the version in package.json too, please!
3
- VERSION = "9.3.0.beta.4".freeze
3
+ VERSION = "9.3.0.beta.5".freeze
4
4
  end
@@ -226,9 +226,8 @@ export class BuildValidator {
226
226
 
227
227
  if (isHMR) {
228
228
  return this.validateHMRBuild(build, appRoot, bundler)
229
- } else {
230
- return this.validateStaticBuild(build, appRoot, bundler)
231
229
  }
230
+ return this.validateStaticBuild(build, appRoot, bundler)
232
231
  }
233
232
 
234
233
  /**
@@ -1285,7 +1285,8 @@ function formatConfig(
1285
1285
  appRoot
1286
1286
  })
1287
1287
  return serializer.serialize(config, metadata)
1288
- } else if (options.format === "json") {
1288
+ }
1289
+ if (options.format === "json") {
1289
1290
  const jsonReplacer = (key: string, value: any): any => {
1290
1291
  if (typeof value === "function") {
1291
1292
  return `[Function: ${value.name || "anonymous"}]`
data/package-lock.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "shakapacker",
3
- "version": "9.3.0-beta.4",
3
+ "version": "9.3.0-beta.5",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "shakapacker",
9
- "version": "9.3.0-beta.4",
9
+ "version": "9.3.0-beta.5",
10
10
  "license": "MIT",
11
11
  "dependencies": {
12
12
  "js-yaml": "^4.1.0",
data/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "shakapacker",
3
- "version": "9.3.0-beta.4",
3
+ "version": "9.3.0-beta.5",
4
4
  "description": "Use webpack to manage app-like JavaScript modules in Rails",
5
5
  "homepage": "https://github.com/shakacode/shakapacker",
6
6
  "bugs": {
@@ -41,5 +41,4 @@ files.forEach((file) => {
41
41
  fs.writeFileSync(file, content, "utf8")
42
42
  })
43
43
 
44
- // eslint-disable-next-line no-console
45
44
  console.log(`Removed "use strict" from ${files.length} files`)
@@ -19,6 +19,7 @@ const babelConfig = require("../../../package/rules/babel")
19
19
 
20
20
  // Skip tests if babel config is not available (not the active transpiler)
21
21
  if (!babelConfig) {
22
+ // eslint-disable-next-line jest/no-disabled-tests
22
23
  describe.skip("babel - skipped", () => {
23
24
  test.todo("skipped because babel is not the active transpiler")
24
25
  })
@@ -19,6 +19,7 @@ const swcConfig = require("../../../package/rules/swc")
19
19
 
20
20
  // Skip tests if swc config is not available (not the active transpiler)
21
21
  if (!swcConfig) {
22
+ // eslint-disable-next-line jest/no-disabled-tests
22
23
  describe.skip("swc - skipped", () => {
23
24
  test.todo("skipped because swc is not the active transpiler")
24
25
  })
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: shakapacker
3
3
  version: !ruby/object:Gem::Version
4
- version: 9.3.0.beta.4
4
+ version: 9.3.0.beta.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - David Heinemeier Hansson
@@ -180,6 +180,9 @@ files:
180
180
  - docs/customizing_babel_config.md
181
181
  - docs/deployment.md
182
182
  - docs/developing_shakapacker.md
183
+ - docs/early_hints.md
184
+ - docs/early_hints_new_api.md
185
+ - docs/feature_testing.md
183
186
  - docs/optional-peer-dependencies.md
184
187
  - docs/peer-dependencies.md
185
188
  - docs/precompile_hook.md
@@ -382,7 +385,7 @@ homepage: https://github.com/shakacode/shakapacker
382
385
  licenses:
383
386
  - MIT
384
387
  metadata:
385
- source_code_uri: https://github.com/shakacode/shakapacker/tree/v9.3.0.beta.4
388
+ source_code_uri: https://github.com/shakacode/shakapacker/tree/v9.3.0.beta.5
386
389
  rdoc_options: []
387
390
  require_paths:
388
391
  - lib