Why Webpacker Wouldn't Compile Assets in a Specific Environment
- April 13, 2020
packs directory and loaded it up via
Locally, things worked great! But once I deployed, integration tests running in the CI pipeline would unexpectedly fail, even though the same tests were passing on my machine. After some time spent troubleshooting, it turned out to be one primary issue, which was drawn out by my misunderstanding of how Webpacker loads configuration settings for an environment. This is a quick review of the entire debugging process.
As Rails is running a request and the
manifest.json file in order to load the correct assets. If that file doesn’t exist, Rails vomits. This is the sort of error you’ll see:
ActionView::Template::Error: Webpacker can't find some-script in /my/app/path/public/packs/manifest.json. Possible causes: 1\. You want to set webpacker.yml value of compile to true for your environment unless you are using the `webpack -w` or the webpack-dev-server. 2\. webpack has not yet re-run to reflect updates. 3\. You have misconfigured Webpacker's config/webpacker.yml file. 4\. Your webpack configuration is not creating a manifest.
This made sense. Upon deploy, Webpacker was apparently not being told to compile assets before requests were made or as they were made, and so that file was never getting correctly generated.
In all of my environments except
production, I wanted to set
true, so that on each request, Rails would check to see if it needs to compile assets before continuing. Instead of duplicating this change in my
test environments, I opted to make it the default, since
production already had it explicitly set to
default: &default compile: true development: <<: *default # other settings... test: <<: *default # other settings... production: <<: *default compile: false # other settings...
I felt good about this… until it failed.
After some brief internal rage, I noticed a particular log that I must have passed over earlier:
RAILS_ENV=build environment is not defined in config/webpacker.yml, falling back to production environment
My tests were being run in the
build environment — not
test. And as it turns out, Webpacker will fall back
production if it can’t find the specified environment. This is why my assets weren’t being compiled. A
build environment wasn’t set in my Webpacker configuration file, so it was falling back to
production, which was explicitly telling Webpacker to not compile assets.
Like most bugs that tempt you to rip your hair out, the solution turned out to be two lines:
build: <<: *default
Sure, enough. All was green after that change.
What bit me here is some assumptions I made about how Webpacker loaded a configuration. The amount of time dealing with the consequences of those assumptions might have been avoided if I had been just a little more thorough in reading through the error logs. Don’t make this mistake yourself!