shakapacker 9.3.0.beta.2 → 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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d196f7ff4fd6270c0a4739f62ed17ee202eef663222018dc0b031b7dfb8ec015
4
- data.tar.gz: cb645bae3cb677c7b7f7e35164d99b779dfb92d7d6a975204ac0fcae71b56f40
3
+ metadata.gz: 9db05ecb02b4491f31eb4ec2374057933be5cf90a09b6dded781c036ff8e494e
4
+ data.tar.gz: a8f9b04812aff8a73275044f61a1ecbc096c5131a3bca69d5b75e292c1c31064
5
5
  SHA512:
6
- metadata.gz: ee177b62cc41abd5fbd460d34f8f8dfe387385152cc683aed5034fe3fd67050043dd3cd2fe32f09f06735ff28a4e71ec6f1f4f945e6ea582dbba06e0883dbb1d
7
- data.tar.gz: dcb85543ec034ede52cf91ed5e36ab5a987e8fb485d54c857fd1762f133252a827d760ac92dd36b9973897e30c3ab1d89f64bacd5761ffe6815b75c990c2c2f9
6
+ metadata.gz: 88f63fdaaed2cfad42f000d97e08fec78dddaa24b304dd23ae515ba24b5b68845e33115adf13994f0a59f85b6be4003a442e8d5f88a1a9295484ca0b31e07fc1
7
+ data.tar.gz: 59069f26686a609a9df9994ec63a1cbc5905d18abbb7379c0460913f16ac58247e760d97eecc544a31a86e212d6af1d171b99f462f4b60b937d0da81d3415a7f
data/CHANGELOG.md CHANGED
@@ -11,6 +11,26 @@
11
11
 
12
12
  Changes since the last non-beta release.
13
13
 
