How can I include javascript file in the rails assets pipeline? - ruby-on-rails

I have created a new ruby on rails project using the command : rails new [project_name].
Further, I want to create javascript files, so I can control my view elements.
For this, I've created a new js file and placed it in the app->assets->javascripts->apple_pay.js
Currently the appe_pay.js implementation is just for testing :
console.log("test")
Also, my application.js, used like a manifest file, looks like this :
//= require_tree .
When I run the project using rails server command, I'm expecting to see the message displayed on the console, but it's not, any ideea ?

find: config/initializers/assets.rb
Then: Rails.application.config.assets.precompile += %w[your_file.js]
noticing that as it's out of application.js you need to include it inside your views using:
javascript_include_tag :your_file
Save & Restart your server :)

If you are not install "jquery-rails" then first install the gem and require file also add in application.js
//= require file_name

Related

Why does Rails fails to boot with "Expected to find a manifest file in `app/assets/config/manifest.js` (Sprockets::Railtie::ManifestNeededError)"?

After bundle update my Rails app fails to boot with:
Expected to find a manifest file in `app/assets/config/manifest.js` (Sprockets::Railtie::ManifestNeededError)
What's happening?
Looks like you've upgraded sprockets. The later version(s) of sprockets require what's called a manifest.js file. You don't have one. You need to create one, and add in a few "directives".
Why do I need to do this?
In the old version of sprockets, big assumptions were made about what assets to bundle/concatenate** - this is what sprockets does btw.
"Sprockets, please"
bundle everything in folder abc together
bundle AND concatenate everything in folder xyz
keep admin.js separate.
Easy Steps To Solve the Problem:
Create the manifest.js file
$ mkdir -p app/assets/config
$ touch app/assets/config/manifest.js
(not the root rails directory)
Then copy and paste the following into the manifest.js file you just created:
//= link_tree ../images
//= link_directory ../javascripts .js
//= link_directory ../stylesheets .css
What are "Directives"?
Those commenty things //= are called "directives".
If you haven't done so, pls review the sprockets documentation and save yourself some headaches. Small example below:
Let's translate the //= link_directory ../javascripts .js directive:
"grab every js file in the javascripts directory, concatenate them, and keep them as SEPARATE javascript files i.e. no bundling." If you want bundling, use a different directive.
Set up your layouts template
You should also have a javascript_include_tag, which is typically placed in your application.html.erb file. If you have other files js files that are separately bundled, don't forget to add them to application.html.erb e.g.:
<%= javascript_include_tag "application", "addOtherFiles", "here", "etc", "data-turbo-track": "reload", defer: true %>
If you have a precompile array in your app/config/environments/production.rb folder (see below for an example) then perhaps you should move them over to your manifest.js if they are not already accessed above.
config.assets.precompile = ["admin.js", "admin.css"]
Presumably you will want your admin.js javascript file separate from your application.js file. No problem, just tell sprockets to keep them separate:
//= link_tree ../images
//= link_directory ../javascripts .js
//= link_directory ../stylesheets .css
//= link "admin.js"
Lastly, if you are using webpacker, you might want to decide what you want handled by the asset pipeline and what you want handled by webpacker. i.e. remove the link_directory to the javascripts file according to your own particular use cases.
Reference: read here for further details re: manifest.js. file
Source: Thanks to Richard Schneeman's blog - see here for more information..
Footnotes and Primers
Concatenating? Normally JavaScript has a lot of white space. To speed things up, you can transform your JS code so that it has no white spaces, so it can be uploaded quickly - that's concatenating.
And bundling? Not as important as it was anymore, but you can combine multiple JS files into one single file, and send that over to the browser). The latest changes are a step in the right direction: now you have to tell sprockets explicitly, what files you want bundled and/or concatenated: this is done in your manifest.js file e.g.:
EDIT: if things are confusing / not clear: complain loudly! How can I fix if you keep mum? everyone benefits by these improvements.
A new major version of sprockets was recently released which is not compatible with the previous version.
Either perform the steps needed to upgrade or pin to version 3.x in Gemfile
gem 'sprockets', '~>3.0'
Based on the answer here you may be able to solve this with:
mkdir -p app/assets/config && echo '{}' > app/assets/config/manifest.js
And if you need more details, the answer in this thread helpfully points to the Guide to upgrading from Sprockets 3.x to 4.x
As suggested by link http://www.redmine.org/boards/2/topics/58169, it is a known issue. See #32223 and sprockets 4.0.0 breaks Redmine 3.4.11 with Ruby <2.5.0.
I just reproduced this issue with redmine 3.4.4, but found everything is ok with Redmine 3.4.12.
wget http://www.redmine.org/releases/redmine-3.4.12.tar.gz

