shakapacker 9.6.0.beta.0 → 9.6.0.rc.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/workflows/claude-code-review.yml +21 -21
- data/.github/workflows/claude.yml +5 -0
- data/CHANGELOG.md +30 -0
- data/CLAUDE.md +8 -0
- data/README.md +1 -1
- data/docs/configuration.md +5 -3
- data/docs/precompile_hook.md +7 -7
- data/eslint.config.js +1 -0
- data/lib/install/binstubs.rb +6 -2
- data/lib/install/config/shakapacker.yml +4 -2
- data/lib/install/template.rb +27 -19
- data/lib/shakapacker/env.rb +4 -2
- data/lib/shakapacker/install/env.rb +33 -0
- data/lib/shakapacker/manifest.rb +81 -20
- data/lib/shakapacker/runner.rb +42 -23
- data/lib/shakapacker/version.rb +1 -1
- data/package/environments/base.ts +4 -0
- data/package/index.d.ts +21 -0
- data/package/index.d.ts.template +21 -0
- data/package/index.ts +26 -0
- data/package/plugins/webpack.ts +5 -0
- data/package/rspack/index.ts +19 -1
- data/package/rules/file.ts +1 -1
- data/package/types/index.ts +8 -0
- data/package/utils/bundlerUtils.ts +232 -0
- data/package/utils/ensureManifestExists.ts +17 -0
- data/package.json +2 -2
- data/sig/shakapacker/manifest.rbs +15 -1
- data/test/package/bundlerUtils.rspack.test.js +102 -0
- data/test/package/bundlerUtils.test.js +97 -0
- data/test/package/environments/base.test.js +3 -0
- data/test/package/rules/file.test.js +1 -1
- data/test/package/utils/ensureManifestExists.test.js +51 -0
- metadata +11 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: a5240d4875989d1257b2c24656db7b29c5d052a9c99e22b9203565bf615aaf43
|
|
4
|
+
data.tar.gz: 855e3c61ff9169c2f4a34cc864d80f41299e48fd2530fb0def09e5bd9e07651f
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 719593b91e0dd86f68db334fe533a76e05ebf7862e04162039b066182bc52642e4c200d0394e6f3cbfaea8a8600d5340d20d9a5cd54bd389c40e4d4ff8c1f055
|
|
7
|
+
data.tar.gz: 80f22641a2e9cba2ab9a8ccda6095133e636165185914b8ae1b6f7a85f1b860834913dc4a697db7d1785f001420e47aefad34584389c0221dc7eb7e0f9778957
|
|
@@ -3,31 +3,19 @@ name: Claude Code Review
|
|
|
3
3
|
on:
|
|
4
4
|
pull_request:
|
|
5
5
|
types: [opened, synchronize, ready_for_review, reopened]
|
|
6
|
-
# Optional: Only run on specific file changes
|
|
7
|
-
# paths:
|
|
8
|
-
# - "src/**/*.ts"
|
|
9
|
-
# - "src/**/*.tsx"
|
|
10
|
-
# - "src/**/*.js"
|
|
11
|
-
# - "src/**/*.jsx"
|
|
12
6
|
|
|
13
7
|
jobs:
|
|
14
8
|
claude-review:
|
|
15
|
-
|
|
16
|
-
# if: |
|
|
17
|
-
# github.event.pull_request.user.login == 'external-contributor' ||
|
|
18
|
-
# github.event.pull_request.user.login == 'new-developer' ||
|
|
19
|
-
# github.event.pull_request.author_association == 'FIRST_TIME_CONTRIBUTOR'
|
|
20
|
-
|
|
9
|
+
if: github.event.pull_request.head.repo.full_name == github.repository
|
|
21
10
|
runs-on: ubuntu-latest
|
|
22
11
|
permissions:
|
|
23
12
|
contents: read
|
|
24
|
-
pull-requests:
|
|
25
|
-
issues:
|
|
26
|
-
id-token: write
|
|
13
|
+
pull-requests: write
|
|
14
|
+
issues: write
|
|
27
15
|
|
|
28
16
|
steps:
|
|
29
17
|
- name: Checkout repository
|
|
30
|
-
uses: actions/checkout@
|
|
18
|
+
uses: actions/checkout@v6
|
|
31
19
|
with:
|
|
32
20
|
fetch-depth: 1
|
|
33
21
|
|
|
@@ -36,9 +24,21 @@ jobs:
|
|
|
36
24
|
uses: anthropics/claude-code-action@v1
|
|
37
25
|
with:
|
|
38
26
|
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
27
|
+
prompt: |
|
|
28
|
+
REPO: ${{ github.repository }}
|
|
29
|
+
PR NUMBER: ${{ github.event.pull_request.number }}
|
|
30
|
+
|
|
31
|
+
Please review this pull request with a focus on:
|
|
32
|
+
- Code quality and best practices
|
|
33
|
+
- Potential bugs or issues
|
|
34
|
+
- Security implications
|
|
35
|
+
- Performance considerations
|
|
36
|
+
|
|
37
|
+
Note: The PR branch is already checked out in the current working directory.
|
|
38
|
+
|
|
39
|
+
Use `gh pr comment` for top-level feedback.
|
|
40
|
+
Use `mcp__github_inline_comment__create_inline_comment` to highlight specific code issues.
|
|
41
|
+
Only post GitHub comments - don't submit review text as messages.
|
|
44
42
|
|
|
43
|
+
claude_args: |
|
|
44
|
+
--allowedTools "mcp__github_inline_comment__create_inline_comment,Bash(gh pr comment:*),Bash(gh pr diff:*),Bash(gh pr view:*)"
|
|
@@ -24,6 +24,8 @@ jobs:
|
|
|
24
24
|
issues: read
|
|
25
25
|
id-token: write
|
|
26
26
|
actions: read # Required for Claude to read CI results on PRs
|
|
27
|
+
checks: read
|
|
28
|
+
statuses: read
|
|
27
29
|
steps:
|
|
28
30
|
- name: Checkout repository
|
|
29
31
|
uses: actions/checkout@v4
|
|
@@ -34,11 +36,14 @@ jobs:
|
|
|
34
36
|
id: claude
|
|
35
37
|
uses: anthropics/claude-code-action@v1
|
|
36
38
|
with:
|
|
39
|
+
github_token: ${{ github.token }}
|
|
37
40
|
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
|
|
38
41
|
|
|
39
42
|
# This is an optional setting that allows Claude to read CI results on PRs
|
|
40
43
|
additional_permissions: |
|
|
41
44
|
actions: read
|
|
45
|
+
checks: read
|
|
46
|
+
statuses: read
|
|
42
47
|
|
|
43
48
|
# Optional: Give a custom prompt to Claude. If this is not specified, Claude will perform the instructions specified in the comment that tagged it.
|
|
44
49
|
# prompt: 'Update the pull request description to include a summary of changes.'
|
data/CHANGELOG.md
CHANGED
|
@@ -11,8 +11,31 @@
|
|
|
11
11
|
|
|
12
12
|
Changes since the last non-beta release.
|
|
13
13
|
|
|
14
|
+
### Security
|
|
15
|
+
|
|
16
|
+
- Removed default `Access-Control-Allow-Origin: *` header from dev server configuration. This header allowed any website to access dev server resources. **If your setup runs webpack-dev-server on a different port from your Rails server, uncomment the `headers` section in `config/shakapacker.yml` to restore cross-origin asset loading.** [PR #936](https://github.com/shakacode/shakapacker/pull/936) by [justin808](https://github.com/justin808). Fixes [#935](https://github.com/shakacode/shakapacker/issues/935).
|
|
17
|
+
|
|
18
|
+
### Added
|
|
19
|
+
|
|
20
|
+
- **Added `SKIP=true` installer mode to preserve existing files**. [PR #926](https://github.com/shakacode/shakapacker/pull/926) by [justin808](https://github.com/justin808). Running `rails shakapacker:install SKIP=true` now skips conflicting files instead of overwriting them. This is useful for CI/CD pipelines and automated setups where you want to install only missing files without touching existing configuration.
|
|
21
|
+
- **Export bundler utility functions for Webpack/Rspack compatibility**. [PR #922](https://github.com/shakacode/shakapacker/pull/922) by [justin808](https://github.com/justin808). New utility functions that make it easier to write bundler-agnostic configuration code: `isRspack`, `isWebpack`, `getBundler()`, `getCssExtractPlugin()`, `getCssExtractPluginLoader()`, `getDefinePlugin()`, `getEnvironmentPlugin()`, and `getProvidePlugin()`. Users no longer need to write conditional logic to handle differences between Webpack and Rspack.
|
|
22
|
+
|
|
23
|
+
```javascript
|
|
24
|
+
// Before: manual conditional logic
|
|
25
|
+
const { config } = require("shakapacker")
|
|
26
|
+
const CssPlugin =
|
|
27
|
+
config.assets_bundler === "rspack"
|
|
28
|
+
? require("@rspack/core").CssExtractRspackPlugin
|
|
29
|
+
: require("mini-css-extract-plugin")
|
|
30
|
+
|
|
31
|
+
// After: use bundler utilities
|
|
32
|
+
const { getCssExtractPlugin } = require("shakapacker")
|
|
33
|
+
const CssPlugin = getCssExtractPlugin()
|
|
34
|
+
```
|
|
35
|
+
|
|
14
36
|
### Changed
|
|
15
37
|
|
|
38
|
+
- Allow `compression-webpack-plugin` v12. [PR #937](https://github.com/shakacode/shakapacker/pull/937) by [G-Rath](https://github.com/G-Rath).
|
|
16
39
|
- **BREAKING: sass-loader now defaults to modern Sass API**. [PR #879](https://github.com/shakacode/shakapacker/pull/879) by [justin808](https://github.com/justin808). The sass-loader configuration now uses `api: "modern"` instead of the deprecated legacy API. This improves compatibility with plugins like sass-resources-loader that require the modern API. If you experience issues after upgrading, you can revert to the legacy API by customizing your webpack config:
|
|
17
40
|
|
|
18
41
|
```javascript
|
|
@@ -36,9 +59,16 @@ Changes since the last non-beta release.
|
|
|
36
59
|
|
|
37
60
|
### Fixed
|
|
38
61
|
|
|
62
|
+
- **Fixed hidden dotfiles and dot-directories being treated as entrypoints**. [PR #915](https://github.com/shakacode/shakapacker/pull/915) by [justin808](https://github.com/justin808). Entry discovery now ignores files and directories whose names start with `.` when traversing `source_entry_path`, preventing unintended bundles from being created. Closes [#853](https://github.com/shakacode/shakapacker/issues/853).
|
|
39
63
|
- **Fixed orphaned webpack/rspack processes when foreman receives SIGTERM**. [PR #888](https://github.com/shakacode/shakapacker/pull/888) by [jordan-brough](https://github.com/jordan-brough). When running under foreman, sending SIGTERM to foreman (e.g. `kill <pid>`) would kill the Ruby shakapacker process but leave the webpack/rspack child process running as an orphan. DevServerRunner now uses `exec` to replace the Ruby process entirely, and Runner uses `spawn` with SIGTERM forwarding to ensure the child process is properly terminated.
|
|
64
|
+
- **Fixed missing-environment fallback to use production instead of development**. [PR #894](https://github.com/shakacode/shakapacker/pull/894) by [justin808](https://github.com/justin808). When a Rails environment (e.g., staging) is not defined in `shakapacker.yml`, Shakapacker now falls back to the `production` configuration instead of `development`. This ensures unknown environments get production-optimized webpack/rspack builds by default.
|
|
40
65
|
- **Fixed installer writing wrong shakapacker version in package.json**. [PR #899](https://github.com/shakacode/shakapacker/pull/899) by [justin808](https://github.com/justin808). The `shakapacker:install` generator now keeps the `package.json` dependency value in sync with the exact version or path that was requested, instead of relying on the post-install value which could differ.
|
|
66
|
+
- **Fixed installer not updating `shakapacker.yml` when selecting a non-default transpiler**. [PR #895](https://github.com/shakacode/shakapacker/pull/895) by [codex-rs](https://github.com/apps/codex-rs). Installing with `JAVASCRIPT_TRANSPILER=babel` (or `esbuild`) now correctly updates `config/shakapacker.yml` to match the selected transpiler instead of leaving it set to `swc`. Previously, a quote mismatch in the `gsub_file` call meant the config was never actually updated, and the condition also excluded `JAVASCRIPT_TRANSPILER=babel` from the update entirely. Additionally, `JAVASCRIPT_TRANSPILER=babel` no longer installs SWC packages.
|
|
67
|
+
- **Fixed ENOENT crash on clean builds when using `webpack-assets-manifest` v6 with `merge: true`**. [PR #931](https://github.com/shakacode/shakapacker/pull/931) by [justin808](https://github.com/justin808). Seeds an empty `{}` manifest file before instantiating the plugin, so the merge read succeeds on first build rather than throwing an unhandled ENOENT.
|
|
68
|
+
- **Improved error message when manifest is empty or missing**. [PR #872](https://github.com/shakacode/shakapacker/pull/872) by [justin808](https://github.com/justin808). When the bundler is still compiling (empty manifest) or hasn't run yet (missing manifest file), users now see clear, actionable error messages instead of the generic 7-point checklist.
|
|
41
69
|
- **Fixed NODE_ENV=test causing DefinePlugin warnings**. [PR #870](https://github.com/shakacode/shakapacker/pull/870) by [justin808](https://github.com/justin808). When RAILS_ENV=test, Shakapacker now sets NODE_ENV=development instead of NODE_ENV=test. This prevents webpack/rspack DefinePlugin conflicts since these bundlers only recognize "development" and "production" as valid NODE_ENV values.
|
|
70
|
+
- **Fixed `--json` flag output being corrupted by log messages**. [PR #869](https://github.com/shakacode/shakapacker/pull/869) by [justin808](https://github.com/justin808). When `--json` is in the command arguments, `[Shakapacker]` log messages are now written to stderr instead of stdout, keeping stdout clean for valid JSON output. This allows `bin/shakapacker --profile --json` to be piped to tools like `webpack-bundle-analyzer`. Normal (non-JSON) usage is unchanged. Resolves [#868](https://github.com/shakacode/shakapacker/issues/868).
|
|
71
|
+
- **Require explicit truthy values for `SKIP` and `FORCE` installer env vars**. [PR #926](https://github.com/shakacode/shakapacker/pull/926) by [justin808](https://github.com/justin808). Previously, any set value (including `"false"` or `"0"`) would activate skip/force mode. Now only explicit truthy values (`true`, `1`, `yes`, case-insensitive) are recognized. This behavior change may require CI/scripts that relied on `FORCE=<any non-empty value>` to switch to `FORCE=true`.
|
|
42
72
|
|
|
43
73
|
### Documentation
|
|
44
74
|
|
data/CLAUDE.md
CHANGED
|
@@ -40,6 +40,14 @@
|
|
|
40
40
|
- **Version management**: Run `bundle exec rake update_changelog` after releases to update version headers
|
|
41
41
|
- **Examples**: Run `grep -A 3 "^### " CHANGELOG.md | head -30` to see real formatting examples
|
|
42
42
|
|
|
43
|
+
## Open Source Maintainability
|
|
44
|
+
|
|
45
|
+
- **Prefer removing complexity over adding configuration.** If a default causes problems, consider removing the default rather than adding an option to disable it.
|
|
46
|
+
- **Every config option is maintenance surface.** Prefer convention over configuration. Don't add options for <10% of users — let them customize via existing extension points (e.g., custom webpack config).
|
|
47
|
+
- **"No is temporary, yes is forever."** Adding a feature creates a permanent maintenance obligation. Reject features that solve one user's niche problem but add complexity for everyone.
|
|
48
|
+
- **Security-safe defaults over convenient defaults.** Don't ship permissive defaults (e.g., `Access-Control-Allow-Origin: *`) just for convenience — make users opt in to less-secure configurations.
|
|
49
|
+
- **Don't refactor adjacent code in feature PRs.** Keep PRs focused. If you spot something to clean up, do it in a separate PR.
|
|
50
|
+
|
|
43
51
|
## Shakapacker-Specific
|
|
44
52
|
|
|
45
53
|
- This gem supports both webpack and rspack configurations
|
data/README.md
CHANGED
|
@@ -166,7 +166,7 @@ Then run the following to install Shakapacker:
|
|
|
166
166
|
bundle exec rake shakapacker:install
|
|
167
167
|
```
|
|
168
168
|
|
|
169
|
-
Before initiating the installation process, ensure you have committed all
|
|
169
|
+
Before initiating the installation process, ensure you have committed all changes. During install, Shakapacker may encounter conflicts with existing files. You can approve prompts interactively, use `FORCE=true` to overwrite without prompting, or use `SKIP=true` to preserve existing files and only create missing ones. Accepted truthy values are `true`, `1`, and `yes` (case-insensitive). If both are set, `FORCE` takes precedence.
|
|
170
170
|
|
|
171
171
|
Shakapacker uses the [`package_json`](https://github.com/shakacode/package_json) gem to handle updating the `package.json` and interacting with the underlying package manager of choice for managing dependencies and running commands; the package manager is managed using the [`packageManager`](https://nodejs.org/api/packages.html#packagemanager) property in the `package.json`, otherwise falling back to the value of `PACKAGE_JSON_FALLBACK_MANAGER` if set or otherwise `npm`.
|
|
172
172
|
|
data/docs/configuration.md
CHANGED
|
@@ -362,9 +362,11 @@ dev_server:
|
|
|
362
362
|
# pathname: '/ws'
|
|
363
363
|
# port: 8080
|
|
364
364
|
|
|
365
|
-
#
|
|
366
|
-
|
|
367
|
-
|
|
365
|
+
# Custom headers for dev server responses
|
|
366
|
+
# Uncomment to enable CORS (e.g., when webpack-dev-server runs on a different
|
|
367
|
+
# port than your Rails server and the browser blocks cross-origin asset requests):
|
|
368
|
+
# headers:
|
|
369
|
+
# "Access-Control-Allow-Origin": "*"
|
|
368
370
|
|
|
369
371
|
# Static file serving
|
|
370
372
|
static:
|
data/docs/precompile_hook.md
CHANGED
|
@@ -35,13 +35,13 @@ before launching long-running processes instead of using `precompile_hook`.
|
|
|
35
35
|
|
|
36
36
|
### Comparison
|
|
37
37
|
|
|
38
|
-
| Aspect
|
|
39
|
-
|
|
40
|
-
| Best for
|
|
41
|
-
| Runs when
|
|
42
|
-
| Production integration
|
|
43
|
-
| Process manager complexity | Lower
|
|
44
|
-
| Debugging
|
|
38
|
+
| Aspect | `precompile_hook` | Explicit setup in `bin/dev` |
|
|
39
|
+
| -------------------------- | ------------------------------------- | --------------------------------------- |
|
|
40
|
+
| Best for | Default/consistent pre-build tasks | Custom multi-step dev boot flows |
|
|
41
|
+
| Runs when | Immediately before compilation starts | Wherever you place it in startup script |
|
|
42
|
+
| Production integration | Automatic via `assets:precompile` | Requires explicit production wiring |
|
|
43
|
+
| Process manager complexity | Lower | Higher (you own orchestration) |
|
|
44
|
+
| Debugging | Centralized hook command | Fully explicit command-by-command flow |
|
|
45
45
|
|
|
46
46
|
### `shakapacker_precompile` Interaction
|
|
47
47
|
|
data/eslint.config.js
CHANGED
|
@@ -233,6 +233,7 @@ module.exports = [
|
|
|
233
233
|
// Remaining utils files that need type safety improvements
|
|
234
234
|
// These use dynamic requires and helper functions that return `any`
|
|
235
235
|
files: [
|
|
236
|
+
"package/utils/bundlerUtils.ts",
|
|
236
237
|
"package/utils/inliningCss.ts",
|
|
237
238
|
"package/utils/errorCodes.ts",
|
|
238
239
|
"package/utils/errorHelpers.ts",
|
data/lib/install/binstubs.rb
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
|
-
|
|
1
|
+
require "shakapacker/install/env"
|
|
2
|
+
|
|
3
|
+
# template.rb sets @conflict_option first during normal install flow.
|
|
4
|
+
# ||= keeps binstubs runnable standalone (e.g., rake shakapacker:binstubs).
|
|
5
|
+
@conflict_option ||= Shakapacker::Install::Env.conflict_option
|
|
2
6
|
|
|
3
7
|
say "Copying binstubs"
|
|
4
|
-
directory "#{__dir__}/bin", "bin",
|
|
8
|
+
directory "#{__dir__}/bin", "bin", @conflict_option
|
|
5
9
|
|
|
6
10
|
chmod "bin", 0755 & ~File.umask, verbose: false
|
|
@@ -161,8 +161,10 @@ development:
|
|
|
161
161
|
allowed_hosts: "auto"
|
|
162
162
|
# Shows progress and colorizes output of bin/shakapacker[-dev-server]
|
|
163
163
|
pretty: true
|
|
164
|
-
|
|
165
|
-
|
|
164
|
+
# Uncomment to enable CORS (e.g., when webpack-dev-server runs on a different
|
|
165
|
+
# port than your Rails server and the browser blocks cross-origin asset requests):
|
|
166
|
+
# headers:
|
|
167
|
+
# "Access-Control-Allow-Origin": "*"
|
|
166
168
|
static:
|
|
167
169
|
watch:
|
|
168
170
|
ignored: "**/node_modules/**"
|
data/lib/install/template.rb
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
require "shakapacker/utils/misc"
|
|
2
2
|
require "shakapacker/utils/manager"
|
|
3
3
|
require "shakapacker/utils/version_syntax_converter"
|
|
4
|
+
require "shakapacker/install/env"
|
|
4
5
|
require "package_json"
|
|
5
6
|
require "yaml"
|
|
6
7
|
require "json"
|
|
7
8
|
|
|
8
9
|
# Install Shakapacker
|
|
9
10
|
|
|
10
|
-
|
|
11
|
+
@conflict_option = Shakapacker::Install::Env.conflict_option
|
|
11
12
|
|
|
12
13
|
# Initialize variables for use throughout the template
|
|
13
14
|
# Using instance variable to avoid method definition issues in Rails templates
|
|
@@ -19,25 +20,33 @@ install_dir = File.expand_path(File.dirname(__FILE__))
|
|
|
19
20
|
# - Otherwise install only the specified transpiler
|
|
20
21
|
if ENV["USE_BABEL_PACKAGES"] == "true" || ENV["USE_BABEL_PACKAGES"] == "1"
|
|
21
22
|
@transpiler_to_install = "babel"
|
|
23
|
+
@install_swc_compat_packages = true
|
|
22
24
|
say "📦 Installing Babel packages (USE_BABEL_PACKAGES is set)", :yellow
|
|
23
25
|
say "✨ Also installing SWC packages for default config compatibility", :green
|
|
24
26
|
elsif ENV["JAVASCRIPT_TRANSPILER"]
|
|
25
27
|
@transpiler_to_install = ENV["JAVASCRIPT_TRANSPILER"]
|
|
28
|
+
@install_swc_compat_packages = false
|
|
26
29
|
say "📦 Installing #{@transpiler_to_install} packages", :blue
|
|
27
30
|
else
|
|
28
31
|
# Default to swc (matches the default in shakapacker.yml)
|
|
29
32
|
@transpiler_to_install = "swc"
|
|
33
|
+
@install_swc_compat_packages = false
|
|
30
34
|
say "✨ Installing SWC packages (20x faster than Babel)", :green
|
|
31
35
|
end
|
|
32
36
|
|
|
33
37
|
# Copy config file
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
38
|
+
shakapacker_config_preexisting = Rails.root.join("config/shakapacker.yml").exist?
|
|
39
|
+
copy_file "#{install_dir}/config/shakapacker.yml", "config/shakapacker.yml", @conflict_option
|
|
40
|
+
|
|
41
|
+
# Update config to match the selected transpiler
|
|
42
|
+
# Skip modification only when SKIP mode preserved a pre-existing user file
|
|
43
|
+
if Shakapacker::Install::Env.update_transpiler_config?(
|
|
44
|
+
transpiler_to_install: @transpiler_to_install,
|
|
45
|
+
conflict_option: @conflict_option,
|
|
46
|
+
config_preexisting: shakapacker_config_preexisting
|
|
47
|
+
)
|
|
48
|
+
gsub_file "config/shakapacker.yml", 'javascript_transpiler: "swc"', "javascript_transpiler: \"#{@transpiler_to_install}\""
|
|
49
|
+
say " 📝 Updated config/shakapacker.yml to use #{@transpiler_to_install} transpiler", :green
|
|
41
50
|
end
|
|
42
51
|
|
|
43
52
|
# Detect TypeScript usage
|
|
@@ -53,7 +62,7 @@ source_config = "#{install_dir}/config/#{assets_bundler}/#{config_file}"
|
|
|
53
62
|
dest_config = "config/#{assets_bundler}/#{config_file}"
|
|
54
63
|
|
|
55
64
|
empty_directory "config/#{assets_bundler}"
|
|
56
|
-
copy_file source_config, dest_config,
|
|
65
|
+
copy_file source_config, dest_config, @conflict_option
|
|
57
66
|
|
|
58
67
|
if @use_typescript
|
|
59
68
|
say " ✨ Using TypeScript config for enhanced type safety", :green
|
|
@@ -223,22 +232,21 @@ Dir.chdir(Rails.root) do
|
|
|
223
232
|
# Inline the logic here since methods can't be called before they're defined in Rails templates
|
|
224
233
|
|
|
225
234
|
# Install transpiler-specific dependencies
|
|
226
|
-
# When USE_BABEL_PACKAGES is set, install both babel AND swc
|
|
227
|
-
# This ensures backward compatibility while supporting the default config
|
|
228
235
|
if @transpiler_to_install == "babel"
|
|
229
236
|
# Install babel packages
|
|
230
237
|
babel_deps = PackageJson.read(install_dir).fetch("babel")
|
|
231
238
|
peers = peers.merge(babel_deps)
|
|
232
239
|
|
|
233
|
-
# Also install SWC
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
240
|
+
# Also install SWC only when USE_BABEL_PACKAGES requested compatibility mode.
|
|
241
|
+
if @install_swc_compat_packages
|
|
242
|
+
swc_deps = PackageJson.read(install_dir).fetch("swc")
|
|
243
|
+
peers = peers.merge(swc_deps)
|
|
237
244
|
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
245
|
+
say "ℹ️ Installing both Babel and SWC packages for compatibility:", :blue
|
|
246
|
+
say " - Babel packages are installed as requested via USE_BABEL_PACKAGES", :blue
|
|
247
|
+
say " - SWC packages are also installed to ensure the default config works", :blue
|
|
248
|
+
say " - Your actual transpiler will be determined by your shakapacker.yml configuration", :blue
|
|
249
|
+
end
|
|
242
250
|
elsif @transpiler_to_install == "swc"
|
|
243
251
|
swc_deps = PackageJson.read(install_dir).fetch("swc")
|
|
244
252
|
peers = peers.merge(swc_deps)
|
data/lib/shakapacker/env.rb
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
class Shakapacker::Env
|
|
2
|
+
FALLBACK_ENV = "production".freeze
|
|
3
|
+
|
|
2
4
|
delegate :config_path, :logger, to: :@instance
|
|
3
5
|
|
|
4
6
|
def self.inquire(instance)
|
|
@@ -11,7 +13,7 @@ class Shakapacker::Env
|
|
|
11
13
|
|
|
12
14
|
def inquire
|
|
13
15
|
fallback_env_warning if config_path.exist? && !current
|
|
14
|
-
current ||
|
|
16
|
+
current || FALLBACK_ENV.inquiry
|
|
15
17
|
end
|
|
16
18
|
|
|
17
19
|
private
|
|
@@ -20,7 +22,7 @@ class Shakapacker::Env
|
|
|
20
22
|
end
|
|
21
23
|
|
|
22
24
|
def fallback_env_warning
|
|
23
|
-
logger.info "RAILS_ENV=#{Rails.env} environment is not defined in #{config_path}, falling back to #{
|
|
25
|
+
logger.info "RAILS_ENV=#{Rails.env} environment is not defined in #{config_path}, falling back to #{FALLBACK_ENV} environment"
|
|
24
26
|
end
|
|
25
27
|
|
|
26
28
|
def available_environments
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
module Shakapacker
|
|
2
|
+
module Install
|
|
3
|
+
module Env
|
|
4
|
+
TRUTHY_VALUES = %w[true 1 yes].freeze
|
|
5
|
+
|
|
6
|
+
module_function
|
|
7
|
+
|
|
8
|
+
def truthy_env?(name)
|
|
9
|
+
TRUTHY_VALUES.include?(ENV[name].to_s.downcase)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def conflict_option
|
|
13
|
+
if truthy_env?("FORCE")
|
|
14
|
+
{ force: true }
|
|
15
|
+
elsif truthy_env?("SKIP")
|
|
16
|
+
{ skip: true }
|
|
17
|
+
else
|
|
18
|
+
{}
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# Preserve existing shakapacker.yml when SKIP mode is active, but still
|
|
23
|
+
# update newly-copied files on fresh installs.
|
|
24
|
+
def update_transpiler_config?(transpiler_to_install:, conflict_option:, config_preexisting:)
|
|
25
|
+
return false if transpiler_to_install == "swc"
|
|
26
|
+
return true if conflict_option[:force]
|
|
27
|
+
return true unless conflict_option[:skip]
|
|
28
|
+
|
|
29
|
+
!config_preexisting
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
data/lib/shakapacker/manifest.rb
CHANGED
|
@@ -33,6 +33,10 @@ class Shakapacker::Manifest
|
|
|
33
33
|
# Raised when an asset cannot be found in the manifest
|
|
34
34
|
class MissingEntryError < StandardError; end
|
|
35
35
|
|
|
36
|
+
# Holds the result of loading the manifest file, keeping data and
|
|
37
|
+
# file-existence state in a single atomic value.
|
|
38
|
+
LoadResult = Struct.new(:data, :manifest_existed, keyword_init: true)
|
|
39
|
+
|
|
36
40
|
delegate :config, :compiler, :dev_server, to: :@instance
|
|
37
41
|
|
|
38
42
|
# Creates a new manifest instance
|
|
@@ -50,7 +54,8 @@ class Shakapacker::Manifest
|
|
|
50
54
|
#
|
|
51
55
|
# @return [Hash] the loaded manifest data
|
|
52
56
|
def refresh
|
|
53
|
-
@
|
|
57
|
+
@load_result = load
|
|
58
|
+
@load_result.data
|
|
54
59
|
end
|
|
55
60
|
|
|
56
61
|
# Looks up an entry point with all its chunks (split code)
|
|
@@ -132,14 +137,19 @@ class Shakapacker::Manifest
|
|
|
132
137
|
Shakapacker.logger.tagged("Shakapacker") { compiler.compile }
|
|
133
138
|
end
|
|
134
139
|
|
|
135
|
-
def
|
|
140
|
+
def load_result
|
|
136
141
|
if config.cache_manifest?
|
|
137
|
-
@
|
|
142
|
+
@load_result ||= load
|
|
138
143
|
else
|
|
139
144
|
refresh
|
|
145
|
+
@load_result
|
|
140
146
|
end
|
|
141
147
|
end
|
|
142
148
|
|
|
149
|
+
def data
|
|
150
|
+
load_result.data
|
|
151
|
+
end
|
|
152
|
+
|
|
143
153
|
def find(name)
|
|
144
154
|
return nil unless data[name.to_s].present?
|
|
145
155
|
|
|
@@ -155,14 +165,27 @@ class Shakapacker::Manifest
|
|
|
155
165
|
end
|
|
156
166
|
|
|
157
167
|
def handle_missing_entry(name, pack_type)
|
|
158
|
-
|
|
168
|
+
# @load_result is always set by the preceding data call (even in
|
|
169
|
+
# non-cached mode), so we read it directly to avoid a second file read.
|
|
170
|
+
result = @load_result
|
|
171
|
+
|
|
172
|
+
# An empty data hash covers both a 0-byte / whitespace-only manifest file
|
|
173
|
+
# and a missing manifest file. Either way the bundler has not produced
|
|
174
|
+
# usable output yet, so we show a targeted "unavailable" message.
|
|
175
|
+
if result.data.empty?
|
|
176
|
+
raise Shakapacker::Manifest::MissingEntryError, manifest_unavailable_error(result)
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
raise Shakapacker::Manifest::MissingEntryError, missing_file_from_manifest_error(full_pack_name(name, pack_type[:type]), result.data)
|
|
159
180
|
end
|
|
160
181
|
|
|
161
182
|
def load
|
|
162
183
|
if config.manifest_path.exist?
|
|
163
|
-
|
|
184
|
+
contents = config.manifest_path.read
|
|
185
|
+
parsed = contents.strip.empty? ? {} : JSON.parse(contents)
|
|
186
|
+
LoadResult.new(data: parsed, manifest_existed: true)
|
|
164
187
|
else
|
|
165
|
-
{}
|
|
188
|
+
LoadResult.new(data: {}, manifest_existed: false)
|
|
166
189
|
end
|
|
167
190
|
end
|
|
168
191
|
|
|
@@ -181,21 +204,59 @@ class Shakapacker::Manifest
|
|
|
181
204
|
end
|
|
182
205
|
end
|
|
183
206
|
|
|
184
|
-
def missing_file_from_manifest_error(bundle_name)
|
|
207
|
+
def missing_file_from_manifest_error(bundle_name, manifest_data)
|
|
185
208
|
bundler_name = config.assets_bundler
|
|
186
|
-
|
|
187
|
-
Shakapacker can't find #{bundle_name} in #{config.manifest_path}. Possible causes:
|
|
188
|
-
1. You forgot to install javascript packages or are running an incompatible javascript runtime version
|
|
189
|
-
2. Your app has code with a non-standard extension (like a `.jsx` file) but the extension is not in the `extensions` config in `config/shakapacker.yml`
|
|
190
|
-
3. You have set compile: false (see `config/shakapacker.yml`) for this environment
|
|
191
|
-
|
|
192
|
-
4. Your #{bundler_name} has not yet FINISHED running to reflect updates.
|
|
193
|
-
5. You have misconfigured Shakapacker's `config/shakapacker.yml` file.
|
|
194
|
-
6. Your #{bundler_name} configuration is not creating a manifest with the expected structure.
|
|
195
|
-
7. Ensure the 'assets_bundler' in config/shakapacker.yml is set correctly (currently: #{bundler_name}).
|
|
196
|
-
|
|
197
|
-
Your manifest contains:
|
|
198
|
-
#{JSON.pretty_generate(
|
|
209
|
+
<<~MSG
|
|
210
|
+
Shakapacker can't find #{bundle_name} in #{config.manifest_path}. Possible causes:
|
|
211
|
+
1. You forgot to install javascript packages or are running an incompatible javascript runtime version
|
|
212
|
+
2. Your app has code with a non-standard extension (like a `.jsx` file) but the extension is not in the `extensions` config in `config/shakapacker.yml`
|
|
213
|
+
3. You have set compile: false (see `config/shakapacker.yml`) for this environment
|
|
214
|
+
(unless you are using the `bin/shakapacker -w` or the `bin/shakapacker-dev-server`, in which case maybe you aren't running the dev server in the background?)
|
|
215
|
+
4. Your #{bundler_name} has not yet FINISHED running to reflect updates.
|
|
216
|
+
5. You have misconfigured Shakapacker's `config/shakapacker.yml` file.
|
|
217
|
+
6. Your #{bundler_name} configuration is not creating a manifest with the expected structure.
|
|
218
|
+
7. Ensure the 'assets_bundler' in config/shakapacker.yml is set correctly (currently: #{bundler_name}).
|
|
219
|
+
|
|
220
|
+
Your manifest contains:
|
|
221
|
+
#{JSON.pretty_generate(manifest_data)}
|
|
199
222
|
MSG
|
|
200
223
|
end
|
|
224
|
+
|
|
225
|
+
def manifest_unavailable_error(result)
|
|
226
|
+
bundler_name = config.assets_bundler
|
|
227
|
+
|
|
228
|
+
if result.manifest_existed
|
|
229
|
+
<<~MSG
|
|
230
|
+
Shakapacker manifest is empty. #{bundler_name} is likely still compiling.
|
|
231
|
+
|
|
232
|
+
This typically happens when:
|
|
233
|
+
1. You just started the dev server and it's still compiling
|
|
234
|
+
2. The dev server crashed during startup
|
|
235
|
+
3. #{bundler_name} compilation hasn't completed yet
|
|
236
|
+
|
|
237
|
+
What to do:
|
|
238
|
+
- Wait a few seconds and refresh the page
|
|
239
|
+
- Check your terminal for #{bundler_name} build progress
|
|
240
|
+
- Look for errors in the #{bundler_name} output
|
|
241
|
+
|
|
242
|
+
Manifest path: #{config.manifest_path}
|
|
243
|
+
MSG
|
|
244
|
+
else
|
|
245
|
+
<<~MSG
|
|
246
|
+
Shakapacker manifest file not found. #{bundler_name} has not yet built assets.
|
|
247
|
+
|
|
248
|
+
This typically happens when:
|
|
249
|
+
1. You haven't started the dev server yet
|
|
250
|
+
2. The compile process hasn't created the manifest file
|
|
251
|
+
3. The manifest_path configuration is incorrect
|
|
252
|
+
|
|
253
|
+
What to do:
|
|
254
|
+
- Start the dev server: bin/shakapacker-dev-server
|
|
255
|
+
- Or run a manual build: bin/shakapacker
|
|
256
|
+
- Verify manifest_path in config/shakapacker.yml
|
|
257
|
+
|
|
258
|
+
Expected manifest path: #{config.manifest_path}
|
|
259
|
+
MSG
|
|
260
|
+
end
|
|
261
|
+
end
|
|
201
262
|
end
|