14
+ ### Added
15
+
16
+ - **HTTP 103 Early Hints support** for faster asset loading. [PR #722](https://github.com/shakacode/shakapacker/pull/722) by [justin808](https://github.com/justin808). Fixes [#721](https://github.com/shakacode/shakapacker/issues/721).
17
+ - **Automatic sending**: Early hints are sent automatically when `early_hints: enabled: true` in `shakapacker.yml`
18
+ - **Per-page configuration**: Configure hints per-controller/action with `preload`/`prefetch`/`none` options
19
+ - **Hero image/video preloading**: Use Rails' built-in `preload_link_tag` (automatically sends early hints)
20
+ - **Zero-config upgrade**: No changes to layouts or views needed - just enable the config!
21
+ - Works seamlessly with existing `append_javascript_pack_tag` / `append_stylesheet_pack_tag` pattern
22
+ - Automatically discovers packs from queues populated by views/partials
23
+ - New `configure_pack_early_hints` class method for controller-level configuration
24
+ - New `skip_send_pack_early_hints` helper to opt-out for specific controllers (e.g., JSON APIs)
25
+ - Optional manual control: `configure_early_hints` can be called in controllers or views
26
+ - Added `early_hints:` option to `javascript_pack_tag` for per-tag control
27
+ - New `early_hints` configuration in `shakapacker.yml` with per-environment settings (`enabled: false` by default)
28
+ - Requires Rails 5.2+ and HTTP/2-capable server (e.g., Puma 5+)
29
+ - Browser support: All modern browsers (Chrome/Edge/Firefox 103+, Safari 16.4+)
30
+ - Gracefully degrades if not supported
31
+ - **Performance note**: May improve or hurt page load performance depending on content - careful testing advised
32
+ - See [Early Hints Guide](docs/early_hints.md) for detailed usage and advanced patterns
33
+
14
34
  ## [v9.3.0-beta.0] - October 13, 2025
15
35
 
16
36
  ### Added
data/CLAUDE.md CHANGED
@@ -27,6 +27,19 @@
27
27
  - Create small, focused PRs that are easy to review
28
28
  - Always create a PR immediately after pushing changes
29
29
 
30
+ ## Changelog
31
+
32
+ - **Update CHANGELOG.md for user-visible changes only**
33
+ - User-visible changes include: new features, bug fixes, breaking changes, deprecations, performance improvements
34
+ - **Do NOT add changelog entries for**: linting fixes, code formatting, internal refactoring, test updates, documentation fixes
35
+ - Non-user-visible changes don't need changelog entries even if they modify code
36
+ - **Format requirements**:
37
+ - Always link to the PR: `[PR #123](https://github.com/shakacode/shakapacker/pull/123)`
38
+ - Always link to the author: `by [username](https://github.com/username)`
39
+ - Keep formatting consistent with existing entries
40
+ - When releasing a version, update the version diff links at the bottom of CHANGELOG.md
41
+ - **For breaking changes**: Use bold formatting and link to migration documentation (e.g., `**Breaking**: Description. See [Migration Guide](docs/vX_upgrade.md)`)
42
+
30
43
  ## Shakapacker-Specific
31
44
 
32
45
  - This gem supports both webpack and rspack configurations
@@ -6,7 +6,7 @@ This document tracks the ESLint errors currently suppressed in the codebase and
6
6
 
7
7
  **As of 2025-10-14**: All TypeScript files in `package/` directory are temporarily excluded from linting via the ignore pattern `package/**/*.ts` in `eslint.config.js`. This allows the project to adopt ESLint configuration without requiring immediate fixes to all existing issues.
8
8
 
9
- **Latest Update**: Fixed all `class-methods-use-this` violations by converting FileWriter methods to static methods (4 violations resolved).
9
+ **Latest Update**: Fixed all `no-param-reassign` violations by refactoring to create new objects instead of mutating parameters (7 violations resolved).
10
10
 
11
11
  ## Current Linting Status
12
12
 
@@ -19,12 +19,12 @@ This document tracks the ESLint errors currently suppressed in the codebase and
19
19
 
20
20
  **TypeScript files** (currently ignored via `package/**/*.ts`):
21
21
 
22
- - **Estimated suppressed errors: ~172** (from sample analysis)
23
- - TypeScript type-safety issues: ~114 (66%)
24
- - Style/convention issues: ~58 (34%)
22
+ - **Estimated suppressed errors: ~163** (from sample analysis)
23
+ - TypeScript type-safety issues: ~114 (70%)
24
+ - Style/convention issues: ~49 (30%)
25
25
 
26
26
  **Target**: Reduce suppressed errors by 50% within Q1 2025
27
- **Last Updated**: 2025-10-14
27
+ **Last Updated**: 2025-10-15
28
28
 
29
29
  ## Priority Matrix
30
30
 
@@ -33,9 +33,9 @@ This document tracks the ESLint errors currently suppressed in the codebase and
33
33
  | `@typescript-eslint/no-explicit-any` | High | High | P1 | 22 |
34
34
  | `@typescript-eslint/no-unsafe-*` | High | High | P1 | 85 |
35
35
  | `config.ts` type safety | High | Medium | P1 | 7 |
36
- | `no-param-reassign` | Medium | Low | P2 | 7 |
36
+ | `no-param-reassign` | Medium | Low | P2 | 0 |
37
37
  | `class-methods-use-this` | Low | Low | P3 | 0 |
38
- | `no-nested-ternary` | Low | Low | P3 | 3 |
38
+ | `no-nested-ternary` | Low | Low | P3 | 0 |
39
39
  | `import/prefer-default-export` | Low | Medium | P3 | 9 |
40
40
  | `global-require` | Medium | High | P2 | 3 |
41
41
  | Other style issues | Low | Low | P3 | 31 |
@@ -80,15 +80,13 @@ This document tracks the ESLint errors currently suppressed in the codebase and
80
80
 
81
81
  ✅ **FIXED** - All FileWriter methods that didn't use instance state have been converted to static methods
82
82
 
83
- #### `no-nested-ternary` (3 instances)
83
+ #### `no-nested-ternary` (0 instances)
84
84
 
85
- **Fix strategy:** Refactor to if-else statements
85
+ **FIXED** - All nested ternary expressions have been refactored to if-else statements for better readability
86
86
 
87
- #### `no-param-reassign` (7 instances)
87
+ #### `no-param-reassign` (0 instances)
88
88
 
89
- **Files affected:** `configExporter/cli.ts`
90
- **Why suppressed:** Common pattern for option objects
91
- **Fix strategy:** Create new objects instead of mutating parameters
89
+ **FIXED** - Refactored `applyDefaults` function to return new objects instead of mutating parameters
92
90
 
93
91
  #### `no-underscore-dangle` (2 instances)
94
92
 
@@ -115,10 +113,11 @@ This document tracks the ESLint errors currently suppressed in the codebase and
115
113
  - Added proper type annotations for `requireOrError` calls
116
114
  - Configured appropriate global rule disables (`no-console`, `no-restricted-syntax`)
117
115
  - ✅ **Fixed `class-methods-use-this`** - Converted FileWriter methods to static methods
116
+ - ✅ **Fixed `no-nested-ternary`** - Refactored to if-else statements for better readability
117
+ - ✅ **Fixed `no-param-reassign`** - Refactored `applyDefaults` to return new objects instead of mutating parameters
118
118
 
119
119
  🔧 Could still fix (low risk):
120
120
 
121
- - `no-nested-ternary` - Refactor conditionals
122
121
  - `no-useless-escape` - Remove unnecessary escapes
123
122
  - Unused variables - Remove or prefix with underscore
124
123
 
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- shakapacker (9.3.0.beta.2)
4
+ shakapacker (9.3.0.beta.5)
5
5
  activesupport (>= 5.2)
6
6
  package_json
7
7
  rack-proxy (>= 0.6.1)
data/README.md CHANGED
@@ -78,6 +78,7 @@ Read the [full review here](https://clutch.co/profile/shakacode#reviews?sort_by=
78
78
  - [View Helper: `image_pack_tag`](#view-helper-image_pack_tag)
79
79
  - [View Helper: `favicon_pack_tag`](#view-helper-favicon_pack_tag)
80
80
  - [View Helper: `preload_pack_asset`](#view-helper-preload_pack_asset)
81
+ - [View Helper: `send_pack_early_hints`](#view-helper-send_pack_early_hints)
81
82
  - [Images in Stylesheets](#images-in-stylesheets)
82
83
  - [Server-Side Rendering (SSR)](#server-side-rendering-ssr)
83
84
  - [Development](#development)
@@ -477,8 +478,8 @@ And the main layout has:
477
478
  is the same as using this in the main layout:
478
479
 
479
480
  ```erb
480
- <%= javascript_pack_tag 'calendar', 'map', application' %>
481
- <%= stylesheet_pack_tag 'calendar', 'map', application' %>
481
+ <%= javascript_pack_tag 'calendar', 'map', 'application' %>
482
+ <%= stylesheet_pack_tag 'calendar', 'map', 'application' %>
482
483
  ```
483
484
 
484
485
  However, you typically can't do that in the main layout, as the view and partial codes will depend on the route.
@@ -490,12 +491,13 @@ Thus, you can distribute the logic of what packs are needed for any route. All t
490
491
  The typical issue is that your layout might reference some partials that need to configure packs. A good way to solve this problem is to use `content_for` to ensure that the code to render your partial comes before the call to `javascript_pack_tag`.
491
492
 
492
493
  ```erb
493
- <% content_for :footer do
494
- render 'shared/footer' %>
494
+ <% content_for :footer do %>
495
+ <%= render 'shared/footer' %>
496
+ <% end %>
495
497
 
496
498
  <%= javascript_pack_tag %>
497
499
 
498
- <%= content_for :footer %>
500
+ <%= yield :footer %>
499
501
  ```
500
502
 
501
503
  There is also `prepend_javascript_pack_tag` that will put the entry at the front of the queue. This is handy when you want an entry in the main layout to go before the partial and main layout `append_javascript_pack_tag` entries.
@@ -522,11 +524,13 @@ And the main layout has:
522
524
  is the same as using this in the main layout:
523
525
 
524
526
  ```erb
525
- <%= javascript_pack_tag 'main', 'calendar', 'map', application' %>
527
+ <%= javascript_pack_tag 'main', 'calendar', 'map', 'application' %>
526
528
  ```
527
529
 
528
530
  For alternative options for setting the additional packs, [see this discussion](https://github.com/shakacode/shakapacker/issues/39).
529
531
 
532
+ **Important:** To prevent FOUC (Flash of Unstyled Content), always place `stylesheet_pack_tag` in the `<head>` section of your layout. When using `append_*` helpers with dynamic pack loading (e.g., React on Rails), use the `content_for` pattern to control execution order. See the [Preventing FOUC guide](./docs/preventing_fouc.md) for detailed examples.
533
+
530
534
  #### View Helper: `asset_pack_path`
531
535
 
532
536
  If you want to link a static asset for `<img />` tag, you can use the `asset_pack_path` helper:
@@ -560,6 +564,24 @@ If you want to preload a static asset in your `<head>`, you can use the `preload
560
564
  <%= preload_pack_asset 'fonts/fa-regular-400.woff2' %>
561
565
  ```
562
566
 
567
+ #### HTTP 103 Early Hints
568
+
569
+ Automatically send early hints to browsers for faster asset loading. Supports `preload`/`prefetch`/`none` configuration per-page.
570
+
571
+ ```yaml
572
+ # config/shakapacker.yml
573
+ production:
574
+ early_hints:
575
+ enabled: true
576
+ debug: false # Enable to see what hints are sent (as HTML comments)
577
+ ```
578
+
579
+ ⚠️ **Important**: May improve or hurt performance depending on content. See the [Early Hints Guide](./docs/early_hints.md) for configuration, performance guidance, and examples.
580
+
581
+ **Troubleshooting**: Enable `debug: true` to see HTML comments showing what hints were sent or why they were skipped.
582
+
583
+ **Requirements:** Rails 5.2+, HTTP/2 server, modern browsers. Gracefully degrades if not supported.
584
+
563
585
  ### Images in Stylesheets
564
586
 
565
587
  If you want to use images in your stylesheets:
@@ -11,7 +11,10 @@ This guide covers all configuration options available in `config/shakapacker.yml
11
11
  - [Development Server](#development-server)
12
12
  - [Compilation Options](#compilation-options)
13
13
  - [Advanced Options](#advanced-options)
14
+ - [Subresource Integrity](#integrity)
15
+ - [Early Hints](#early_hints)
14
16
  - [Environment-Specific Configuration](#environment-specific-configuration)
17
+ - [Build Configurations (config/shakapacker-builds.yml)](#build-configurations-configshakapacker-buildsyml)
15
18
 
16
19
  ## Basic Configuration
17
20
 
@@ -484,6 +487,37 @@ integrity:
484
487
 
485
488
  See [Subresource Integrity Guide](subresource_integrity.md) for details.
486
489
 
490
+ ### `early_hints`
491
+
492
+ **Type:** `object`
493
+ **Default:** `{ enabled: false, css: "preload", js: "preload" }`
494
+ **Requires:** Rails 5.2+, HTTP/2 server
495
+
496
+ Automatically send HTTP 103 Early Hints for faster asset loading.
497
+
498
+ ```yaml
499
+ early_hints:
500
+ enabled: true # Master switch (default: false)
501
+ css: "preload" # 'preload' | 'prefetch' | 'none' (default: 'preload')
502
+ js: "preload" # 'preload' | 'prefetch' | 'none' (default: 'preload')
503
+ ```
504
+
505
+ **Options:**
506
+
507
+ - `enabled`: Enable/disable early hints (default: `false`)
508
+ - `css`: Hint type for CSS - `'preload'`, `'prefetch'`, or `'none'` (default: `'preload'`)
509
+ - `js`: Hint type for JS - `'preload'`, `'prefetch'`, or `'none'` (default: `'preload'`)
510
+
511
+ ⚠️ **Performance note**: May improve or hurt page load depending on content. Configure per-page for best results.
512
+
513
+ See the [Early Hints Guide](early_hints.md) for:
514
+
515
+ - Performance considerations and warnings
516
+ - Per-page configuration (`configure_pack_early_hints`)
517
+ - Dynamic configuration examples
518
+ - Hero image preloading with `preload_link_tag`
519
+ - Troubleshooting and testing recommendations
520
+
487
521
  ## Environment-Specific Configuration
488
522
 
489
523
  Shakapacker supports per-environment configuration with fallback logic:
@@ -608,6 +642,106 @@ default: &default
608
642
  - packages/ui-components
609
643
  ```
610
644
 
645
+ ## Build Configurations (config/shakapacker-builds.yml)
646
+
647
+ Shakapacker supports defining reusable build configurations in `config/shakapacker-builds.yml`. This allows you to run predefined builds with a simple command, making it easy to switch between different build scenarios.
648
+
649
+ ### Creating a Build Configuration File
650
+
651
+ Generate `config/shakapacker-builds.yml` with example builds:
652
+
653
+ ```bash
654
+ bin/shakapacker --init # Creates config/shakapacker-builds.yml
655
+ ```
656
+
657
+ This generates a file with example builds for common scenarios (HMR development, standard development, and production).
658
+
659
+ ### Running Builds by Name
660
+
661
+ Once you have `config/shakapacker-builds.yml`, you can run builds by name:
662
+
663
+ ```bash
664
+ # List available builds
665
+ bin/shakapacker --list-builds
666
+
667
+ # Run a specific build
668
+ bin/shakapacker --build dev-hmr # Client bundle with HMR (automatically uses dev server)
669
+ bin/shakapacker --build prod # Client and server bundles for production
670
+ bin/shakapacker --build dev # Client bundle for development
671
+ ```
672
+
673
+ ### Build Configuration Format
674
+
675
+ Example `config/shakapacker-builds.yml`:
676
+
677
+ ```yaml
678
+ builds:
679
+ dev-hmr:
680
+ description: Client bundle with HMR (React Fast Refresh)
681
+ bundler: rspack # Optional: override assets_bundler from config/shakapacker.yml
682
+ environment:
683
+ NODE_ENV: development
684
+ RAILS_ENV: development
685
+ WEBPACK_SERVE: "true" # Automatically uses bin/shakapacker-dev-server
686
+ outputs:
687
+ - client
688
+ config: config/${BUNDLER}/custom.config.js # Optional: custom config file with variable substitution
689
+
690
+ prod:
691
+ description: Production client and server bundles
692
+ environment:
693
+ NODE_ENV: production
694
+ RAILS_ENV: production
695
+ outputs:
696
+ - client # Multiple outputs - builds both client and server bundles
697
+ - server
698
+ ```
699
+
700
+ ### Build Configuration Options
701
+
702
+ - **`description`** (optional): Human-readable description of the build
703
+ - **`bundler`** (optional): Override the default bundler from `config/shakapacker.yml` (`webpack` or `rspack`)
704
+ - **`dev_server`** (optional): Boolean flag to force routing to dev server (overrides environment variable detection)
705
+ - **`environment`**: Environment variables to set when running the build
706
+ - **`outputs`**: Array of output types - can include `client`, `server`, or both for multiple bundles in a single build
707
+ - **`config`** (optional): Custom config file path (supports `${BUNDLER}` variable substitution)
708
+ - **`bundler_env`** (optional): Key-value pairs passed as bundler `--env` flags (e.g., `{ analyze: true }` becomes `--env analyze=true`)
709
+
710
+ ### Automatic Dev Server Detection
711
+
712
+ Shakapacker automatically uses `bin/shakapacker-dev-server` instead of the regular build command when:
713
+
714
+ 1. The build has `dev_server: true` explicitly set (preferred method - takes precedence over environment variables), OR
715
+ 2. The build has `WEBPACK_SERVE=true` or `HMR=true` in its environment variables (fallback for backward compatibility)
716
+
717
+ Example:
718
+
719
+ ```bash
720
+ # These are equivalent:
721
+ bin/shakapacker --build dev-hmr
722
+ WEBPACK_SERVE=true bin/shakapacker-dev-server # (with dev-hmr environment vars)
723
+ ```
724
+
725
+ ### Variable Substitution
726
+
727
+ The `config` field supports `${BUNDLER}` substitution:
728
+
729
+ ```yaml
730
+ builds:
731
+ custom:
732
+ bundler: rspack
733
+ config: config/${BUNDLER}/custom.config.js # Becomes: config/rspack/custom.config.js
734
+ ```
735
+
736
+ ### When to Use Build Configurations
737
+
738
+ Build configurations are useful for:
739
+
740
+ - **Multiple build scenarios**: Use when you need different builds for HMR development, standard development, and production
741
+ - **CI/CD pipelines**: Use when you want predefined builds that can be referenced in deployment scripts
742
+ - **Team consistency**: Use to ensure all developers use the same build configurations
743
+ - **Complex setups**: Use to manage different bundler configs or environment variables for different scenarios
744
+
611
745
  ## Troubleshooting
612
746
 
613
747
  If you encounter configuration issues:
@@ -627,4 +761,6 @@ See [Troubleshooting Guide](troubleshooting.md) for more help.
627
761
  - [Deployment Guide](deployment.md)
628
762
  - [CDN Setup Guide](cdn_setup.md)
629
763
  - [Precompile Hook Guide](precompile_hook.md)
764
+ - [Early Hints Guide](early_hints.md)
765
+ - [Subresource Integrity Guide](subresource_integrity.md)
630
766
  - [Troubleshooting Guide](troubleshooting.md)