Rails Webpacker compile error on Production enviorment - ruby-on-rails

env
Rails 6.0.0
Ruby 2.6.0
Amazon Linux2
What
When I deploy my rails app this error happen
ActionView::Template::Error (Webpacker can't find application in /home/web/www/eloop-regular/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.
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.
my config/webpacker.yml contains
production:
<<: *default
# Production depends on precompilation of packs prior to booting for performance.
compile: true
# Extract and emit a css file
extract_css: true
# Cache manifest.json for performance
cache_manifest: true
2. webpack has not yet re-run to reflect updates.
I run
$ RAILS_ENV=production bundle exec rails webpacker:compile
3. You have misconfigured Webpacker's config/webpacker.yml file.
in development environment webpacker works correctly.
4. Your webpack configuration is not creating a manifest.
manifest.json is created

I have the same issue when I run pre-built rails 6 app.Found out it is because of Webpack version inconsistency in yarn.lock file.
Then when I run
yarn add #rails/webpacker
bundle update webpacker
as found in this comment , issue's solved.

Remove Webpacker:
rm -rf bin/webpack*
Install Webpacker:
rails webpacker:install
Compile by Webpacker in production mode:
RAILS_ENV=production rails webpacker:compile
About this

I'd the same problem. Just run in development environment:
rails webpacker:install
If you use Docker, run:
docker exec rails-app-name rails webpacker:install

If the manifest.json does not exist in your filesystem create it with rake assets:precompile.

For me what worked was to replace
<%= stylesheet_pack_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
with <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
In the application.html.erb file

Related

Rails cssbundling, TailwindCSS and Sass in production

Need
I need both Sass and TailwindCSS to work in parallel for our project (Rails 7 deployed on Heroku).
Current setup
# Procfile
release: rake db:migrate
web: bundle exec puma -C config/puma.rb
worker: bundle exec sidekiq -C config/sidekiq.yml
css: yarn build:css
sass: yarn build:sass
js: yarn build
// package.json
{
// ...
"scripts": {
"build": "...",
"build:css": "tailwindcss -i ./path/to/input.css -o ./path/to/output1.css",
"build:sass": "sass ./path/to/input.sass.scss:./path/to/output2.css"
}
}
<!-- application.html.erb -->
<%= stylesheet_link_tag 'tailwind', 'data-turbo-track': 'reload' %>
<%= stylesheet_link_tag 'application', 'data-turbo-track': 'reload' %>
Problem
Locally, everything works just fine. But when I try to push this to production, my Sass code disappears.
I found out in cssbundling gem's docs that it was due to:
When you deploy your application to production, the css:build task attaches to the assets:precompile task to ensure that all your package dependencies from package.json have been installed via yarn, and then runs yarn build:css to process your stylesheet entrypoint, as it would in development.
Solution(?)
So I changed for only one script calling the other ones:
// package.json
{
// ...
"scripts": {
"build": "...",
"build:css": "yarn build:sass & yarn build:tailwind",
"build:css-watch": "yarn build:sass --watch & yarn build:tailwind --watch"
"build:tailwind": "tailwindcss -i ./path/to/input.css -o ./path/to/output1.css",
"build:sass": "sass ./path/to/input.sass.scss:./path/to/output2.css"
}
}
Which now works in production, but for development environment, if I want to use the --watch option, the only solution I found is to create another script: build:css-watch.
Question(s)
Is my solution the best one for my problem?
If so, the build:css-watch script looks really weird to me, is there any other solution?

Rails webpacker has no packs directory

Premable: as a Rails 6.1.3 application, on deployment, I noticed that migrations were not launched, thus there may be a capistrano issue at hand.
Being an initial deployment, shared files were copied over, the database manually created, migrated and populated with a postgresql archive.
Launching the server however leads to a complaint
Webpacker can't find application.js
and in examining the directory structure, the public/packs directory is absent.
On localhost, these are created on first page call-up; but this is not occuring on a VPS.
Upon consultation of the Rails guide for webpacker neither command
bundle exec webpacker:compile nor bundle exec assets:precompile run, both with the same error:
bundler: command not found: assets:precompile
Install missing gem executables with `bundle install`
yet bundle install runs successfuly repeatedly, invoking webpacker 5.4.0.
config/webpacker.yml has
development:
<<: *default
compile: true
So this behaviour is contrary to the assertion in the guide "By default, Webpacker compiles automatically on demand in development when a Rails page loads. "
How should this be configured for proper deployment, in both development and production modes?

Rails 6 server just stopped compiling webpack

I have a really weird thing happening.
I was working on this project on my development environment and when I used to start the Rails server,
It would compile webpack on the first browser request.
Now, all the sudden, this is not happening, causing all the javascript and style to fail and the app is not rendered properly.
The Rails server console does not even show the [Webpacker] Compiling… line
If I start the webpack-dev-server myself, it works. But for some reason the rails server has just stopped doing it on its own. I have changed the line webpack_compile_output: false to true in webpacker.yml but the rails server still doesn't show anything that has to do with Webpack.
It's really strange. I haven't added any gems or updated any versions of node or webpack. I did update Git globally on my machine from version 1.9 to version 2.24 but that's about it.
Any ideas?
Update: (As Requested, here is the content of my config/wenpacker.yml
default: &default
source_path: app/javascript
source_entry_path: packs
public_root_path: public
public_output_path: packs
cache_path: tmp/cache/webpacker
check_yarn_integrity: false
webpack_compile_output: true
# Additional paths webpack should lookup modules
# ['app/assets', 'engine/foo/app/assets']
resolved_paths: []
# Reload manifest.json on all requests so we reload latest compiled packs
cache_manifest: false
# Extract and emit a css file
extract_css: false
static_assets_extensions:
- .jpg
- .jpeg
- .png
- .gif
- .tiff
- .ico
- .svg
- .eot
- .otf
- .ttf
- .woff
- .woff2
extensions:
- .mjs
- .js
- .sass
- .scss
- .css
- .module.sass
- .module.scss
- .module.css
- .png
- .svg
- .gif
- .jpeg
- .jpg
development:
<<: *default
compile: true
# Verifies that correct packages and versions are installed by inspecting package.json, yarn.lock, and node_modules
check_yarn_integrity: false
# Reference: https://webpack.js.org/configuration/dev-server/
dev_server:
https: false
host: localhost
port: 3035
public: localhost:3035
hmr: false
# Inline should be set to true if using HMR
inline: false
overlay: true
compress: true
disable_host_check: true
use_local_ip: false
quiet: false
headers:
'Access-Control-Allow-Origin': '*'
watch_options:
ignored: '**/node_modules/**'
test:
<<: *default
compile: true
# Compile test packs to a separate directory
public_output_path: packs-test
production:
<<: *default
# Production depends on precompilation of packs prior to booting for performance.
compile: false
# Extract and emit a css file
extract_css: true
# Cache manifest.json for performance
cache_manifest: true
Experiencing this as well. Typically when running rails s you'll see something like this:
Started GET "/react_test/hello" for ::1 at 2020-05-15 16:54:29 -0700
Processing by ReactTestController#hello as HTML
Rendering react_test/hello.html.erb within layouts/application
[Webpacker] Everything's up-to-date. Nothing to do
If you make a change to a js (or css/scss) that are part of your webpack resources:
Processing by ReactTestController#hello as HTML
Rendering react_test/hello.html.erb within layouts/application
[Webpacker] Compiling...
[Webpacker] Compiled all packs in /Users/foo/public/packs
[Webpacker] Hash: 1ea802b336ed3c771c61
Version: webpack 4.43.0
Time: 4844ms
... truncated for brevity (a list of assets, size, etc)
At some point, all of this stops - and you'll "have" to run both rails s and ./bin/webpack-dev-server manually. So far, what I've noticed is that this is triggered when you run webpack-dev-server - e.g. when updating config/webpacker.yml - it does say it on that file itself in a note:
# Note: You must restart bin/webpack-dev-server for changes to take effect
Try this workaround:
Stop Rails server and webpack-dev-server
Make some (temporary) change to your /app/javascript/packs/application.js file
e.g. comment out an import: //import 'bootstrap'
Restart rails s (only, not webpack-dev-server)
This will error out - because it's missing what was commented out (in this example bootstrap
Undo/uncomment the temporary change
Reload the page - hopefully, it should be good (Webpack compiles, etc).
I think (guess) it's some caching/sync issue that is "fixed/(reset?)" by making some change to application.js
Hth...
If webpacker stops responding to changes in application.scss or application.js, run this command in terminal:
rails webpacker:install
So, I actually ran into this today and after reading this question and doing some additional debugging, I realized the Rails Webpacker was failing because I had another project already running Webpacker and that confused the Rails version.
Shutting down the other Webpacker and restarting the Rails server immediately fixed the issue.
This drove me nuts when trying to stimulus reflex. This worked for me (although then had another Stimiuls Reflex issue with ActionCable connection is not open! thereafter which was progress.
In terminal execute rails dev:cache which will likely disable caching
Run your rails server
Thereafter re-run rails dev:cache in terminal (after shutting rails server).
In environments/development.rb the relevent config is:
config.action_controller.perform_caching = true
config.action_controller.enable_fragment_cache_logging = true
config.cache_store = :memory_store
config.public_file_server.headers = {
'Cache-Control' => "public, max-age=#{2.days.to_i}",
}
My case was that I changed my version of node using nvm.
When everything stopped compiling, I forgot that switching my version simply uninstalled yarn which is normal, because I'm using another node/npm image and since yarn was installed globally by npm...
So:
Run bin/rails webpacker:install, it will say: "Yarn not installed. Please download and install Yarn from https://yarnpkg.com/lang/en/docs/install/
Exiting!"
Reinstall yarn using npm i -g yarn
Run your belove bin/rails s command, and you're done 🎉
Note: you'll see again [Webpacker] doing its job in your terminal ✅
I had an isse with webpacker compilation not running in the test environment on a project I hadnt touch in a while.
bundle update webpacker solved the issue. Weirdly, reverting to the old Gemfile.lock also works now so I dont know exactly what the issue was.

All assets are not loading in production envirnoment rails 5

Anything works fine while I run my server using rails s, but while I run the server in production mode it looks like:without stylesheets and other assets. What I have to do to solve that problem?
In production.rb set
config.public_file_server.enabled = true
config.assets.compile = true
Then run the server like this
RAILS_ENV=production rails assets:precompile
RAILS_ENV=production rails server
Did you precompile your assets? Try running locally:
RAILS_ENV=production bundle exec rake assets:precompile
A public/assets directory will be created and then commit changes to your repository.
The assets should now be detected on your production server.
Can you provide us with an example how you are linking to CSS and JS files? It should look like this ( this is in .haml not .erb)
= stylesheet_link_tag 'default/application', media: 'all', 'data-turbolinks-track' => true
= javascript_include_tag 'application', 'data-turbolinks-track' => true

Rails 4: assets not loading in production

I'm trying to put my app into production and image and css asset paths aren't working.
Here's what I'm currently doing:
Image assets live in /app/assets/images/image.jpg
Stylesheets live in /app/assets/stylesheets/style.css
In my layout, I reference the css file like this: <%= stylesheet_link_tag "styles", media: "all", "data-turbolinks-track" => true %>
Before restarting unicorn, I run RAILS_ENV=production bundle exec rake assets:precompile and it succeeds and I see the fingerprinted files in the public/assets directory.
When I browse to my site, I get a 404 not found error for mysite.com/stylesheets/styles.css.
What am I doing wrong?
Update:
In my layout, it looks like this:
<%= stylesheet_link_tag "bootstrap.min", media: "all", "data-turbolinks-track" => true %>
<%= stylesheet_link_tag "styles", media: "all", "data-turbolinks-track" => true %>
<%= javascript_include_tag "application", "data-turbolinks-track" => true %>
The generate source is this:
<link data-turbolinks-track="true" href="/stylesheets/bootstrap.min.css" media="all" rel="stylesheet" />
<link data-turbolinks-track="true" href="/stylesheets/styles.css" media="all" rel="stylesheet" />
<script data-turbolinks-track="true" src="/assets/application-0c647c942c6eff10ad92f1f2b0c64efe.js"></script>
Looks like Rails is not properly looking for the compiled css files. But it's very confusing why it's working correctly for javascripts (notice the /assets/****.js path).
In rails 4 you need to make the changes below:
config.assets.compile = true
config.assets.precompile = ['*.js', '*.css', '*.css.erb']
This works with me. use following command to pre-compile assets
RAILS_ENV=production bundle exec rake assets:precompile
Best of luck!
I just had the same problem and found this setting in config/environments/production.rb:
# Rails 4:
config.serve_static_assets = false
# Or for Rails 5:
config.public_file_server.enabled = false
Changing it to true got it working. It seems by default Rails expects you to have configured your front-end webserver to handle requests for files out of the public folder instead of proxying them to the Rails app. Perhaps you've done this for your javascript files but not your CSS stylesheets?
(See Rails 5 documentation). As noted in comments, with Rails 5 you may just set the RAILS_SERVE_STATIC_FILES environment variable, since the default setting is config.public_file_server.enabled = ENV['RAILS_SERVE_STATIC_FILES'].present?.
In /config/environments/production.rb I had to add this:
Rails.application.config.assets.precompile += %w( *.js ^[^_]*.css *.css.erb )
The .js was getting precompiled already, but I added it anyway. The .css and .css.erb apparently don't happen automatically. The ^[^_] excludes partials from being compiled -- it's a regexp.
It's a little frustrating that the docs clearly state that asset pipeline IS enabled by default but doesn't clarify the fact that only applies to javascripts.
I was able to solve this problem by changing:
config.assets.compile = false to
config.assets.compile = true in /config/environments/production.rb
Update (June 24, 2018): This method creates a security vulnerability if the version of Sprockets you're using is less than 2.12.5, 3.7.2, or 4.0.0.beta8
For Rails 5, you should enable the follow config code:
config.public_file_server.enabled = true
By default, Rails 5 ships with this line of config:
config.public_file_server.enabled = ENV['RAILS_SERVE_STATIC_FILES'].present?
Hence, you will need to set the environment variable RAILS_SERVE_STATIC_FILES to true.
There are 2 things you must accomplish to serve the assets in production:
Precompile the assets.
Serve the assets on the server to browser.
1) In order to precompile the assets, you have several choices.
You can run rake assets:precompile on your local machine, commit it to source code control (git), then run the deployment program, for example capistrano. This is not a good way to commit precompiled assets to SCM.
You can write a rake task that run RAILS_ENV=production rake assets:precompile on the target servers each time you deploy your Rails app to production, before you restart the server.
Code in a task for capistrano will look similar to this:
on roles(:app) do
if DEPLOY_ENV == 'production'
execute("cd #{DEPLOY_TO_DIR}/current && RAILS_ENV=production rvm #{ruby_string} do rake assets:precompile")
end
end
2) Now, you have the assets on production servers, you need to serve them to browser.
Again, you have several choices.
Turn on Rails static file serving in config/environments/production.rb
config.serve_static_assets = true # old
or
config.serve_static_files = true # new
Using Rails to serve static files will kill your Rails app performance.
Configure nginx (or Apache) to serve static files.
For example, my nginx that was configured to work with Puma looks like this:
location ~ ^/(assets|images|fonts)/(.*)$ {
alias /var/www/foster_care/current/public/$1/$2;
gzip on;
expires max;
add_header Cache-Control public;
}
Rails 4 no longer generates the non fingerprinted version of the asset: stylesheets/style.css will not be generated for you.
If you use stylesheet_link_tag then the correct link to your stylesheet will be generated
In addition styles.css should be in config.assets.precompile which is the list of things that are precompiled
change your Production.rb file line
config.assets.compile = false
into
config.assets.compile = true
and also add
config.assets.precompile = ['*.js', '*.css', '*.css.erb']
What you SHOULD NOT do:
Some of my colleagues above have recommended you to do this:
config.serve_static_assets = true ## DON”T DO THIS!!
config.public_file_server.enabled = true ## DON”T DO THIS!!
The rails asset pipeline says of the above approach:
This mode uses more memory, performs more poorly than the default and is not recommended. See here: (http://edgeguides.rubyonrails.org/asset_pipeline.html#live-compilation)
What you SHOULD do:
Precompile your assets.
RAILS_ENV=production rake assets:precompile
You can probably do that with a rake task.
I'm running Ubuntu Server 14.04, Ruby 2.2.1 and Rails 4.2.4 I have followed a deploy turorial from DigitalOcean and everything went well but when I go to the browser and enter the IP address of my VPS my app is loaded but without styles and javascript.
The app is running with Unicorn and Nginx. To fix this problem I entered my server using SSH with my user 'deployer' and go to my app path which is '/home/deployer/apps/blog' and run the following command:
RAILS_ENV=production bin/rake assets:precompile
Then I just restart the VPS and that's it!
It works for me!
Hope it could be useful for somebody else!
If precompile is set you DO NOT need
config.assets.compile = true
as this is to serve assets live.
Our problem was we only had development secret key base set in config/secrets.yml
development:
secret_key_base: '83d141eeb181032f4070ae7b1b27d9ff'
Need entry for production environment
The default matcher for compiling files includes application.js, application.css and all non-JS/CSS files (this will include all image assets automatically) from app/assets folders including your gems:
If you have other manifests or individual stylesheets and JavaScript files to include, you can add them to the precompile array in config/initializers/assets.rb:
Rails.application.config.assets.precompile += ['admin.js', 'admin.css', 'swfObject.js']
http://guides.rubyonrails.org/asset_pipeline.html#precompiling-assets
First of all check your assets, it might be possible there is some error in pre-compiling of assets.
To pre-compile assets in production ENV run this command:
RAILS_ENV=production rake assets:precompile
If it shows error, remove that first,
In case of "undefined variable" error, load that variable file before using it in another file.
example:
#import "variables";
#import "style";
in application.rb file set sequence of pre-compiliation of assets
example:
config.assets.precompile += [ 'application.js', 'admin.js', 'admin/events.js', 'admin/gallery.js', 'frontendgallery.js']
config.assets.precompile += [ 'application.css', 'admin.css','admin/events.css', 'admin/gallery.css', 'frontendgallery.css']
Found this:
The configuration option config.serve_static_assets has been renamed to config.serve_static_files to clarify its role.
in config/environments/production.rb:
# Disable serving static files from the `/public` folder by default since
# Apache or NGINX already handles this.
config.serve_static_files = ENV['RAILS_SERVE_STATIC_FILES'].present?
So set env RAILS_SERVE_STATIC_FILES or using Nginx to serving static files.
Add config.serve_static_assets = true will still work, but removed in future.
it is not recommended to let capistrano do assets precompile, because it may take ages and often time out. try to do local assets precompile.
1st, set in config/application.rb
config.assets.initialize_on_precompile = false
then do local
RAILS_ENV=production bin/rake assets:precompile
and add those public/assets to git.
and config/environments/development.rb, change your asset path to avoid using precompiled assets:
config.assets.prefix = '/dev-assets'
If you have db connection issue, means u have initializer that uses db. one way around it is to set a new environment by duplicate production.rb as maybe production2.rb, and in database.yml, add production2 environment with development db setting. then do
RAILS_ENV=production2 bin/rake assets:precompile
if you are still facing some issue with assets, for example ckeditor,
add the js file into config/initializers/assets.rb
Rails.application.config.assets.precompile += %w( ckeditor.js )
I may be wrong but those who recommend changing
config.assets.compile = true
The comment on this line reads: #Do not fallback to assets pipeline if a precompiled asset is missed.
This suggests that by setting this to true you are not fixing the problem but rather bypassing it and running the pipeline every time. This must surely kill your performance and defeat the purpose of the pipeline?
I had this same error and it was due to the application running in a sub folder that rails didn't know about.
So my css file where in home/subfolder/app/public/.... but rails was looking in home/app/public/...
try either moving your app out of the subfolder or telling rails that it is in a subfolder.
location ~ ^/assets/ {
expires 1y;
add_header Cache-Control public;
add_header ETag "";
}
This fixed the problem for me in production. Put it into the nginx config.
Even we faced the same problem where RAILS_ENV=production bundle exec rake assets:precompile succeeded but things did not work as expected.
We found that unicorn was the main culprit here.
Same as your case, even we used to restart unicorn after compiling the assets. It was noticed that when unicorn is restarted, only its worker processes are restarted and not the master process.
This is the main reason the correct assets are not served.
Later, after compiling assets, we stopped and started unicorn so that the unicorn master process is also restarted and the correct assets were getting served.
Stopping and starting unicorn brings around 10 secs on downtime when compared to restarting the unicorn. This is the workaround that can be used where as long term solution is move to puma from unicorn.

Resources