Asterisks - Pre-compilation of an offline asset
I am trying to make sprokets compile a separate standalone js resource, so it will guess and minify it and become part of all rails projects.
I need this js to have a name without a digest, so it won't change (i.e. built into other websites, etc.)
I cannot get the rails (4) / stars to fulfill my bets.
What I have tried:
-
Adding resource (
script.js
) in misc folder overrides assets / javascripts and does not load it into javascript sprockets manifest. While this keeps it in the project, it doesn't get fading and minimizing, and it doesn't automatically load through activation. -
Tried adding another manifest named
scripts-manifest.js
to the//= require script.js
asset to add its path to the precompilation path inapplication.rb
but the problem is that rails 4 add the digest to all assets no matter how work in rails 3) -
Tried using https://github.com/alexspeller/non-stupid-digest-assets to add unimportant asset version. I may have done it wrong, as it doesn't work or does nothing.
I add an initializer
NonStupidDigestAssets.whitelist = ["script.js"]
and try to put it in app / assets / javascripts / misc and publicly / but it still doesn't work /
I have read that this stone should help in most cases and I am sure I am doing something wrong with or without path definition somewhere
source to share
One way to do this is to add an initializer that generates the compiled versions directly.
- Add js file to a subfolder in
/app/assets/javascripts
. Do not include this inapplication.js
lest it get added to compiled assets. -
Create an initializer in
/config/initializers
that uglify uses directlyoutput_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) }
-
Include a public js file (in this example :)
/public/public_script.js
in your app layout
This way you have direct access to make custom changes to uglify handles your js and the file location never changes for your external services to access them.
I did all of this locally and verified that it was working with the Rails 4.2 beta
source to share
how would you do it with rails 4 do the following:
- add it to the precompilation list
config.assets.precompile += %w(your_file_name.js)
- make sure it is not listed in
application.js
(directly or viarequire_tree
) - symlink the digested file on deployment
- read
manifest.yml
to get the actual filename -
ln -s digested-filename.js actual-filename.js
- read
since rails 4, the generation of undigested assets has been removed (for good reasons) and this is a simple and straightforward way to implement the desired behavior.
source to share
Just wanted to add my own solution based on 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 dump the file in javascripts/application.js
. as we probably don't want it to be compiled with the rest of our JS and we can keep using //= require_tree .
:
//= stub non_digest/external_bookmarklet
source to share