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.
@@ -0,0 +1,492 @@
1
+ # Feature Testing Guide
2
+
3
+ This guide shows how to manually verify that Shakapacker features are working correctly in your application.
4
+
5
+ ## Table of Contents
6
+
7
+ - [HTTP 103 Early Hints](#http-103-early-hints)
8
+ - [Asset Compilation](#asset-compilation)
9
+ - [Code Splitting](#code-splitting)
10
+ - [Subresource Integrity (SRI)](#subresource-integrity-sri)
11
+ - [Source Maps](#source-maps)
12
+ - [Development Server](#development-server)
13
+
14
+ ## HTTP 103 Early Hints
15
+
16
+ ### Prerequisites
17
+
18
+ - Rails 5.2+
19
+ - HTTP/2-capable server (Puma 5+ recommended)
20
+ - Modern browser (Chrome/Edge/Firefox 103+, Safari 16.4+)
21
+
22
+ ### ⚠️ Development Mode Limitations
23
+
24
+ **Early hints require HTTP/2 and will NOT work in standard Rails development mode**, which uses HTTP/1.1 by default.
25
+
26
+ **Why localhost testing doesn't work:**
27
+
28
+ - Early hints require HTTP/2
29
+ - HTTP/2 requires HTTPS/TLS (not `http://`)
30
+ - Plain `http://localhost` uses HTTP/1.1
31
+ - Early hints are silently ignored on HTTP/1.1
32
+
33
+ **Debug Mode:** Enable `debug: true` in config to see HTML comments showing what hints were sent (or why they weren't):
34
+
35
+ ```yaml
36
+ # config/shakapacker.yml
37
+ development:
38
+ early_hints:
39
+ enabled: true
40
+ debug: true # Outputs debug info as HTML comments
41
+ ```
42
+
43
+ **Testing recommendation:** Use Method 1 (Browser DevTools) or Method 2 (curl) on production/staging environments with HTTPS enabled. You should see BOTH `HTTP/2 103` (early hints) and `HTTP/2 200` (final response).
44
+
45
+ ### Method 1: Browser DevTools (Recommended)
46
+
47
+ 1. **Enable early hints in config:**
48
+
49
+ ```yaml
50
+ # config/shakapacker.yml
51
+ production:
52
+ early_hints:
53
+ enabled: true
54
+ ```
55
+
56
+ 2. **Open Chrome DevTools** (F12 or Cmd+Option+I)
57
+
58
+ 3. **Go to Network tab** and reload your page
59
+
60
+ 4. **Look for the initial document request** (usually first row)
61
+
62
+ 5. **Check the Status column** - you should see:
63
+ - `103 Early Hints` (shown briefly before the final response)
64
+ - Followed by `200 OK` for the final HTML
65
+
66
+ 6. **Verify Link headers:**
67
+ - Click on the document request
68
+ - Go to the "Headers" tab
69
+ - Scroll to "Response Headers" section
70
+ - Look for `Link:` headers with `rel=preload` or `rel=prefetch`
71
+
72
+ **Expected output:**
73
+
74
+ ```
75
+ Link: </packs/application-abc123.js>; rel=preload; as=script; crossorigin="anonymous"
76
+ Link: </packs/application-xyz789.css>; rel=preload; as=style; crossorigin="anonymous"
77
+ ```
78
+
79
+ ### Method 2: curl (Command Line)
80
+
81
+ **Test early hints with curl (requires HTTPS/HTTP2):**
82
+
83
+ ```bash
84
+ # Production/staging with HTTPS
85
+ curl -v --http2 https://your-app.com 2>&1 | grep -A5 "< HTTP"
86
+
87
+ # Look for:
88
+ # < HTTP/2 103
89
+ # < link: </packs/...>; rel=preload
90
+ # < HTTP/2 200
91
+ ```
92
+
93
+ **⚠️ Local testing limitations:**
94
+
95
+ ```bash
96
+ # This will NOT show early hints (returns HTTP/1.1):
97
+ RAILS_ENV=production bundle exec rails server
98
+ curl -v --http2 http://localhost:3000 2>&1 | grep -A5 "< HTTP"
99
+ # Output: < HTTP/1.1 200 OK (no 103 status)
100
+
101
+ # Why: Puma requires SSL certificates for HTTP/2
102
+ # Early hints need HTTP/2, which needs HTTPS
103
+ ```
104
+
105
+ **Expected output:**
106
+
107
+ ```
108
+ < HTTP/2 103
109
+ < link: </packs/application-abc123.js>; rel=preload; as=script; crossorigin="anonymous"
110
+ < link: </packs/application-xyz789.css>; rel=preload; as=style; crossorigin="anonymous"
111
+ <
112
+ < HTTP/2 200
113
+ < content-type: text/html; charset=utf-8
114
+ ```
115
+
116
+ ### Method 3: Check HTML Source
117
+
118
+ Early hints don't appear in HTML source (they're sent as HTTP headers before HTML). However, you can verify the assets exist:
119
+
120
+ ```html
121
+ <!-- View page source and look for these tags in <head> or before </body> -->
122
+ <script src="/packs/application-abc123.js"></script>
123
+ <link rel="stylesheet" href="/packs/application-xyz789.css" />
124
+ ```
125
+
126
+ The asset filenames in early hints should match those in your HTML.
127
+
128
+ ### Troubleshooting Early Hints
129
+
130
+ **Not seeing 103 status?**
131
+
132
+ 1. **Enable debug mode to see what's happening:**
133
+
134
+ ```yaml
135
+ # config/shakapacker.yml
136
+ production: # or development
137
+ early_hints:
138
+ enabled: true
139
+ debug: true # Shows debug info as HTML comments
140
+ ```
141
+
142
+ View page source and look for `<!-- Shakapacker Early Hints Debug -->` comments showing what hints were sent or why they were skipped.
143
+
144
+ 2. **Reverse proxies and CDNs often strip 103 responses:**
145
+
146
+ **Most common cause**: If debug mode shows hints are being sent but you don't see `HTTP/2 103` in curl or DevTools, your reverse proxy or CDN is likely stripping the 103 status code before it reaches the client.
147
+
148
+ Common culprits:
149
+ - Control Plane (cpln.app)
150
+ - Some Cloudflare configurations
151
+ - nginx without explicit early hints support
152
+ - AWS ALB/ELB
153
+ - Other load balancers and proxies
154
+
155
+ **How to fix proxy stripping:**
156
+
157
+ **nginx** - Enable early hints support:
158
+
159
+ ```nginx
160
+ # nginx.conf
161
+ http {
162
+ # Enable HTTP/2
163
+ server {
164
+ listen 443 ssl http2;
165
+
166
+ # Pass through early hints (nginx 1.13+)
167
+ proxy_pass_header Link;
168
+
169
+ location / {
170
+ proxy_pass http://rails_backend;
171
+ proxy_http_version 1.1;
172
+ }
173
+ }
174
+ }
175
+ ```
176
+
177
+ **Cloudflare** - Early hints are supported but must be enabled:
178
+ - Go to Speed > Optimization in your Cloudflare dashboard
179
+ - Enable "Early Hints"
180
+ - Note: Only available on paid plans (Pro, Business, Enterprise)
181
+
182
+ **AWS ALB/ELB** - Does NOT support HTTP/2 103:
183
+ - AWS load balancers strip 103 responses
184
+ - **Workaround**: Deploy without ALB/ELB, or accept Link headers in 200 response
185
+ - Alternative: Use CloudFront with origin that supports 103
186
+
187
+ **Control Plane (cpln.app)** - Appears to strip 103:
188
+ - Control Plane supports HTTP/2 by default but early hints (103) don't appear to pass through
189
+ - No documented configuration option for early hints passthrough
190
+ - **Contact Control Plane support** if you need early hints support for your application
191
+ - **Workaround**: Early hints will work server-side but won't be visible to clients
192
+ - Link headers may still be included in 200 response
193
+
194
+ **General workaround when proxy strips 103:**
195
+ - Rails still sends Link headers in the 200 response
196
+ - Browsers can use these for next-page prefetch (not early hints benefit)
197
+ - Consider if early hints are worth the complexity for your setup
198
+ - Use debug mode to verify Rails is sending hints correctly
199
+
200
+ 3. **Check server supports HTTP/2 and early hints:**
201
+
202
+ ```bash
203
+ # Puma version (need 5+)
204
+ bundle exec puma --version
205
+ ```
206
+
207
+ 4. **Verify config is enabled:**
208
+
209
+ ```bash
210
+ # In Rails console
211
+ Shakapacker.config.early_hints
212
+ # Should return: { enabled: true, css: "preload", js: "preload", debug: false }
213
+ ```
214
+
215
+ 5. **Check Rails log for debug messages:**
216
+
217
+ ```bash
218
+ tail -f log/production.log | grep -i "early hints"
219
+ ```
220
+
221
+ 6. **Verify your server uses HTTP/2:**
222
+ ```bash
223
+ curl -I --http2 https://your-app.com | grep -i "HTTP/2"
224
+ ```
225
+
226
+ ## Asset Compilation
227
+
228
+ ### Verify Assets Compile Successfully
229
+
230
+ **Check manifest.json:**
231
+
232
+ ```bash
233
+ # Development
234
+ cat public/packs/manifest.json | jq .
235
+
236
+ # Production (after precompile)
237
+ cat public/packs/manifest.json | jq '.entrypoints'
238
+ ```
239
+
240
+ **Expected output:**
241
+
242
+ ```json
243
+ {
244
+ "entrypoints": {
245
+ "application": {
246
+ "assets": {
247
+ "js": [
248
+ "/packs/vendors~application-abc123.chunk.js",
249
+ "/packs/application-xyz789.js"
250
+ ],
251
+ "css": ["/packs/application-abc123.chunk.css"]
252
+ }
253
+ }
254
+ }
255
+ }
256
+ ```
257
+
258
+ **Verify assets exist on disk:**
259
+
260
+ ```bash
261
+ ls -lh public/packs/
262
+ # Should see .js, .css, .map files with hashed names
263
+ ```
264
+
265
+ ### Check HTML References
266
+
267
+ **View page source and verify pack tags:**
268
+
269
+ ```html
270
+ <!-- Should see hashed filenames -->
271
+ <link rel="stylesheet" href="/packs/application-abc123.css" />
272
+ <script src="/packs/application-xyz789.js"></script>
273
+ ```
274
+
275
+ ## Code Splitting
276
+
277
+ ### Verify Chunks Are Created
278
+
279
+ **Check manifest.json for chunks:**
280
+
281
+ ```bash
282
+ cat public/packs/manifest.json | jq '.entrypoints.application.assets.js'
283
+ ```
284
+
285
+ **Expected output (with code splitting):**
286
+
287
+ ```json
288
+ [
289
+ "/packs/vendors~application-abc123.chunk.js", // Vendor chunk
290
+ "/packs/application-xyz789.js" // Main chunk
291
+ ]
292
+ ```
293
+
294
+ **View Network tab in DevTools:**
295
+
296
+ - Should see multiple `.chunk.js` files loading
297
+ - Chunks load in order (vendors first, then application code)
298
+
299
+ ## Subresource Integrity (SRI)
300
+
301
+ ### Verify Integrity Attributes
302
+
303
+ **Enable SRI in config:**
304
+
305
+ ```yaml
306
+ # config/shakapacker.yml
307
+ production:
308
+ integrity:
309
+ enabled: true
310
+ ```
311
+
312
+ **Check manifest.json for integrity hashes:**
313
+
314
+ ```bash
315
+ cat public/packs/manifest.json | jq '.application.js'
316
+ ```
317
+
318
+ **Expected output:**
319
+
320
+ ```json
321
+ {
322
+ "src": "/packs/application-abc123.js",
323
+ "integrity": "sha384-oqVuAfXRKap7fdgcCY5uykM6+R9GqQ8K/uxy9rx7HNQlGYl1kPzQho1wx4JwY8wC"
324
+ }
325
+ ```
326
+
327
+ **Check HTML for integrity attribute:**
328
+
329
+ ```html
330
+ <!-- View page source -->
331
+ <script
332
+ src="/packs/application-abc123.js"
333
+ integrity="sha384-oqVuAfXRKap7fdgcCY5uykM6+R9GqQ8K/uxy9rx7HNQlGYl1kPzQho1wx4JwY8wC"
334
+ crossorigin="anonymous"
335
+ ></script>
336
+ ```
337
+
338
+ ### Verify SRI Works
339
+
340
+ **Break the integrity (for testing):**
341
+
342
+ 1. Edit `public/packs/application-xyz789.js` (add a space)
343
+ 2. Reload page
344
+ 3. **Expected:** Browser console shows SRI error:
345
+ ```
346
+ Failed to find a valid digest in the 'integrity' attribute
347
+ ```
348
+
349
+ ## Source Maps
350
+
351
+ ### Verify Source Maps Generate
352
+
353
+ **Check for .map files:**
354
+
355
+ ```bash
356
+ ls -lh public/packs/*.map
357
+ # Should see .js.map and .css.map files
358
+ ```
359
+
360
+ **Check HTML references source maps:**
361
+
362
+ ```bash
363
+ curl http://localhost:3000/packs/application-xyz789.js | tail -5
364
+ ```
365
+
366
+ **Expected output:**
367
+
368
+ ```javascript
369
+ //# sourceMappingURL=application-xyz789.js.map
370
+ ```
371
+
372
+ ### Verify Source Maps Work in DevTools
373
+
374
+ 1. **Open DevTools** → Sources tab
375
+ 2. **Find your source files** under `webpack://` or `src/`
376
+ 3. **Set a breakpoint** in your original source code
377
+ 4. **Trigger the code** - debugger should stop at your source, not compiled output
378
+
379
+ ## Development Server
380
+
381
+ ### Verify Dev Server Running
382
+
383
+ **Check server status:**
384
+
385
+ ```bash
386
+ # Start dev server
387
+ ./bin/shakapacker-dev-server
388
+
389
+ # In another terminal, check it's running
390
+ curl http://localhost:3035
391
+ # Should return: "Shakapacker is running"
392
+ ```
393
+
394
+ **Check Rails connects to dev server:**
395
+
396
+ ```bash
397
+ # Start Rails
398
+ ./bin/dev # or rails server
399
+
400
+ # Check Rails log for:
401
+ [Shakapacker] Compiling...
402
+ [Shakapacker] Compiled all packs in /app/public/packs
403
+ ```
404
+
405
+ **Verify hot reloading:**
406
+
407
+ 1. Edit a JavaScript file in `app/javascript/`
408
+ 2. Save the file
409
+ 3. Browser should automatically reload (if HMR configured)
410
+ 4. Or check terminal shows recompile message
411
+
412
+ ### Troubleshooting Dev Server
413
+
414
+ **Connection refused?**
415
+
416
+ ```bash
417
+ # Check dev_server.yml
418
+ cat config/shakapacker.yml | grep -A10 "dev_server"
419
+
420
+ # Verify settings:
421
+ # host: localhost
422
+ # port: 3035
423
+ # https: false
424
+ ```
425
+
426
+ **Test connection manually:**
427
+
428
+ ```bash
429
+ curl http://localhost:3035/packs/application.js
430
+ # Should return JavaScript code (not 404)
431
+ ```
432
+
433
+ ## Testing Checklist
434
+
435
+ Use this checklist to verify a complete Shakapacker setup:
436
+
437
+ - [ ] **Assets compile:** `bundle exec rails assets:precompile` succeeds
438
+ - [ ] **Manifest exists:** `public/packs/manifest.json` contains entrypoints
439
+ - [ ] **Assets load:** Page loads without 404s for pack files
440
+ - [ ] **Code splitting works:** Multiple chunks load in Network tab
441
+ - [ ] **Source maps work:** Can debug original source in DevTools
442
+ - [ ] **Dev server runs:** `./bin/shakapacker-dev-server` starts successfully
443
+ - [ ] **SRI enabled (if configured):** HTML contains `integrity` attributes
444
+ - [ ] **Early hints work (if configured):** DevTools shows 103 status
445
+
446
+ ## Common Issues
447
+
448
+ ### Assets Return 404
449
+
450
+ **Check manifest:**
451
+
452
+ ```bash
453
+ cat public/packs/manifest.json | jq .
454
+ ```
455
+
456
+ **Recompile:**
457
+
458
+ ```bash
459
+ bundle exec rails assets:precompile
460
+ ```
461
+
462
+ ### Old Assets Cached
463
+
464
+ **Clear public/packs:**
465
+
466
+ ```bash
467
+ rm -rf public/packs
468
+ bundle exec rails assets:precompile
469
+ ```
470
+
471
+ ### Dev Server Won't Start
472
+
473
+ **Check port not in use:**
474
+
475
+ ```bash
476
+ lsof -i :3035
477
+ # Kill process if needed
478
+ kill -9 <PID>
479
+ ```
480
+
481
+ **Check dev_server config:**
482
+
483
+ ```bash
484
+ cat config/shakapacker.yml | grep -A10 dev_server
485
+ ```
486
+
487
+ ## Additional Resources
488
+
489
+ - [Configuration Guide](configuration.md)
490
+ - [Early Hints Guide](early_hints.md)
491
+ - [Subresource Integrity Guide](subresource_integrity.md)
492
+ - [Troubleshooting Guide](troubleshooting.md)
@@ -86,11 +86,30 @@ default: &default
86
86
  # https://developer.mozilla.org/en-US/docs/Web/Security/Subresource_Integrity#cross-origin_resource_sharing_and_subresource_integrity
87
87
  cross_origin: "anonymous"
88
88
 
89
+ # HTTP 103 Early Hints support for faster asset loading
90
+ # Sends Link headers to browsers so they can preload assets while Rails is rendering
91
+ # See docs/early_hints_new_api.md for setup instructions and requirements
92
+ # https://api.rubyonrails.org/classes/ActionDispatch/Request.html#method-i-send_early_hints
93
+ early_hints:
94
+ enabled: false
95
+ # css: "preload" # 'preload' | 'prefetch' | 'none' - default: 'preload'
96
+ # js: "preload" # 'preload' | 'prefetch' | 'none' - default: 'preload'
97
+ # debug: false # Output early hints info as HTML comments for troubleshooting
98
+
89
99
  development:
90
100
  <<: *default
91
101
  compile: true
92
102
  compiler_strategy: mtime
93
103
 
104
+ # Early hints disabled by default in development
105
+ # To enable: Set enabled: true AND start Puma with: bundle exec puma --early-hints
106
+ # See docs/early_hints_new_api.md for setup instructions
107
+ # early_hints:
108
+ # enabled: true
109
+ # css: "preload"
110
+ # js: "preload"
111
+ # debug: true
112
+
94
113
  # Reference: https://webpack.js.org/configuration/dev-server/
95
114
  # Keys not described there are documented inline and in https://github.com/shakacode/shakapacker/
96
115
  dev_server:
@@ -150,3 +169,11 @@ production:
150
169
 
151
170
  # Cache manifest.json for performance
152
171
  cache_manifest: true
172
+
173
+ # Early hints disabled by default. See docs/early_hints_new_api.md before enabling.
174
+ # Requires proper server configuration (Puma + HTTP/2 proxy like nginx, Thruster, or Control Plane)
175
+ early_hints:
176
+ enabled: false
177
+ # css: "preload"
178
+ # js: "preload"
179
+ # debug: false
@@ -235,6 +235,10 @@ class Shakapacker::Configuration
235
235
  fetch(:integrity)
236
236
  end
237
237
 
238
+ def early_hints
239
+ fetch(:early_hints)
240
+ end
241
+
238
242
  private
239
243
  def validate_output_paths!
240
244
  # Skip validation if already validated to avoid redundant checks