I'm trying to extract all vendor assets into separate file and serve them as a minified and combined file also in development environment. I could do that in Rails 3 by using debug: false
in javascript_link_tag
and stylesheet_link_tag
helpers like this:
<%= stylesheet_link_tag "vendor", :media => "all", :debug => false %>
<%= stylesheet_link_tag "application", :media => "all" %>
<%= javascript_include_tag "vendor", :debug => false %>
<%= javascript_include_tag "application" %>
That made Rails to serve me vendor.js
and vendor.css
as a minified and combined assets even in development environment. application.js
and application.css
were served as usually in development environment.
I can not achieve similar results in Rails 4, because if using the lines above, then this will be generated into html for every asset specified in vendor
assets:
<script debug="false"... ><script>
How to achieve the same thing in Rails 4?
I have written a detailed blog post for Rails 3 about this feature at my blog. You can check it out if my question is not clear enough http://itreallymatters.net/post/45763483826/speeding-up-page-load-time-in-rails
To compile your assets locally, run the assets:precompile task locally on your app. Make sure to use the production environment so that the production version of your assets are generated. A public/assets directory will be created. Inside this directory you'll find a manifest.
rails assets:precompile is the task that does the compilation (concatenation, minification, and preprocessing). When the task is run, Rails first looks at the files in the config.assets.precompile array. By default, this array includes application.js and application.css .
The asset pipeline provides a framework to concatenate and minify or compress JavaScript and CSS assets. It also adds the ability to write these assets in other languages such as CoffeeScript, Sass and ERB. Prior to Rails 3.1 these features were added through third-party Ruby libraries such as Jammit and Sprockets.
Overall: Its a regression with Sprockets 2. Read on for an explanation and solution.
Assume you have a file called vendor.js
with the following:
# vendor.js
//= require jquery
//= require knockout
//= ... some more requires
function one() { }
function two() { }
// and some javascript code
First, let's see what the Asset Debugging does:
Places a single <script src="vendor.js">
tag if debugging is disabled,
(or)
Places multiple <script src="vendor.js?body=1">, <script src="jquery.js?body=1">, <script src="knockout.js?body=1">, ...
when debugging is enabled
The body=1
is also an integral part of debugging. If you say <script src="vendor.js?body=1">
- it only renders the javascript inside vendor.js
. It doesn't include any of the other require ...
code.
But if you hit vendor.js
alone, without the ?body=1
, it includes all the require ...
code as well.
So a combination of the above two produce the necessary debugging output. What we want to do is, when we say javascript_include_tag "vendor", :debug => false
, we want a single <script src="vendor.js">
tag with NO ?body=1
appended.
The regressed code is here. Specifically the buggy code is this one statement:
L88. if request_debug_assets?
Its checking request_debug_assets?, and then automatically setting :debug => true
further in line #92. But request_debug_assets?
is returning true, because that is being set at the application configuration level.
This one statement should have ideally been:
L88. if request_debug_assets? && options["debug"] != false
I'll raise a pull request for the same, but until the pull request is reviewed and merged, you can do the following in an initializer:
# config/initializers/sprockets_debug_patch.rb
module Sprockets::Rails::Helper
def javascript_include_tag(*sources)
options = sources.extract_options!.stringify_keys
# CHECK options["debug"] as well, not just the global assets.debug
if request_debug_assets? && options["debug"] != false
# REST ALL SAME CODE AS ORIGINAL METHOD
Do the same for stylesheet_include_tag
as well. Unfortunately there is no better way than copy/pasting the method code, but this resolves the problem.
Throughout Sprockets::Rails::Helper
class, you will find that it says all this will be deprecated in Sprockets 3.x. I don't know if Rails 4 is scheduled to ship with Sprockets 3.x. If so, then these patches might end up not being required.
Another option if you don't want to use monkeypatch right now and you are just trying to work with your app without worrying about all of you assets is to set / change
config.assets.debug = false
config.assets.compress = false
in config/development.rb
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With