How to fetch assets inside vendor subfolders in Rails?

I need to install a series of libs in my application, keeping them in their respective folders inside /vendor/plugins/
Example, the ckeditor library:
Main folder in /vendor/plugins/ckeditor/
js file in /vendor/plugins/ckeditor/js/Chart.js
css file in /vendor/plugins/ckeditor/css/chart.min.css
So that I can import into my application.scss like this:
*= require chart.min
And in my application.js like this:
//= require Chart.js
When I try to do this rails only accesses the folder /vendor/assets/plugins/ plugins, generating the error:
could not find file 'chart.min' with type 'text/css'
How do I get the project to scan all of the vendor's subfolders until find the file I'm importing?
First add the /vendor/plugins directory to the assets load path:
module MyApp
class Application < Rails::Application
config.assets.paths << Rails.root.join("vendor", "plugins")
# Settings in config/environments/* take precedence over those specified here.
# Application configuration should go into files in config/initializers
# -- all .rb files in that directory are automatically loaded.
end
end
However adding a directory to the assets load path does not mean that Sprockets will search all the subdirectories recursively. Nor is it a very good idea to configure it to do so.
You still need to provide a complete path from /vendor/plugins.
app/assets/javascripts/application.js:
//= require ckeditor/js/Chart
app/assets/stylesheets/application.css:
*= require ckeditor/css/chart.min
Or you can just use the Rails integration gem and skip all the hassle.

Unable to require a js file from a gem in asset pipeline

I have a local gem. And there is a js file:
app/assets/javascripts/autocomplete_location/location_autocomplete.js
Now I am trying to use this gem in my rails project. I am able to use it's other ruby files, but can't include the above js file. I have tried putting engine.rb file in my gem. Still no luck.
I tried
//= require autocomplete_locations/location_autocomplete
in application.js file of my project. Still, when I start server and open any page, it throws this error:
Sprockets::FileNotFound > couldn't find file 'autocomplete_locations/location_autocomplete' with type 'application/javascript'
//= require autocomplete_locations/location_autocomplete is still not the same as 'autocomplete_locations/location_autocomplete. The folder being required is autocomplete_locations and the name of the folder containing the file is autocomplete_location. I didn't catch that neither on my previous comment. If that does not solve the issue. Try requiring and testing a different javascript file just to make sure it is not a problem with the asset pipeline.
Thanks for your suggestions, after struggling through several hit and trial, I solved this by adding below code in lib/autocomplete_locations.rb:
class Engine < ::Rails::Engine
environment = Sprockets::Environment.new
environment.append_path '../vendor/assets/javascripts'
end
Now I am able to require my assets in rails project.

Rails 5 can't find JS file

