Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

sprockets - precompiling a standalone asset

I am trying to make sprokets compile a single standalone js asset, so it will uglify and minify it and be part of the entire rails projects.

I need that this js to have a non-digest name, so it's will not change (i.e. embedded in other websites, etc)

I can't seem to force rails (4) /sprockets to do my bidding.

What I tried:

  1. Adding the asset (script.js) in a misc folder unders assets/javascripts and not load it in the sprockets javascript manifest. While this keeps it in the project, it doesn't get uglified and minified, and doesn't get automatically loaded via asset-sync.

  2. Tried adding another manifest called scripts-manifest.js to //= require script.js asset, to add its path in the precompile path in application.rb, but the problem is that rails 4 adds digest to all assets no matter what (doesn't work like that in rails 3)

  3. Tried using https://github.com/alexspeller/non-stupid-digest-assets to add a non digest version of the asset. I may have done it incorrectly, as it doesn't work or do anything..

    I add the initializer NonStupidDigestAssets.whitelist = ["script.js"] and tried putting it in app/assets/javascripts/misc and in public/ but it still won't work/

I have read that this gem should help in most cases, and I am sure I am doing something wrong with either path definition or no including it somewhere

like image 574
Nick Ginanto Avatar asked Mar 19 '26 09:03

Nick Ginanto


2 Answers

One way to do this is to add an initializer that generates the compiled versions directly.

  1. Add your js file to a subfolder in /app/assets/javascripts. Don't include this in application.js so it isn't added to the compiled assets.
  2. Create an initializer in /config/initializers that uses uglify directly

    output_file = "#{Rails.root}/public/public_script.js"

    input_file = "#{Rails.root}/app/assets/javascripts/non_digest/public_script.js"

    uglified = Uglifier.compile(File.read(input_file))

    File.open(output_file, 'w') {|f| f.write(uglified) }

  3. Include the public js file (in this example: /public/public_script.js) in your application layout

This way you have direct access to make custom changes to how uglify handles your js and the location of the file never changes for your external services accessing them.

I did all this locally and tested that it worked using the beta version of Rails 4.2

like image 67
Ken Stipek Avatar answered Mar 21 '26 21:03

Ken Stipek


Just wanted to add my own solution based off Ken's answer.

I created non_digest.rb in config/initializers:

Dir["#{Rails.root}/app/assets/javascripts/non_digest/*"].each do |asset|
  asset_name = File.basename(asset)
  asset_output = "#{Rails.root}/public/external/#{asset_name}"
  asset_uglified = Uglifier.compile(File.read(asset))

  File.open(asset_output, 'w') {|a| a.write(asset_uglified) }
end

Don't forget to stub the file in javascripts/application.js. as we probably don't want it compiled with the rest of our JS and we can continue to use //= require_tree .:

//= stub non_digest/external_bookmarklet

like image 37
Thomas Taylor Avatar answered Mar 21 '26 23:03

Thomas Taylor



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!