You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Fix NoMethodError when environment is missing from shakapacker.yml (#669)
Why
Deploying to staging/custom environments crashed with nil error.
Summary
Added configuration fallback (production) and fixed NODE_ENV
assignment for custom environments like staging.
Key improvements
- Configuration falls back to production for undefined environments
- NODE_ENV auto-set to production for staging and custom environments
- Added logging when fallback occurs for easier debugging
Impact
Existing: No change for standard dev/test/production setups
New: Staging and custom environments work without explicit config
Risks
None. Graceful fallback maintains backward compatibility.
Copy file name to clipboardExpand all lines: CHANGELOG.md
+11-1Lines changed: 11 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -11,7 +11,17 @@
11
11
12
12
Changes since the last non-beta release.
13
13
14
-
_No unreleased changes._
14
+
### Fixed
15
+
16
+
- Fixed NoMethodError when custom environment (e.g., staging) is not defined in shakapacker.yml. [PR #669](https://github.com/shakacode/shakapacker/pull/669) by [justin808](https://github.com/justin808).
17
+
- When deploying to environments like Heroku staging with `RAILS_ENV=staging`, shakapacker would crash with `undefined method 'deep_symbolize_keys' for nil:NilClass`
18
+
-**Configuration fallback:** Now properly falls back to production environment configuration (appropriate for staging)
19
+
-**NODE_ENV handling:**`bin/shakapacker` now automatically sets `NODE_ENV=production` for custom environments (staging, etc.)
20
+
- Previously: `RAILS_ENV=staging` would set `NODE_ENV=development`, breaking webpack optimizations
21
+
- Now: `RAILS_ENV` in `[development, test]` uses that value for `NODE_ENV`, everything else uses `production`
22
+
- Logs informational message when falling back to help with debugging
23
+
- This ensures shakapacker works with any Rails environment even if not explicitly defined in shakapacker.yml
Copy file name to clipboardExpand all lines: docs/deployment.md
+52-8Lines changed: 52 additions & 8 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -3,8 +3,6 @@
3
3
Shakapacker hooks up a new `shakapacker:compile` task to `assets:precompile`, which gets run whenever you run `assets:precompile`.
4
4
If you are not using Sprockets `shakapacker:compile` is automatically aliased to `assets:precompile`.
5
5
6
-
```
7
-
8
6
## Heroku
9
7
10
8
In order for your Shakapacker app to run on Heroku, you'll need to do a bit of configuration before hand.
@@ -19,13 +17,59 @@ git push heroku master
19
17
20
18
We're essentially doing the following here:
21
19
22
-
* Creating an app on Heroku
23
-
* Creating a Postgres database for the app (this is assuming that you're using Heroku Postgres for your app)
24
-
* Adding the Heroku NodeJS and Ruby buildpacks for your app. This allows the `npm` or `yarn` executables to properly function when compiling your app - as well as Ruby.
25
-
* Pushing your code to Heroku and kicking off the deployment
20
+
- Creating an app on Heroku
21
+
- Creating a Postgres database for the app (this is assuming that you're using Heroku Postgres for your app)
22
+
- Adding the Heroku NodeJS and Ruby buildpacks for your app. This allows the `npm` or `yarn` executables to properly function when compiling your app - as well as Ruby.
23
+
- Pushing your code to Heroku and kicking off the deployment
26
24
27
25
Your production build process is responsible for installing your JavaScript dependencies before `rake assets:precompile`. For example, if you are on Heroku, the `heroku/nodejs` buildpack must run **prior** to the `heroku/ruby` buildpack for precompilation to run successfully.
28
26
27
+
### Custom Rails Environments (e.g., staging)
28
+
29
+
**Key distinction:**
30
+
31
+
-**RAILS_ENV** is used to look up configuration in `config/shakapacker.yml`
32
+
-**NODE_ENV** is used by your `webpack.config.js` (or `rspack.config.js`) for build optimizations
33
+
34
+
**Good news:** As of this version, `bin/shakapacker` automatically sets `NODE_ENV=production` for custom environments like staging:
35
+
36
+
```bash
37
+
# NODE_ENV automatically set to 'production' for staging
This omission resulted in an error in the browser:
36
+
35
37
```
36
38
Failed to load resource: net::ERR_CONTENT_DECODING_FAILED
37
39
```
@@ -40,6 +42,40 @@ The error was caused by an old version of the peer dependency `webpack-compressi
40
42
41
43
So, be sure to investigate warnings from `yarn install`!
42
44
45
+
## NoMethodError: undefined method 'deep_symbolize_keys' for nil:NilClass
46
+
47
+
If you see this error during deployment (especially on Heroku with a staging environment):
48
+
49
+
```
50
+
NoMethodError: undefined method 'deep_symbolize_keys' for nil:NilClass
51
+
from shakapacker/configuration.rb:XXX:in 'load'
52
+
```
53
+
54
+
This happens when deploying to a custom Rails environment (like `staging`) that isn't explicitly defined in your `config/shakapacker.yml` file.
55
+
56
+
**Solution:** This was fixed in Shakapacker v9.1.1+. Upgrade to the latest version:
57
+
58
+
```ruby
59
+
# Gemfile
60
+
gem 'shakapacker', '~> 9.1'
61
+
```
62
+
63
+
After upgrading, Shakapacker will automatically fall back to sensible defaults when your environment isn't defined:
64
+
65
+
1. First tries your environment (e.g., `staging`)
66
+
2. Falls back to `production` configuration
67
+
68
+
**Alternative:** If you can't upgrade immediately, explicitly add your environment to `config/shakapacker.yml`:
69
+
70
+
```yaml
71
+
staging:
72
+
<<: *default
73
+
compile: false
74
+
cache_manifest: true
75
+
```
76
+
77
+
See the [deployment guide](./deployment.md#custom-rails-environments-eg-staging) for more details.
78
+
43
79
## ENOENT: no such file or directory - node-sass
44
80
45
81
If you get the error `ENOENT: no such file or directory - node-sass` on deploy with
@@ -54,7 +90,7 @@ thing, like Heroku.
54
90
55
91
However, if you get this on local development, or not during a deploy then you
56
92
may need to rebuild `node-sass`. It's a bit of a weird error; basically, it
57
-
can't find the `node-sass` binary. An easy solution is to create a postinstall
93
+
can't find the `node-sass` binary. An easy solution is to create a postinstall
58
94
hook to ensure `node-sass` is rebuilt whenever new modules are installed.
59
95
60
96
In `package.json`:
@@ -67,19 +103,18 @@ In `package.json`:
67
103
68
104
## Can't find hello_react.js in manifest.json
69
105
70
-
* If you get this error `Can't find hello_react.js in manifest.json`
71
-
when loading a view in the browser it's because webpack is still compiling packs.
72
-
Shakapacker uses a `manifest.json` file to keep track of packs in all environments,
73
-
however since this file is generated after packs are compiled by webpack. So,
74
-
if you load a view in browser whilst webpack is compiling you will get this error.
75
-
Therefore, make sure webpack
76
-
(i.e `./bin/shakapacker-dev-server`) is running and has
77
-
completed the compilation successfully before loading a view.
78
-
106
+
- If you get this error `Can't find hello_react.js in manifest.json`
107
+
when loading a view in the browser it's because webpack is still compiling packs.
108
+
Shakapacker uses a `manifest.json` file to keep track of packs in all environments,
109
+
however since this file is generated after packs are compiled by webpack. So,
110
+
if you load a view in browser whilst webpack is compiling you will get this error.
111
+
Therefore, make sure webpack
112
+
(i.e `./bin/shakapacker-dev-server`) is running and has
113
+
completed the compilation successfully before loading a view.
79
114
80
115
## throw er; // Unhandled 'error' event
81
116
82
-
* If you get this error while trying to use Elm, try rebuilding Elm. You can do
117
+
-If you get this error while trying to use Elm, try rebuilding Elm. You can do
83
118
so with a postinstall hook in your `package.json`:
84
119
85
120
```json
@@ -90,9 +125,9 @@ completed the compilation successfully before loading a view.
90
125
91
126
## webpack or webpack-dev-server not found
92
127
93
-
* This could happen if `shakapacker:install` step is skipped. Please run `bundle exec rails shakapacker:install` to fix the issue.
128
+
-This could happen if `shakapacker:install` step is skipped. Please run `bundle exec rails shakapacker:install` to fix the issue.
94
129
95
-
* If you encounter the above error on heroku after upgrading from Rails 4.x to 5.1.x, then the problem might be related to missing `yarn` binstub. Please run following commands to update/add binstubs:
130
+
-If you encounter the above error on heroku after upgrading from Rails 4.x to 5.1.x, then the problem might be related to missing `yarn` binstub. Please run following commands to update/add binstubs:
This error occurs because you are trying to minify by `terser` a pack that's already been minified by Shakapacker. To avoid this conflict and prevent appearing of `ExecJS::RuntimeError` error, you will need to disable uglifier from Rails config:
@@ -225,7 +264,7 @@ application is using your staging `config.asset_host` host when using
225
264
226
265
This can be fixed by setting the environment variable `SHAKAPACKER_ASSET_HOST` to
227
266
an empty string where your assets are compiled. On Heroku this is done under
228
-
*Settings* -> *Config Vars*.
267
+
_Settings_ -> _Config Vars_.
229
268
230
269
This way shakapacker won't hard-code the CDN host into the manifest file used by
231
270
`javascript_pack_tag`, but instead fetch the CDN host at runtime, resolving the
@@ -243,6 +282,7 @@ In order to generate the storage path, we rely on the filename that's [provided
243
282
This usually works out of the box. There's a potential problem however, if you use the [context setting](https://webpack.js.org/configuration/entry-context/#context) in your webpack config. By default this is set to current Node working directory/project root.
@@ -252,12 +292,14 @@ If you were to override it like:
252
292
Then the filename available in the rule generator will be relative to that directory.
253
293
254
294
This means for example:
295
+
255
296
- a static asset from `node_modules` folder could end up being referenced with path of `../../node_modules/some_module/static_file.jpg` rather than simply `node_modules/some_module/static_file.jpg`.
256
297
- a static asset in one of the `additional_paths`, example `app/assets/images/image.jpg`, would end up being referenced with path of `../assets/images/image.jpg`.
257
298
258
299
Those paths are later passed to [output path generation in the rule](https://github.com/shakacode/shakapacker/blob/e52b335dbabfb934fe7d3076a8322b97d5ef3470/package/rules/file.js#L25-L26), where we would end up with a path like `static/../../node_modules/some_module/static_file.jpg`, resulting in the file being output in a location two directories above the desired path.
259
300
260
301
You can avoid this by:
302
+
261
303
- not using overridden `context` in your webpack config, if there's no good reason for it.
262
304
- using custom Webpack config to modify the static file rule, following a similar process as outlined in the [Webpack Configuration](https://github.com/shakacode/shakapacker/blob/main/README.md#webpack-configuration) section of the readme.
0 commit comments