I installed a plugin (http://antenna.io/demo/jquery-bar-rating/examples/) using Bower.
Now I have a file:
vendor/assets/bower_components/jquery-bar-rating/jquery.barrating.js
Also in my application.rb I have:
config.assets.paths << Rails.root.join('vendor', 'assets', 'bower_components')
I restarted my Rails server but when I access the app it says:
Sprockets::FileNotFound: couldn't find file 'jquery.barrating' with type 'application/javascript'
Checked in these paths:
/Users/xxx/Documents/Dev/xxx/Backend/app/assets/documentation
/Users/xxx/Documents/Dev/xxx/Backend/app/assets/images
/Users/xxx/Documents/Dev/xxx/Backend/app/assets/javascripts
/Users/xxx/Documents/Dev/xxx/Backend/app/assets/stylesheets
/Users/xxx/Documents/Dev/xxx/Backend/vendor/assets/bower_components
So it looks in the right folder but still can't find the file.
Any idea what is happening?
I can't entirely remember how I did it a while ago, but I think basically if you need the file in the plugin within your js, you could do:
//= require jquery-bar-rating
//OR
//= require jquery-bar-rating/jquery.barrating

rake assets:precompile for specific JS file

Could I run rake assets:precompile for specific JavaScript file?
Otherwise the full precompile lasts for 5 minutes and makes quick changes in JavaScript files very annoying.
If you wanted to precompile just one file, you could make a custom rake task to do so fairly easy.
namespace :assets do
desc "compile one js file"
task :compile_one_file => :environment do
dest = "#{Rails.root}/vendor/assets/javascripts/compiled/"
js_asset = "your_jsfile.js"
File.write(dest + js_asset, Uglifier.compile(Rails.application.assets.find_asset(js_asset).to_s))
end
end
then from the command line
rake assets:compile_one_file
Hope this helps, I find this useful for vendor js files that I don't change often such as jquery and jquery plugins. That way when im in development it speeds up my page loads keeping the asset pipeline from having to route all the separate requests for my vendor files. It just serves up one minified js file of all my vendor js.
Short: You can't.
During precompilation Rails goes through the Application.js file and merges all imports into one so just changing one file is simply not possible due to the compression that goes on in there. (It doesn't do anything to files not referenced from application.js)
Next up: You should not have to run rake assets:precompile during development when doing quick fixes. Only on deployment where (depending on your patience) it should be no problem having the task run 5 minutes.
You should be using the development environment during development where asset precompilation is not necessary because Rails will serve the assets unmerged and un-minified.
If you are running the Rails build in web-server through rails s this should be by default, but you can explicitly start the rails server using:
rails s RAILS_ENV=development
If the assets are still not correctly displayed or you see errors make sure you have config.assets.debug = true
#Tigraine is partially correct. Rails 3.1+ assets are intended to be fully managed by Rails and by default all assets will be compiled down to one js and one css asset.
HOWEVER...
Compiling down to a single asset relies on the use of an asset manifest (application.js and application.css) that is processed by the Sprockets gem. By default these manifests include a require_tree directive and it's that directive that includes all the files. If you remove that directive, you've got to do a bit more work to get your assets compiled.
If you want to build separate assets you can set a config option in application.rb.
config.assets.precompile += %w( additional/asset.css funky/stuff.js )
The above line would add the files additional/asset.css and funky/stuff.js to the list of files that would be produced when the assets are precompiled (Note that the '+=' is being used to extend the default list). To be as explicit as possible this means that you would have four assets precompiled: application.js, funky/stuff.js, application.css, and additional/asset.css.
That said, you might want to check out the guard-rails-assets gem. The gem is flexible in the way it supports precompiling; precompiling only changed assets is possible. I've heard some good feedback about it but not used it myself.
#Tigraine isn't correct.
It's possible, you just have to create folders and put the css files in them and import it to different files in the assets folder.
Like
application.css
*= require_self
*= require foundation_and_overrides
*= require reset
*= require_tree ./screen
Where Screen is a folder I've placed inside the stylesheet folder. like assets/stylesheets/screen/. I call the application.css with
<%= stylesheet_link_tag "application", media: "screen, projection" %>
Now, if you want to create a single css file for another layout you create that under assets/stylesheets
Like xxx.css
If you need multiple files for xxx you follow the same steps as above but the important part here is that you add this line to
production.rb
config.assets.precompile += %w( xxx.css )
Then inside the layout you add:
<%= stylesheet_link_tag "xxx", media: "screen, projection" %>
You can do this completely without Rails. This can make things run faster depending on your environment.
quick_compile.rb
require 'sprockets'
sprocket = Sprockets::Environment.new
sprocket.js_compressor = :uglifier # or read off config yml
sprocket.append_path('app/assets/javascripts') # the directory that holds you js src.
file = File.new('test_min.js','w+') # the output file path.
file.puts(sprocket.find_asset('test.js')) # the file to complie
file.close
If you just want to evalute the //= require statement, you can remove the js_compressor setting. Sprocket will concatenate the files required.

Resources