shakapacker 9.3.0 → 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 (58) 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 +15 -8
  10. data/CLAUDE.md +6 -10
  11. data/CONTRIBUTING.md +57 -0
  12. data/Gemfile.lock +1 -1
  13. data/README.md +58 -33
  14. data/docs/api-reference.md +519 -0
  15. data/docs/configuration.md +11 -5
  16. data/docs/css-modules-export-mode.md +40 -6
  17. data/docs/transpiler-migration.md +12 -9
  18. data/docs/using_swc_loader.md +13 -10
  19. data/docs/v9_upgrade.md +11 -2
  20. data/eslint.config.fast.js +120 -8
  21. data/eslint.config.js +50 -31
  22. data/lib/install/config/shakapacker.yml +14 -1
  23. data/lib/shakapacker/configuration.rb +47 -4
  24. data/lib/shakapacker/dev_server_runner.rb +4 -0
  25. data/lib/shakapacker/doctor.rb +1 -1
  26. data/lib/shakapacker/version.rb +1 -1
  27. data/package/config.ts +2 -3
  28. data/package/configExporter/cli.ts +29 -24
  29. data/package/dev_server.ts +2 -2
  30. data/package/env.ts +1 -1
  31. data/package/environments/__type-tests__/rspack-plugin-compatibility.ts +6 -6
  32. data/package/environments/base.ts +2 -2
  33. data/package/environments/development.ts +3 -6
  34. data/package/environments/production.ts +2 -2
  35. data/package/environments/test.ts +2 -1
  36. data/package/esbuild/index.ts +0 -2
  37. data/package/index.d.ts +1 -0
  38. data/package/index.d.ts.template +1 -0
  39. data/package/index.ts +0 -1
  40. data/package/plugins/rspack.ts +3 -1
  41. data/package/plugins/webpack.ts +5 -3
  42. data/package/rspack/index.ts +3 -3
  43. data/package/rules/file.ts +1 -1
  44. data/package/rules/raw.ts +3 -1
  45. data/package/rules/rspack.ts +0 -2
  46. data/package/rules/sass.ts +0 -2
  47. data/package/rules/webpack.ts +0 -1
  48. data/package/swc/index.ts +0 -2
  49. data/package/types.ts +8 -11
  50. data/package/utils/debug.ts +0 -4
  51. data/package/utils/getStyleRule.ts +17 -9
  52. data/package/utils/helpers.ts +8 -3
  53. data/package/utils/pathValidation.ts +10 -11
  54. data/package/utils/requireOrError.ts +4 -3
  55. data/package/webpackDevServerConfig.ts +4 -4
  56. data/package.json +1 -1
  57. data/test/package/transpiler-defaults.test.js +42 -0
  58. metadata +5 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1e94cd0b57c81506b9cab0fb54cc6a876276c3f3331686cf921fa4485442ab99
4
- data.tar.gz: 292b0623b5241014524f9227ed2a1009752de53e8db610344567f761c7b8b4bc
3
+ metadata.gz: 827667fa6e3a24bab59f3d9c2ef8404755b0deed67e1fce8ec62ada24e9b1a51
4
+ data.tar.gz: 06e18cd459b5e343601524ef2a1275ed0a86e6f842f63ef49d22e94fd7468ff2
5
5
  SHA512:
6
- metadata.gz: 6dd27e8501b86f06fbefd6f71a2a3ceb9c975dd28f140251ab03cf6bd972b631db35666e9c05bdf434bf2ac13c1568f57bd73a7841efb38befb541f2d0cfaeb1
7
- data.tar.gz: 623358b9543ddcad7586a68e03aba4848151d4490a298c39320a395cb4aa450783a91f4c21d53b491868600d57e054f3f52bcb72eb244f25ebc0e8cb20ff1738
6
+ metadata.gz: ccc98e916ba625cc386091668bad5737376f0d031758ce44124f8c3a45f463e8e9dbdc2e42c302387b3f1f074a075524e9856e01295cd73ea1efa7ebf3f40469
7
+ data.tar.gz: 5b256253fb6abd10007f861c6fc16a2a2500db40ca2a454cd75f8aeb89f83a13669394524cffb3cfffac6b490aa9a57f498358d3c57c0836d069072d208713eb
@@ -0,0 +1,224 @@
1
+ # Update Changelog
2
+
3
+ You are helping to add an entry to the CHANGELOG.md file for the Shakapacker project.
4
+
5
+ ## Critical Requirements
6
+
7
+ 1. **User-visible changes only**: Only add changelog entries for user-visible changes:
8
+ - New features
9
+ - Bug fixes
10
+ - Breaking changes
11
+ - Deprecations
12
+ - Performance improvements
13
+ - Security fixes
14
+ - Changes to public APIs or configuration options
15
+
16
+ 2. **Do NOT add entries for**:
17
+ - Linting fixes
18
+ - Code formatting
19
+ - Internal refactoring
20
+ - Test updates
21
+ - Documentation fixes (unless they fix incorrect docs about behavior)
22
+ - CI/CD changes
23
+
24
+ ## Formatting Requirements
25
+
26
+ ### Entry Format
27
+
28
+ Each changelog entry MUST follow this exact format:
29
+
30
+ ```markdown
31
+ - **Bold description of change**. [PR #123](https://github.com/shakacode/shakapacker/pull/123) by [username](https://github.com/username). Optional additional context or details.
32
+ ```
33
+
34
+ **Important formatting rules**:
35
+
36
+ - Start with a dash and space: `- `
37
+ - Use **bold** for the main description
38
+ - End the bold description with a period before the link
39
+ - Always link to the PR: `[PR #123](https://github.com/shakacode/shakapacker/pull/123)` - **Note: Shakapacker uses `#` in PR links, unlike React on Rails**
40
+ - Always link to the author: `by [username](https://github.com/username)`
41
+ - End with a period after the author link
42
+ - Additional details can be added after the main entry, using proper indentation for multi-line entries
43
+
44
+ ### Breaking Changes Format
45
+
46
+ For breaking changes, use this format:
47
+
48
+ ```markdown
49
+ - **Breaking**: Description of the breaking change. See [Migration Guide](docs/vX_upgrade.md) for migration instructions. [PR #123](https://github.com/shakacode/shakapacker/pull/123) by [username](https://github.com/username).
50
+ ```
51
+
52
+ ### Category Organization
53
+
54
+ Entries should be organized under these section headings. The project uses both standard and custom headings:
55
+
56
+ **Standard headings** (from keepachangelog.com) - use these for most changes:
57
+
58
+ - `### Added` - New features
59
+ - `### Changed` - Changes to existing functionality
60
+ - `### Deprecated` - Deprecation notices
61
+ - `### Removed` - Removed features
62
+ - `### Fixed` - Bug fixes
63
+ - `### Security` - Security-related changes
64
+ - `### Improved` - Improvements to existing features
65
+
66
+ **Custom headings** (project-specific) - use sparingly when standard headings don't fit:
67
+
68
+ - `### ⚠️ Breaking Changes` - Breaking changes only (Shakapacker uses emoji in heading)
69
+ - `### API Improvements` - API changes and improvements
70
+ - `### Developer Experience` - Developer workflow improvements
71
+ - `### Performance` - Performance improvements
72
+
73
+ **Prefer standard headings.** Only use custom headings when the change needs more specific categorization.
74
+
75
+ **Only include section headings that have entries.**
76
+
77
+ ### Version Management
78
+
79
+ After adding entries, use the rake task to manage version headers:
80
+
81
+ ```bash
82
+ bundle exec rake update_changelog
83
+ ```
84
+
85
+ This will:
86
+
87
+ - Add headers for the new version
88
+ - Update version diff links at the bottom of the file
89
+
90
+ ### Version Links
91
+
92
+ After adding an entry to the `## [Unreleased]` section, ensure the version diff links at the bottom of the file are correct.
93
+
94
+ The format at the bottom should be:
95
+
96
+ ```markdown
97
+ [Unreleased]: https://github.com/shakacode/shakapacker/compare/v9.3.0...main
98
+ [v9.3.0]: https://github.com/shakacode/shakapacker/compare/v9.2.0...v9.3.0
99
+ ```
100
+
101
+ When a new version is released:
102
+
103
+ 1. Change `[Unreleased]` heading to `## [vX.Y.Z] - Month Day, Year`
104
+ 2. Add a new `## [Unreleased]` section at the top
105
+ 3. Update the `[Unreleased]` link to compare from the new version
106
+ 4. Add a new version link for the released version
107
+
108
+ ## Process
109
+
110
+ ### For Regular Changelog Updates
111
+
112
+ 1. **Determine the correct version tag to compare against**:
113
+ - First, check the tag dates: `git log --tags --simplify-by-decoration --pretty="format:%ai %d" | head -10`
114
+ - Find the latest version tag and its date
115
+ - Compare main branch date to the tag date
116
+ - If the tag is NEWER than main, it means main needs to be updated to include the tag's commits
117
+ - **CRITICAL**: Always use `git log TAG..BRANCH` to find commits that are in the tag but not in the branch, as the tag may be ahead
118
+
119
+ 2. **Check commits and version boundaries**:
120
+ - Run `git log --oneline LAST_TAG..main` to see commits since the last release
121
+ - Also check `git log --oneline main..LAST_TAG` to see if the tag is ahead of main
122
+ - If the tag is ahead, entries in "Unreleased" section may actually belong to that tagged version
123
+ - Identify which commits contain user-visible changes
124
+ - Extract PR numbers and author information from commit messages
125
+ - **Never ask the user for PR details** - get them from the git history
126
+
127
+ 3. **Validate** that changes are user-visible (per the criteria above). If not user-visible, skip those commits.
128
+
129
+ 4. **Read the current CHANGELOG.md** to understand the existing structure and formatting.
130
+
131
+ 5. **Determine where entries should go**:
132
+ - If the latest version tag is NEWER than main branch, move entries from "Unreleased" to that version section
133
+ - If main is ahead of the latest tag, add new entries to "Unreleased"
134
+ - Always verify the version date in CHANGELOG.md matches the actual tag date
135
+
136
+ 6. **Add or move entries** to the appropriate section under appropriate category headings.
137
+ - **CRITICAL**: When moving entries from "Unreleased" to a version section, merge them with existing entries under the same category heading
138
+ - **NEVER create duplicate section headings** (e.g., don't create two "### Fixed" sections)
139
+ - If the version section already has a category heading (e.g., "### Fixed"), add the moved entries to that existing section
140
+ - Maintain the category order as defined above
141
+
142
+ 7. **Verify formatting**:
143
+ - Bold description with period
144
+ - Proper PR link
145
+ - Proper author link
146
+ - Consistent with existing entries
147
+ - File ends with a newline character
148
+
149
+ 8. **Run linting** after making changes:
150
+
151
+ ```bash
152
+ yarn lint
153
+ ```
154
+
155
+ 9. **Show the user** the added or moved entries and explain what was done.
156
+
157
+ ### For Beta to Non-Beta Version Release
158
+
159
+ When releasing from beta to a stable version (e.g., v9.1.0-beta.3 → v9.1.0):
160
+
161
+ 1. **Remove all beta version labels** from the changelog:
162
+ - Change `## [v9.1.0-beta.1]`, `## [v9.1.0-beta.2]`, etc. to a single `## [v9.1.0]` section
163
+ - Combine all beta entries into the stable release section
164
+
165
+ 2. **Consolidate duplicate entries**:
166
+ - If bug fixes or changes were made to features introduced in earlier betas, keep only the final state
167
+ - Remove redundant changelog entries for fixes to beta features
168
+ - Keep the most recent/accurate description of each change
169
+
170
+ 3. **Update version diff links** at the bottom to point to the stable version
171
+
172
+ ### For New Beta Version Release
173
+
174
+ When creating a new beta version, ask the user which approach to take:
175
+
176
+ **Option 1: Process changes since last beta**
177
+
178
+ - Only add entries for commits since the previous beta version
179
+ - Maintains detailed history of what changed in each beta
180
+
181
+ **Option 2: Collapse all prior betas into current beta**
182
+
183
+ - Combine all beta changelog entries into the new beta version
184
+ - Removes previous beta version sections
185
+ - Cleaner changelog with less version noise
186
+
187
+ After the user chooses, proceed with that approach.
188
+
189
+ ## Examples
190
+
191
+ Run this command to see real formatting examples from the codebase:
192
+
193
+ ```bash
194
+ grep -A 3 "^### " CHANGELOG.md | head -30
195
+ ```
196
+
197
+ ### Good Entry Example
198
+
199
+ ```markdown
200
+ - **Enhanced error handling for better security and debugging**. [PR #786](https://github.com/shakacode/shakapacker/pull/786) by [justin808](https://github.com/justin808).
201
+ - Path validation now properly reports permission errors instead of silently handling them
202
+ - Module loading errors now include original error context for easier troubleshooting
203
+ - Improved security by only catching ENOENT errors in path resolution, rethrowing permission and access errors
204
+ ```
205
+
206
+ ### Entry with Sub-bullets Example
207
+
208
+ ```markdown
209
+ - **HTTP 103 Early Hints support** for faster asset loading. [PR #722](https://github.com/shakacode/shakapacker/pull/722) by [justin808](https://github.com/justin808). Automatically sends early hints when `early_hints: enabled: true` in `shakapacker.yml`. Works with `append_javascript_pack_tag`/`append_stylesheet_pack_tag`, supports per-controller/action configuration, and includes helpers like `configure_pack_early_hints` and `skip_send_pack_early_hints`. Requires Rails 5.2+ and HTTP/2-capable server. See [Early Hints Guide](docs/early_hints.md).
210
+ ```
211
+
212
+ ### Breaking Change Example
213
+
214
+ ```markdown
215
+ - **Breaking: SWC default configuration now uses `loose: false`**. [PR #658](https://github.com/shakacode/shakapacker/pull/658) by [justin808](https://github.com/justin808). See [v9 Upgrade Guide - SWC Loose Mode](./docs/v9_upgrade.md#swc-loose-mode-breaking-change-v910) for migration details.
216
+ ```
217
+
218
+ ## Additional Notes
219
+
220
+ - Keep descriptions concise but informative
221
+ - Focus on the "what" and "why", not the "how"
222
+ - Use past tense for the description
223
+ - Be consistent with existing formatting in the changelog
224
+ - Always ensure the file ends with a trailing newline
@@ -0,0 +1,17 @@
1
+ {
2
+ "problemMatcher": [
3
+ {
4
+ "owner": "actionlint",
5
+ "pattern": [
6
+ {
7
+ "regexp": "^(?:\\x1b\\[\\d+m)?(.+?)(?:\\x1b\\[\\d+m)*:(?:\\x1b\\[\\d+m)*(\\d+)(?:\\x1b\\[\\d+m)*:(?:\\x1b\\[\\d+m)*(\\d+)(?:\\x1b\\[\\d+m)*: (?:\\x1b\\[\\d+m)*(.+?)(?:\\x1b\\[\\d+m)* \\[(.+?)\\]$",
8
+ "file": 1,
9
+ "line": 2,
10
+ "column": 3,
11
+ "message": 4,
12
+ "code": 5
13
+ }
14
+ ]
15
+ }
16
+ ]
17
+ }
@@ -5,6 +5,15 @@ on:
5
5
  branches:
6
6
  - "main"
7
7
  pull_request:
8
+ paths:
9
+ - "spec/dummy/**"
10
+ - "lib/**"
11
+ - "**.rb"
12
+ - "**.js"
13
+ - "**.ts"
14
+ - "package.json"
15
+ - ".github/workflows/dummy.yml"
16
+ workflow_dispatch:
8
17
 
9
18
  concurrency:
10
19
  # Pushing new changes to a branch will cancel any in-progress CI runs
@@ -5,6 +5,19 @@ on:
5
5
  branches:
6
6
  - "main"
7
7
  pull_request:
8
+ paths:
9
+ - "lib/install/**"
10
+ - "lib/generators/**"
11
+ - "spec/generator_specs/**"
12
+ - "**.rb"
13
+ - "**.gemspec"
14
+ - "Gemfile"
15
+ - "gemfiles/**"
16
+ - "package.json"
17
+ - "**.js"
18
+ - "**.ts"
19
+ - ".github/workflows/generator.yml"
20
+ workflow_dispatch:
8
21
 
9
22
  concurrency:
10
23
  # Pushing new changes to a branch will cancel any in-progress CI runs
@@ -5,6 +5,19 @@ on:
5
5
  branches:
6
6
  - "main"
7
7
  pull_request:
8
+ paths:
9
+ - "**.js"
10
+ - "**.ts"
11
+ - "package.json"
12
+ - "yarn.lock"
13
+ - "eslint.config.js"
14
+ - ".prettierrc"
15
+ - ".prettierignore"
16
+ - "knip.json"
17
+ - "tsconfig.json"
18
+ - "jest.config.js"
19
+ - ".github/workflows/node.yml"
20
+ workflow_dispatch:
8
21
 
9
22
  concurrency:
10
23
  # Pushing new changes to a branch will cancel any in-progress CI runs
@@ -58,6 +71,76 @@ jobs:
58
71
 
59
72
  - name: TypeScript type check
60
73
  run: yarn type-check
74
+
75
+ # We only download and run Actionlint if there is any difference in GitHub Action workflows
76
+ # https://github.com/rhysd/actionlint/blob/main/docs/usage.md#on-github-actions
77
+ # Note: Only runs on pull_request events, not push events (where github.event.pull_request is null)
78
+ - name: Check GitHub Action changes
79
+ if: github.event_name == 'pull_request'
80
+ id: check-workflows
81
+ run: |
82
+ git fetch origin ${{ github.event.pull_request.base.sha }}
83
+ if git diff --name-only ${{ github.event.pull_request.base.sha }} ${{ github.sha }} | grep -q '^.github/workflows'; then
84
+ echo "changed=true" >> "$GITHUB_OUTPUT"
85
+ response=$(curl -sf https://api.github.com/repos/rhysd/actionlint/releases/latest)
86
+ if [ $? -eq 0 ]; then
87
+ actionlint_version=$(echo "$response" | jq -r .tag_name)
88
+ if [ -z "$actionlint_version" ]; then
89
+ echo "Failed to parse Actionlint version"
90
+ exit 1
91
+ fi
92
+ echo "actionlint_version=\"$actionlint_version\"" >> "$GITHUB_OUTPUT"
93
+ fi
94
+ fi
95
+ - name: Setup Actionlint
96
+ if: github.event_name == 'pull_request' && steps.check-workflows.outputs.changed == 'true'
97
+ uses: actions/cache@v4
98
+ id: cache-actionlint
99
+ with:
100
+ path: ./actionlint
101
+ key: ${{ runner.os }}-actionlint-${{ steps.check-workflows.outputs.actionlint_version }}
102
+ - name: Download Actionlint
103
+ if: github.event_name == 'pull_request' && steps.check-workflows.outputs.changed == 'true' && steps.cache-actionlint.outputs.cache-hit != 'true'
104
+ run: bash <(curl https://raw.githubusercontent.com/rhysd/actionlint/main/scripts/download-actionlint.bash)
105
+ - name: Lint GitHub Actions
106
+ if: github.event_name == 'pull_request' && steps.check-workflows.outputs.changed == 'true'
107
+ run: |
108
+ echo "::add-matcher::.github/actionlint-matcher.json"
109
+ SHELLCHECK_OPTS="-S warning" ./actionlint -color
110
+ shell: bash
111
+
112
+ type-check-dts-without-webpack:
113
+ name: Verify .d.ts files work without webpack
114
+ runs-on: ubuntu-latest
115
+
116
+ steps:
117
+ - uses: actions/checkout@v4
118
+ with:
119
+ persist-credentials: false
120
+ - uses: actions/setup-node@v4
121
+ with:
122
+ node-version: 20.x
123
+
124
+ - name: Create test directory and copy .d.ts files
125
+ run: |
126
+ mkdir -p /tmp/test-types
127
+ cp package/*.d.ts /tmp/test-types/
128
+ # types.ts is imported by index.d.ts; copy if it exists
129
+ cp package/types.ts /tmp/test-types/ 2>/dev/null || true
130
+
131
+ - name: Install TypeScript in test directory
132
+ run: |
133
+ cd /tmp/test-types
134
+ npm init -y
135
+ npm install typescript @types/node
136
+
137
+ - name: Verify hand-written .d.ts files type-check without webpack
138
+ run: |
139
+ cd /tmp/test-types
140
+ npx tsc --noEmit \
141
+ --skipLibCheck \
142
+ --moduleResolution node \
143
+ *.d.ts
61
144
  test:
62
145
  name: Testing
63
146
  strategy:
@@ -5,6 +5,17 @@ on:
5
5
  branches:
6
6
  - "main"
7
7
  pull_request:
8
+ paths:
9
+ - "**.rb"
10
+ - "**.gemspec"
11
+ - "Gemfile"
12
+ - "Rakefile"
13
+ - "gemfiles/**"
14
+ - ".rubocop.yml"
15
+ - "package.json"
16
+ - "**.ts"
17
+ - ".github/workflows/ruby.yml"
18
+ workflow_dispatch:
8
19
 
9
20
  concurrency:
10
21
  # Pushing new changes to a branch will cancel any in-progress CI runs
@@ -2,8 +2,18 @@ name: Test Both Bundlers
2
2
 
3
3
  on:
4
4
  pull_request:
5
+ paths:
6
+ - "spec/dummy/**"
7
+ - "lib/**"
8
+ - "**.rb"
9
+ - "**.js"
10
+ - "**.ts"
11
+ - "package.json"
12
+ - "yarn.lock"
13
+ - ".github/workflows/test-bundlers.yml"
5
14
  push:
6
15
  branches: [master, main]
16
+ workflow_dispatch:
7
17
 
8
18
  jobs:
9
19
  test-webpack:
data/CHANGELOG.md CHANGED
@@ -9,8 +9,20 @@
9
9
 
10
10
  ## [Unreleased]
11
11
 
12
+ ### Fixed
13
+
14
+ - Extended manifest merging for multiple client configurations to all environments. [PR #800](https://github.com/shakacode/shakapacker/pull/800) by [Judahmeek](https://github.com/Judahmeek).
15
+
12
16
  Changes since the last non-beta release.
13
17
 
18
+ ### Added
19
+
20
+ - **Support for `css_modules_export_mode` configuration option**. [PR #817](https://github.com/shakacode/shakapacker/pull/817) by [justin808](https://github.com/justin808). Adds `css_modules_export_mode` setting in `shakapacker.yml` to control CSS Modules export style. Set to `"named"` (default, v9+ behavior with true named exports) or `"default"` (v8 behavior with default export object). Allows teams to opt into v8-style exports for easier migration from v8 or when using TypeScript with strict type checking.
21
+ - **`Configuration#data` public API method** with enhanced documentation and safety. [PR #820](https://github.com/shakacode/shakapacker/pull/820) by [justin808](https://github.com/justin808). The `Configuration#data` method is now part of the public Ruby API, providing stable access to raw configuration data. Returns a frozen hash with symbolized keys to prevent accidental mutations. Includes comprehensive test coverage and detailed RDoc documentation.
22
+ - **Support for `javascript_transpiler: 'none'`** for completely custom webpack configurations. [PR #799](https://github.com/shakacode/shakapacker/pull/799) by [justin808](https://github.com/justin808). Allows users with custom webpack configs to skip Shakapacker's transpiler setup and validation by setting `javascript_transpiler: 'none'` in `shakapacker.yml`. Useful when managing transpilation entirely outside of Shakapacker's defaults.
23
+
24
+ ## [v9.3.0] - November 2, 2025
25
+
14
26
  ### Fixed
15
27
 
16
28
  - **Enhanced error handling for better security and debugging**. [PR #786](https://github.com/shakacode/shakapacker/pull/786) by [justin808](https://github.com/justin808).
@@ -29,8 +41,9 @@ Changes since the last non-beta release.
29
41
  - Eliminates confusing warning about `useContentHash: false` not being allowed in production
30
42
  - Development environment now explicitly sets `useContentHash: false` for faster builds
31
43
  - Production no longer needs explicit override since it inherits the correct default
32
-
33
- ## [v9.3.0] - October 28, 2025
44
+ - Fixed Rails constant error when using custom environments like staging. [PR #681](https://github.com/shakacode/shakapacker/pull/681) by [justin808](https://github.com/justin808). `RAILS_ENV=staging` no longer causes "uninitialized constant Shakapacker::Instance::Rails" error. Shakapacker now works in non-Rails contexts.
45
+ - Fixed TypeScript type definitions to export proper types instead of `any`. [PR #684](https://github.com/shakacode/shakapacker/pull/684) by [justin808](https://github.com/justin808). Previously `package/index.d.ts` was exporting all types as `any`, breaking IDE autocomplete. Now properly exports typed interfaces.
46
+ - Fixed integrity config handling and sass-loader version check. [PR #688](https://github.com/shakacode/shakapacker/pull/688) by [justin808](https://github.com/justin808). Properly handles subresource integrity configuration and correctly detects sass-loader version for conditional logic.
34
47
 
35
48
  ### Added
36
49
 
@@ -62,12 +75,6 @@ Changes since the last non-beta release.
62
75
  - **Improved error messages** to suggest `assets_bundler_config_path`. [PR #712](https://github.com/shakacode/shakapacker/pull/712) by [justin808](https://github.com/justin808). More helpful error messages when bundler config is not found, suggesting use of `assets_bundler_config_path` for custom locations.
63
76
  - **Improved doctor command output** clarity and accuracy. [PR #682](https://github.com/shakacode/shakapacker/pull/682) by [justin808](https://github.com/justin808). Better formatting and organization of diagnostic information with more actionable recommendations.
64
77
 
65
- ### Fixed
66
-
67
- - Fixed Rails constant error when using custom environments like staging. [PR #681](https://github.com/shakacode/shakapacker/pull/681) by [justin808](https://github.com/justin808). `RAILS_ENV=staging` no longer causes "uninitialized constant Shakapacker::Instance::Rails" error. Shakapacker now works in non-Rails contexts.
68
- - Fixed TypeScript type definitions to export proper types instead of `any`. [PR #684](https://github.com/shakacode/shakapacker/pull/684) by [justin808](https://github.com/justin808). Previously `package/index.d.ts` was exporting all types as `any`, breaking IDE autocomplete. Now properly exports typed interfaces.
69
- - Fixed integrity config handling and sass-loader version check. [PR #688](https://github.com/shakacode/shakapacker/pull/688) by [justin808](https://github.com/justin808). Properly handles subresource integrity configuration and correctly detects sass-loader version for conditional logic.
70
-
71
78
  ## [v9.2.0] - October 9, 2025
72
79
 
73
80
  ### Added
data/CLAUDE.md CHANGED
@@ -29,16 +29,12 @@
29
29
 
30
30
  ## Changelog
31
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)`)
32
+ - **Update CHANGELOG.md for user-visible changes only** (features, bug fixes, breaking changes, deprecations, performance improvements)
33
+ - **Do NOT add entries for**: linting, formatting, refactoring, tests, or documentation fixes
34
+ - **Format**: `[PR #123](https://github.com/shakacode/shakapacker/pull/123) by [username](https://github.com/username)` (Shakapacker uses `#` in PR links)
35
+ - **Use `/update-changelog` command** for guided changelog updates with automatic formatting
36
+ - **Version management**: Run `bundle exec rake update_changelog` after releases to update version headers
37
+ - **Examples**: Run `grep -A 3 "^### " CHANGELOG.md | head -30` to see real formatting examples
42
38
 
43
39
  ## Shakapacker-Specific
44
40
 
data/CONTRIBUTING.md CHANGED
@@ -103,11 +103,36 @@ Shakapacker uses optional peer dependencies (via `peerDependenciesMeta`) for max
103
103
  - **No installation warnings** - Package managers won't warn about missing optional dependencies
104
104
  - **Version constraints still apply** - When a package is installed, version compatibility is enforced
105
105
 
106
+ ### TypeScript Declaration Files and Optional Dependencies
107
+
108
+ When importing types from optional peer dependencies, we use `@ts-expect-error` directives:
109
+
110
+ ```typescript
111
+ // @ts-expect-error: webpack is an optional peer dependency (using type-only import)
112
+ import type { Configuration } from "webpack"
113
+ ```
114
+
115
+ **Important behavior:**
116
+
117
+ - **In development** (webpack installed): TypeScript doesn't error, but `@ts-expect-error` expects one → TypeScript compilation will fail
118
+ - **In production** (webpack not installed): TypeScript errors on import, `@ts-expect-error` suppresses it → TypeScript compilation succeeds
119
+
120
+ This is counterintuitive but correct. Our CI validates both scenarios to ensure the behavior works as expected.
121
+
122
+ **Example scenario:**
123
+
124
+ If webpack were changed from optional to required in `package.json`:
125
+
126
+ - Development builds would fail with: `error TS2578: Unused '@ts-expect-error' directive`
127
+ - This surfaces the dependency change immediately, preventing accidental breakage
128
+ - The build failure prompts developers to remove the `@ts-expect-error` directive
129
+
106
130
  ### When modifying dependencies:
107
131
 
108
132
  1. Add new peer dependencies to both `peerDependencies` and `peerDependenciesMeta` (marking as optional)
109
133
  2. Keep version ranges synchronized between `devDependencies` and `peerDependencies`
110
134
  3. Test with multiple package managers: `npm`, `yarn`, and `pnpm`
135
+ 4. If adding type-only imports from optional dependencies, use the `@ts-expect-error` pattern shown above
111
136
 
112
137
  ### Testing peer dependency changes:
113
138
 
@@ -223,6 +248,8 @@ The project uses Yarn in CI workflows for the following reasons:
223
248
  - `.github/workflows/ruby.yml` - Ruby test suite across Ruby/Rails versions
224
249
  - `.github/workflows/node.yml` - Node.js test suite across Node versions
225
250
  - `.github/workflows/generator.yml` - Generator installation tests
251
+ - `.github/workflows/dummy.yml` - Dummy app integration tests
252
+ - `.github/workflows/eslint-validation.yml` - ESLint configuration validation
226
253
 
227
254
  All workflows use:
228
255
 
@@ -239,6 +266,36 @@ And install dependencies with:
239
266
  yarn install
240
267
  ```
241
268
 
269
+ ### CI Optimization: Path Filtering
270
+
271
+ To reduce CI costs and execution time, workflows use **path filtering** to run only when relevant files change:
272
+
273
+ - **Ruby workflow** - Only runs when Ruby files, gemspecs, Gemfile, or RuboCop config changes
274
+ - **Node workflow** - Only runs when JS/TS files, package.json, or Node config changes
275
+ - **Generator specs** - Only runs when generator-related files change
276
+ - **Dummy specs** - Only runs when dummy app or lib files change
277
+ - **Test bundlers** - Only runs when code affecting bundler integration changes
278
+
279
+ This means documentation-only PRs (e.g., only changing `README.md`) will skip all test workflows entirely.
280
+
281
+ **Important:** The full test suite always runs on pushes to the `main` branch to ensure the main branch is always thoroughly tested.
282
+
283
+ ### Manual Workflow Execution
284
+
285
+ All workflows can be triggered manually via the GitHub Actions UI using the "Run workflow" button. This is useful for:
286
+
287
+ - Re-running tests after a temporary CI failure
288
+ - Testing workflows on specific branches without creating a PR
289
+ - Running full test suites on PRs that would normally skip certain workflows
290
+
291
+ ### Conditional Linting
292
+
293
+ The Node workflow includes conditional execution of actionlint (GitHub Actions linter):
294
+
295
+ - Only downloads and runs when `.github/workflows/*` files change
296
+ - Saves time by skipping on most PRs
297
+ - Includes caching for faster execution when needed
298
+
242
299
  ### Testing with Other Package Managers
243
300
 
244
301
  While CI uses Yarn, the gem supports all major package managers (npm, yarn, pnpm, bun). Generator specs test against all package managers to ensure compatibility.
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- shakapacker (9.3.0)
4
+ shakapacker (9.3.1)
5
5
  activesupport (>= 5.2)
6
6
  package_json
7
7
  rack-proxy (>= 0.6.1)