Assets not compiling - ruby-on-rails

This is driving me crazy - changes to css on my rails site only update when I run rake assets:precompile.
Does anyone know how to fix this, so assets will get compiled as they are changed?
I have a hunch the issue is in this config/environments/development.rb file:
Rails.application.configure do
# Settings specified here will take precedence over those in config/application.rb.
config.assets.compile = true
# In the development environment your application's code is reloaded on
# every request. This slows down response time but is perfect for development
# since you don't have to restart the web server when you make code changes.
config.cache_classes = false
# Do not eager load code on boot.
config.eager_load = false
# Show full error reports and disable caching.
config.consider_all_requests_local = true
config.action_controller.perform_caching = false
# Care if the mailer can't send.
config.action_mailer.raise_delivery_errors = true
# Print deprecation notices to the Rails logger.
config.active_support.deprecation = :log
config.action_mailer.delivery_method = :smtp
config.action_mailer.perform_deliveries = true
config.action_mailer.default_url_options = { :host => "http://localhost:3000/" }
# SMTP settings for gmail
config.action_mailer.smtp_settings = {
address: 'smtp.gmail.com',
port: 587,
domain: 'gmail.com',
user_name: ENV['gmail_username'],
password: ENV['gmail_password'],
authentication: 'plain',
enable_starttls_auto: true
}
# Raise an error on page load if there are pending migrations.
config.active_record.migration_error = :page_load
# Debug mode disables concatenation and preprocessing of assets.
# This option may cause significant delays in view rendering with a large
# number of complex assets.
config.assets.debug = true
# Asset digests allow you to set far-future HTTP expiration dates on all assets,
# yet still be able to expire them through the digest params.
config.assets.digest = true
# Adds additional error checking when serving assets at runtime.
# Checks for improperly declared sprockets dependencies.
# Raises helpful error messages.
config.assets.raise_runtime_errors = true
# Raises error for missing translations
# config.action_view.raise_on_missing_translations = true
end
Here is the top of my assets/stylesheets/application.css file:
/*
* This is a manifest file that'll be compiled into application.css, which will include all the files
* listed below.
*
* Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
* or any plugin's vendor/assets/stylesheets directory can be referenced here using a relative path.
*
* You're free to add application wide styles to this file and they'll appear at the bottom of the
* compiled file so the styles you add here take precedence over styles defined in any styles
* defined in the other CSS/SCSS files in this directory. It is generally better to create a new
* file per style scope.
*
*= require_tree .
*= require_self
*/
As well as the top of application.js:
// This is a manifest file that'll be compiled into application.js, which will include all the files
// listed below.
//
// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
// or any plugin's vendor/assets/javascripts directory can be referenced here using a relative path.
//
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
// compiled file.
//
// Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details
// about supported directives.
//
//= require jquery
//= require jquery_ujs
//= require_tree .
Edit: I should add that this only became a problem once I removed bootstrap...

To solve the issue:
rake assets:clobber
OR
delete the public/assets folder
From the comments above: Assets not compiling

Related

Webpack / Webpacker not serving styles with RSpec tests. webpack-dev-server not configured?

