Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ruby on Rails 4.2 Asset pipeline not minifying/compressing the application-fingerprinted.js JS file

I have a ruby on Rails 4.2 app and am facing a "hair-tearing" issue for long 2 days about my asset pipeline. My prod is hosted on Heroku and I directly mention this here as I think it might be relevant I have them gem 'rails_12factor', group: :production

I read and tried the suggestions of the (too) numerous SO questions about Rails assets not compiling but none worked as I'll describe further down.

The issue observed which led me to this SO question is that my my javascript application.js file was NOT minified in production.

How do I know? the white spaces are still here, the comments have not been removed, well the applciation.js, contrary to my application.css, is just a concatenatation of all js files but NO compressing/minifying has been done.

Most questions on SO deal with issues where neither images, css or js is minified/precompilied but my situation is peculiar to the extent that images, css are precompiled/minified, but only js is a problem and is not minified.

Is there a problem with my js? (see below for some experiments I tried to find out the reason of the bug) Seems not

My set up below will show you how I deal with assets (to the extent of my beginner understanding) : I use guard to constantly monitor any change and precompile stuff and put the resulting/generated application-tr56d7.css (fingerprinted) and application-45dsugdsy67.js ((fingerprinted) inside public/assets and then when I deploy on git, it pushes all changes , including the precompiled/minified files and then when I push to Heroku, my production asset settings say to Rails to deploy my already precompiled assets. I'm a beginner and struggled with understanding all the numerous dev/prod environment assets settings but I think that is what is defined in the code you'll find further down.

I know all this process it's working because everytime i change a file when I can find a new application-tr56d7.css and a new application-45dsugdsy67.js(examples of course) (along with a new css.gz and.js.z which must be the binary stuff)

Every time I change a js file for example, guard make his job and I can read something like:

I, [2018-02-09T09:53:41.140165 #130534]  INFO -- : Writing /home/mathieu/rails_projects/my_app/public/assets/application-af0ab4a348e4f5545c844cfac02a0670.js

The new generated application.css and application.js files can then be found in public/assets folder: for example

/public/assets/application-1021e7d2ea120fe40c67ec288f1c6525.js
/public/assets/application-1021e7d2ea120fe40c67ec288f1c6525.js.gz (binary: just a list of numbers...)
/public/assets/application-753e1d0958f76ae233a460ad47606790.css
/public/assets/application-753e1d0958f76ae233a460ad47606790.css.gz (binary: just a list of numbers...)

So when I observed that in production the css was application-753e1d0958f76ae233a460ad47606790.css minified but not the application-1021e7d2ea120fe40c67ec288f1c6525.js js, I went to see on public/assets and here too I noticed the same thing:

  • the css files generated by guard such as /public/assets/application-753e1d0958f76ae233a460ad47606790.css css are minified

  • but the js files genrated by gyard are NOT minified

So I think that, but I'm not sure, it's not a Heorku specific problem, it's just that even before pushing it to Heroku, my js file hosted on public/assets should be but is not minified.

What i tried to debug this (spoiling the suspenese:all failed):

  • tried to say explicitly in assets.rb to compile application.js not work => Result: js still not minified locally and not on production website on heroku

    # It is recommended to make explicit list of assets in config/application.rb config.assets.precompile = ['application.js']

  • tried cleaning all old stuff by rake :assets clobber => Result: js still not minified locally and not on production website on heroku

  • tried cleaning old stuff by changing version assets.rb: changed => Result: js still not minified locally and not on production website on heroku

     config.assets.version = '1.0'
    

    into

     config.assets.version = '1.1'
    
  • tried to change all the various dev and prod asset settings => Result: js still not minified locally and not on production website on heroku

config.serve_static_assets = true and tried false tried also so many different settings for both files but none worked.

  • tried to compile in local and in prod => Result: js still not minified locally and not on production website on heroku

    rake assets:precompile RAILS_ENV=production --trace

Also tried local:

rake assets:precompile
  • 2 weirdest attempt: after all my attempts at making this work by modifying the asset pipeline settings which all failed, I thought maybe there 's a tricky javascript error somewhere breaking silently the minification/compressing made by guard (which also be silent in terms of page load as no error appear on chrome dev tools when i load my pages but who knows...read on some SO questions some strange effect of comments on the asset pipeline)', so I decided to comment ALL my js files inside assets/javascripts/! nothing left: and even removed the js that ends up in the pipeline but injected by a gem (so not visible in my folder app/assets/javascripts) such as jquery gem: and create 2 very basic js files that would be the only remaining files... well still : => Result: js still not minified locally and not on production website on heroku

Did again the same test as above but here went even further: I emptied (deleted all the content) of all the js files inside my assets/javascripts and removed form application.js all the gems to only leave require directory , and then created 2 very simple js files to check if it was minified now.... and still same result: js still not minified locally and not on production website on heroku

  • A test that kind of worked

doing rake assets:clobber then the push (git add, git commit, git push, git push heroku paster) DOES compile the js BUT unfortunately it creates other issues: it sends to the production an OLD version of the js (I know because i put a alert message inside the js and it's not the latest one!). What does it reveal about the bug that rake assets:clobber kind of debug it?

EDIT I made it work but with quite a demanding process: leveraging some people saying there is no compilation if you don't change css or js (see https://stackoverflow.com/a/7988689/1467802), I tweaked the previous process: (change sth in the js file, rake assets:clobber, git add, git commit, git push, git heroku master) and it works: it cpmpiles and sends the latest js file! Isn't there any way not to have to remeber eveyr time to change sth inside the js to ensure compilation ?

I'm out of ideas. Maybe my settings are just wrong and as a beginner, I'm missing something obvious.

The weirdest poart is: my cs is minified! why not the js????

My codebase

/config/environments/development.rb

MyApp::Application.configure do
 # Do not compress assets
  config.assets.compress = false

  # Expands the lines which load the assets
  config.assets.debug = true

  config.serve_static_files = false
end

/config/environments/production.rb

MyApp::Application.configure do

# Disable Rails's static asset server (Apache or nginx will already do this)
  config.serve_static_files = false

  # Compress JavaScripts and CSS
  # config.assets.compress = true removed when switch from Rails 3.2 to Rails 4
  config.assets.js_compressor  = :uglifier
  config.assets.js_compressor = Uglifier.new(
    # Remove all console.* functions
    :compress => { :drop_console => true }
  ) if defined? Uglifier
  config.assets.css_compressor = :sass

  # Don't fallback to assets pipeline if a precompiled asset is missed
  config.assets.compile = false

  # Generate digests for assets URLs
  config.assets.digest = true

  config.force_ssl = true

end

/config/initializers/assets.rb

Rails.application.configure do
  # Precompile additional assets.
  # application.js, application.css, and all non-JS/CSS in app/assets folder are already added.

  # related to deployment pb with active admin
  config.assets.precompile += %w[admin/active_admin.css admin/active_admin.js] 

  # for ckeditor: github.com/galetahub/ckeditor
  config.assets.precompile += %w( ckeditor/* )

  # Version of your assets, change this if you want to expire all your assets
  config.assets.version = '1.0'  

end

/config/application.rb

require File.expand_path('../boot', __FILE__)

require "active_record/railtie"
require "action_controller/railtie"
require "action_mailer/railtie"
require "active_resource/railtie"
require "sprockets/railtie"

if defined?(Bundler)
  # If you precompile assets before deploying to production, use this line
  Bundler.require(*Rails.groups(:assets => %w(development test)))
end

module MyApp
  class Application < Rails::Application

    config.autoload_paths += %W(#{config.root}/lib)
    # Enable the asset pipeline
    config.assets.enabled = true
  end
end

/Guardfile

# More info at https://github.com/guard/guard#readme
require 'active_support' # edded this due to a bug where guard did not load github.com/rails/rails/issues/14664
require 'active_support/core_ext'

require 'active_support/inflector'

# Make sure this guard is ABOVE any other guards using assets such as jasmine-headless-webkit
# It is recommended to make explicit list of assets in `config/application.rb`
# config.assets.precompile = ['application.js', 'application.css', 'all-ie.css']
# update dec 2014- added :runner => :cli because of a know bug on guard rail assets
# if bug is solved i can remove the part :runner=> cli
guard 'rails-assets', :run_on => [:start, :change], :runner => :cli do
  watch(%r{^app/assets/.+$})
  watch('config/application.rb')  
end

assets/javascripts/application.js

//= require jquery
//= require jquery.turbolinks
//= require jquery_ujs
//= require jquery.cookie
//= require cloudinary-jquery.min
//= require twitter/bootstrap
//= require paloma
//= require html5shiv-printshiv
//= require storageService
//= require turbolinks
//= require_directory .

Terminal process when deploying after, for example chagning some js files and waiting guard has notified me it has finished its precompilaiton job:

git add --all
git commit -a -m "fix issue with asset pipeline"
git push
git push heroku master
like image 784
Mathieu Avatar asked Feb 09 '18 09:02

Mathieu


1 Answers

I know what I am going to say is not conventional, but your aproach hasn't been so explicit, you should try adding the explicit compress call you have made false in development

/config/environments/production.rb

MyApp::Application.configure do
  # Compress assets please
  config.assets.compress = true
  # ... other stuff
end

After that clean your assets and regenerate them with

$ bundle exec rake assets:clobber
$ RAILS_ENV=production bundle exec rake assets:precompile
like image 168
ErvalhouS Avatar answered Oct 11 '22 02:10

ErvalhouS