I'm new to webpack and clearly missing something here. This seemed to be working until we upgraded our app to rails 6.1 and webpacker 5.4. yarn --version webpack outputs 1.22.10
Everything appears to get served correctly in the development environment. In the test environment some assets appear to get served(like some images and some react templates) but no styles are served and the app is totally unstyled.
One thing I noticed is that if I leave webpack-dev-server off in development mode, I get the same issue as test gets. This makes me think that the test env is not configured properly to work with webpack-dev-server but so far I cannot figure out how to connect them
The app has assets in two locations: app/assets and app/frontend
One interesting thing that I noticed is that the public/packs directory looks very different from the public/packs-test directory` although I can't see any reason why that should be true.
public/packs has a single file in it : manifest.json
public/packs-test has a ton of chunk files in it
Here is the relevant config
webpacker.yml
---
# Note: You must restart bin/webpack-dev-server for changes to take effect
default: &default
source_path: app/frontend
source_entry_path: packs
public_output_path: packs
cache_path: tmp/cache/webpacker
resolved_paths: ['app/assets', 'vendor/assets']
# Reload manifest.json on all requests so we reload latest compiled packs
cache_manifest: false
extensions:
- .erb
- .jsx
- .js
- .sass
- .scss
- .css
- .module.sass
- .module.scss
- .module.css
- .png
- .svg
- .gif
- .jpeg
- .jpg
- .json
development:
<<: *default
compile: true
# Reference: https://webpack.js.org/configuration/dev-server/
dev_server:
https: true
host: localhost
port: 3035
public: localhost:3035
hmr: true
# Inline should be set to true if using HMR
inline: true
overlay: true
compress: true
disable_host_check: true
use_local_ip: false
quiet: false
headers:
'Access-Control-Allow-Origin': '*'
watch_options:
ignored: /node_modules/
aggregateTimeout: 300
poll: 500
test:
<<: *default
compile: true
public_output_path: packs-test
production: &production
<<: *default
compile: false
cache_manifest: true
webstaging:
<<: *production
webtest:
<<: *production
webdev:
<<: *production
config/webpack/environment.js
const { environment } = require('#rails/webpacker')
const erbLoader = require('./loaders/erb')
const svgLoader = require('./loaders/svg')
const addCommonsChunkPlugins = require('./plugins/commons-chunk')
const injectIndividualStylesheets = require('./individual-stylesheets')
// Set shorter hashes
environment.config.set('output.filename', '[name]-[hash:6].js')
environment.config.set('output.chunkFilename', '[name]-[chunkhash:6].chunk.js')
// More readable classnames for css modules
const cssLoader = environment.loaders
.get('moduleCss')
.use.find(el => el.loader === 'css-loader')
cssLoader.options.localIdentName = '[local]_[hash:base64:5]'
// Manually add any ES6 targeted vendor dependencies
// converts /node_modules/ to /node_modules(?!\/my-es6-targeted-module)/
const babelLoader = environment.loaders.get('babel')
const newExcludePattern = new RegExp(`${babelLoader.exclude.source}(?!\/better-youtube-api)`)
babelLoader.exclude = newExcludePattern
// Add erb loader (for images.js.erb)
environment.loaders.append('erb', erbLoader)
// Load svg files differently from css and js files
environment.loaders.insert('svg', svgLoader, { after: 'file' })
// Exclude svg extension from file loader
const fileLoader = environment.loaders.get('file')
fileLoader.exclude = /\.(svg)$/i
// Add commons chunk plugin for extracting common shared modules
addCommonsChunkPlugins(environment)
// Add individual stylesheets to webpack entries
injectIndividualStylesheets(environment)
module.exports = environment
config/webpack/development.js
process.env.NODE_ENV = process.env.NODE_ENV || 'development'
const environment = require('./environment')
module.exports = environment.toWebpackConfig()
config/webpack/test.js
process.env.NODE_ENV = process.env.NODE_ENV || 'development'
const environment = require('./environment')
module.exports = environment.toWebpackConfig()
Rails.application.configure do
# Settings specified here will take precedence over those in config/application.rb.
config.action_mailer.default_url_options = { host: "localhost", port: 3000 }
Rails.application.routes.default_url_options[:host] = 'localhost:3000'
config.force_ssl = true
# The test environment is used exclusively to run your application's
# test suite. You never need to work with it otherwise. Remember that
# your test database is "scratch space" for the test suite and is wiped
# and recreated between test runs. Don't rely on the data there!
config.cache_classes = true
# Do not eager load code on boot. This avoids loading your whole application
# just for the purpose of running a single test. If you are using a tool that
# preloads Rails for running tests, you may have to set it to true.
config.eager_load = false
# Configure public file server for tests with Cache-Control for performance.
config.public_file_server.enabled = true
config.public_file_server.headers = {
'Cache-Control' => "public, max-age=#{1.hour.seconds.to_i}"
}
# Separate file storage in the test environment
config.active_storage.service = :test
# Use inline job processing to make things happen immediately
config.active_job.queue_adapter = :inline
# Show full error reports and disable caching.
config.consider_all_requests_local = true
config.action_controller.perform_caching = false
# Raise exceptions instead of rendering exception templates.
config.action_dispatch.show_exceptions = false
# Disable request forgery protection in test environment.
config.action_controller.allow_forgery_protection = true
config.action_mailer.perform_caching = false
# Tell Action Mailer not to deliver emails to the real world.
# The :test delivery method accumulates sent emails in the
# ActionMailer::Base.deliveries array.
config.action_mailer.delivery_method = :test
# Print deprecation notices to the stderr.
config.active_support.deprecation = :stderr
# Raises error for missing translations
# config.action_view.raise_on_missing_translations = true
config.x.enable_gtm = false
end
I would be extremely grateful for any insite as I have been fighting this for a while
I still don't really know what was going on here or if it was resolvable but upgrading my webpack (not webpacker) version along with many sub dependencies solved this for me.

Rails Production log dont update

I'm using Rails 6.0.3
In production I try to run a tail -f on the production log and I don't receive updates when I do any action on the application. Any idea?
I tried to apply 0644 permissions to the production.log file, but that's not the problem, because there is data in the file.
I am using nginx and puma too.
Production Log:
Production log file permissions
-rw-rw-r-- 1 ubuntu ubuntu 733 Apr 25 11:44 production.log
production.rb
Rails.application.configure do
# Settings specified here will take precedence over those in config/application.rb.
# Code is not reloaded between requests.
config.cache_classes = true
# Eager load code on boot. This eager loads most of Rails and
# your application in memory, allowing both threaded web servers
# and those relying on copy on write to perform better.
# Rake tasks automatically ignore this option for performance.
config.eager_load = true
# Full error reports are disabled and caching is turned on.
config.consider_all_requests_local = false
# Ensures that a master key has been made available in either ENV["RAILS_MASTER_KEY"]
# or in config/master.key. This key is used to decrypt credentials (and other encrypted files).
# config.require_master_key = true
# Disable serving static files from the `/public` folder by default since
# Apache or NGINX already handles this.
config.public_file_server.enabled = ENV['RAILS_SERVE_STATIC_FILES'].present?
# Store uploaded files on the local file system (see config/storage.yml for options).
config.active_storage.service = :local
config.cache_store = :redis_cache_store, { url: "redis://localhost:6379/0" }
# Mount Action Cable outside main process or domain.
.....
# Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies.
# config.force_ssl = true
# Use the lowest log level to ensure availability of diagnostic information
# when problems arise.
config.log_level = :debug
# Prepend all log lines with the following tags.
# config.log_tags = [ :request_id ]
# Use a different cache store in production.
# config.cache_store = :mem_cache_store
config.action_mailer.perform_caching = false
# Ignore bad email addresses and do not raise email delivery errors.
# Set this to true and configure the email server for immediate delivery to raise delivery errors.
# config.action_mailer.raise_delivery_errors = false
............
# Enable locale fallbacks for I18n (makes lookups for any locale fall back to
# the I18n.default_locale when a translation cannot be found).
config.i18n.fallbacks = true
# Send deprecation notices to registered listeners.
config.active_support.deprecation = :notify
# Use default logging formatter so that PID and timestamp are not suppressed.
config.log_formatter = ::Logger::Formatter.new
# Do not dump schema after migrations.
config.active_record.dump_schema_after_migration = false
end
Thanks in advance.
I solved my problem by adding these lines to my production file:
config.logger = Logger.new (Rails.root.join ("log / production.log"))
And restarting the cougar on the production server.

javascript_include_tag inconsistent behavior

Working with Ruby 2.0 and Rails 4.0, I'm seeing a different behavior on my asset pipeline and I'm not sure why. Here's the gist of it...
I have in my ./app/assets/javascripts folder an application.js.coffee and google_analytics.js.coffee file.
In my app/views/layouts/application.html.haml, I have the following two lines:
= javascript_include_tag "application"
= javascript_include_tag "google_analytics"
This produces the following in the rendered page once deployed to production:
<script src="/assets/application-f15feb4200e0d1db4963a00b28fbe9ca.js"></script>
<script src="/javascripts/google_analytics.js"></script>
Note that the application include is compiled into the assets pipeline as expected, while the google_analytics script is not.
In development mode, everything's served from the assets pipe without the fingerprints as expected:
<script src="/assets/jquery.js?body=1"></script>
<!-- several other includes suppressed for brevity here -->
<script src="/assets/application.js?body=1"></script>
<script src="/assets/google_analytics.js?body=1"></script>
I also checked the production deployment and noted that google_analytics doesn't get pre-compiled and fingerprinted.
EDIT: After getting the comments and answers below, added the following to config/environments/production.rb and attempted another deploy:
ComingSoon::Application.configure do
config.serve_static_assets = false
config.assets.js_compressor = :uglifier
config.assets.compile = false
config.assets.digest = true
config.assets.version = '1.0'
config.assets.precompile += ['google_analytics.js.coffee']
end
Why is the sprockets assets pipeline not pre-compiling the google_analytics script and serving it up like it does the application script? how do I fix this?
You can add the google script to the precompile list in your config/environments/production.rb file on the config.assets.precompile setting. More here: What is the purpose of config.assets.precompile?
The google_analytics file needs to be added to the precompile list:
config.assets.precompile += ['google_analytics.js.coffee', ..]
Add above to your application.rb or production.rb as desired.
Note: Unless you have required the file in the application.js manifest file, through a direct require or through a require_tree, the js doesn't get compiled.

How to precompile assets and avoid "Error: file isn't precompiled" on specific pages?

When I push my code to Heroku I get the following message:
Precompiling assets failed, enabling runtime asset compilation
Runtime compilation can cause issues, so I added the following line to config/application.rb:
config.assets.initialize_on_precompile = false
(As suggested at Error pushing to heroku - aborting my rake assets:precompile and on Heroku Help )
This allows the precompilation to work. However, some of my pages include other javascript files. For example, I include a file from 'vendor/javascripts' within certain pages by putting a tag on the specific page:
<%= javascript_include_tag "src/ace.js" %>
When I visit such a page, it causes the following error (when precompiling works):
ActionView::Template::Error: src/ace.js isn't precompiled
How can I fix it so such pages do not throw errors?
You'll need to add the file to the assets.precompile.
Add the following to your config/environments/production.rb to compile all your css/js files:
config.assets.precompile = ['*.js', '*.css']
You can add your ace.js and other required files in a javascript file for instance "custom.js"
Then you can use your regular code to include the file
Add the following in custom.js. ( Assumed ace.js resides in vendor/javascripts)
//= require ace
Add the file to compilation list by adding following in application.rb
config.assets.precompile += %w( custom.js )
You can now use your javascript_tag to include the source
<%= javascript_include_tag "custom" %>

How do I use config.assets.precompile for directories rather than single files?

How do I use config.assets.precompile in production to only include the files in 'lib/assets/javascripts', 'lib/assets/stylesheets', 'vendor/assets/javascripts' and 'vendor/assets/stylesheets'?
Basically something like:
config.assets.precompile += %w( pagespecific.js anotherpage.js )
But used to auto include files in specific directories that are not 'app/assets/javascripts' or 'app/assets/stylesheets'.
*edit: adding the solution I ended up using for page specific js
config.assets.precompile += ['pages/*.js']
You can simply write it like this:
config.assets.precompile += ['directory/*']
The point of compiling assets is to build one (or a small number of) files to minimize the number of HTTP requests from the browser.
If you're going to serve each file individually, then why not just disable precompile?
To use precompile as intended, build an entire directory into one file using Sprockets' require_directory:
//= require_directory ./awesome_js_app
...and list that file in your config.assets.precompile array.
By default, all CSS is built into application.css & JS into application.js. You can add more top-level files to compile with the precompile directive in config/environments/production.rb (and other envs if you wish.) For example:
config.assets.precompile += %w( public.css public.js )
Then the Sprockets //= require ... directives in those top-level files will determine the composition of final compiled file.
You can use these additional top-level files in your layouts to have different CSS & JS for certain views.
It's probably a bit better to include this as an asset path(as per your example solution it would be):
config.assets.paths << Rails.root.join('app', 'assets', 'javascripts', 'pages')
It also allows you to include paths not in the assets directory (for example with including the bootstrap-sass). These paths are then added to your assets folder in your public directory, and pushed to your asset location if using something like asset_sync.
I found this link, and think may be it helpful for you, please see
keithgaputis's answer. Rails config.assets.precompile setting to process all CSS and JS files in app/assets
I think you can do like following.
# In production.rb
config.assets.precompile << Proc.new { |path|
if path =~ /\.(css|js)\z/
full_path = Rails.application.assets.resolve(path).to_path
app_assets_path = Rails.root.join('app', 'assets').to_path
if full_path.starts_with? app_assets_path
puts "excluding asset: " + full_path
false
else
puts "including asset: " + full_path
true
end
else
false
end
}
As of Sprockets 3 you can use a manifest.js file to declare which files or directories are precompiled. See upgrade docs. So in your config you would add:
config.assets.precompile = %w(manifest.js)
Then in app/assets/config/manifest.js you can have
//= link_directory ../pages .js
Use link_tree if you want js files in nested sub-directories to be precompiled too.

Resources