Rails 5 assets not mentioned on the `applications.js` manifest are served? - javascript

Please enlighten me!
Let say I have the following assets structure in a Rails 5 application.
app/assets/javascripts
application.js
file1.js
In the application.js manifest I am not requiring //= file1 neither I am using require_tree . directive.
If a JS file is not required in any way in the manifest application.js neither is it included in the Rails.application.config.assets.precompile += %w[]
Is this asset going to be served?
If there is a tag in some view <%= javascript_include_tag 'file1' %> , should it work or raise an error?

No, that file is not served by default. By default (depending on Rails version/asset config), only the files listed in Rails.application.config.assets.precompile, by default application.js application.css or in newer Sprockets/Rails via files listed in manifest.js are available for direct serving via javascript_include_tag.
That 2. would raise an error.

Related

Rails 5 - JS not working in production environment (only)

I am struggling.
I have rails 5 app with a series of js files in my app/assets/javascripts folder. The js in those files works just fine in the development environment, but when I publish on heroku, it stops working.
I can see from the chrome inspector, that the application.js file that is visible from the network tab shows the content of the js files in my app. That js just doesnt seem to do anything in production. No console errors appear from the chrome console inpsector.
I can see from this post that there are a series of things to try. I've tried all of them. I've even made a completely new app and added the js files on at a time to see if there is a tipping point where something is required in a different order to something else (mostly guessing) - but that does nothing to fix the problem.
I can see from this article that one suggestion is to:
# Don't fallback to assets pipeline if a precompiled asset is missed
config.assets.compile = false
and then try:
rake assets:clean assets:precompile
I've tried each of these suggestions and still can't find the problem.
If there were an error in the way I've written the js, I would expect that to be exposed in both my development and production environment console inspectors in chrome. There are no errors showing in either environment.
If there were a problem with the production environment reading the js file, I'm confused about why I can word search for the words used in the js file in the file I can open from the network tab and see the correct text.
How do I go about solving this problem?
My relevant files are:
app/assets/javascripts/application.js
//= require jquery
//= require jquery_ujs
//= require turbolinks
//= require jquery-fileupload/vendor/jquery.ui.widget
//= require jquery-fileupload/jquery.iframe-transport
//= require jquery-fileupload/jquery.fileupload
//= require bootstrap-sprockets
//= require moment
//= require bootstrap-datetimepicker
//= require pickers
// require underscore
// require gmaps/google
//= require markerclusterer
//= require cocoon
//= require cable
//= require_tree .
config/initializers/assets.rb
# Be sure to restart your server when you modify this file.
# Version of your assets, change this if you want to expire all your assets.
Rails.application.config.assets.version = '1.0'
# Add additional assets to the asset load path
# Rails.application.config.assets.paths << Emoji.images_path
# Precompile additional assets.
# application.js, application.css, and all non-JS/CSS in app/assets folder are already added.
# Rails.application.config.assets.precompile += %w( search.js )
config/production.rb
# Do not fallback to assets pipeline if a precompiled asset is missed.
config.assets.compile = false
The relevant file that is not working in the production environment is saved in app/assets/javscripts/stance/commercial.js (so it should be identified in application.js by //= require_tree.
That file has:
jQuery(document).ready(function() {
jQuery('[name="organisation[commercial_attributes][standard_financial_split]"]').on('click', function() {
if (jQuery(this).val() == 'true' ) {
jQuery('#commercial_standard_financial_split_content').removeClass('hidden');
} else {
jQuery('#commercial_standard_financial_split_content').removeClass('hidden').addClass('hidden');
}
});
});
Can anyone help with a process for getting js to work in the production environment?
I am out of suggestions for things to try and this isn't the sort of thing that the tutorials, code schools (I am a student in code school, go rails, udemy and have a million books), but can't find an reference point from which to start in solving this problem.
For me, the solution was to remove the javascript include tag from the header of my application.html.erb to beneath the body. That fixed the problem with the js file I referenced in my question.
However, this has now broken my google maps javascript, so I'm not sure that this is actually a good solution.

In RoR, how do I include all JS files in a folder on one page only?

I’m using Rails 4.2.3. I have the following folder of Javascript files
app/assets/javascripts/flot/
I want all the files in this folder included on only a single page (i.e. only one action from a controller). Is is possible to do this without hard-coding every file in a javascript_include_tag in my view? Note, I am NOT interested in answers in which all the JS files get included on every action of the controller. I only need these files for the view rendered by one action.
You could create a master JS file in that folder and throw in a list of
//= require [file name]
into the mix so it loads all of them from that list.
Then include the following line in the view you want to use.
<%= javascript_include_tag "flot/[master file name]" %>
Javascript_Include_Tag
For example you could name your file app/assets/javascripts/flot/main.js
Then the content would be
#flot/main.js
//= require_tree .
and
#your view
...
<%= javascript_include_tag "flot/main" %>
...
Then any files added to your flot folder or subfolders would automatically be added to your tree. Just make sure you've excluded the flot folder from the require_tree in your application.js file as explained in this link

Rails Asset-pipeline policy

quick example,
make a new rails project, and if we look in to app/assets/javascripts/application.js
it says,
//= require jquery
//= require jquery_ujs
//= require turbolinks
//= require_tree .
in default.
I added foo.js, bar.js in app/assets/javascripts/
and if i run the app, this asset-pipeline
loads foo.js, bar.js in every-pages even i don't need to use in most of the pages.
Is this a right structure?
What about
change to require_self
and use javascript_include_tag and load the js files manually when i need?
Isn't this a better way?
Why Rails asset pipeline default policy is always loading every js files even i dont need?
Browsers usually cache assets files.
Therefore it might make sense to deliver one huge assets file to the browser when the user visits the application for the first time. All following request (even for other pages) will be faster, because the browser will not have to reload other small assets.
But it depends: If you have large javascript libraries that are only rarely used in your app, then it might be better to deliver that files only on that special pages.
//= require jquery
//= require jquery_ujs
//= require turbolinks
//= require_tree .
Notice the last require_tree . which means, what ever javascript files currently present inside your app/javsacript folder will be auto loaded.
So, in reply to your first question, Yes it's a right structure. Js files inside javascript folder will get auto loaded.
You have kept the js file inside js folder means, in your project you are going to use it :)
In production:
When you precompile your assets in production machine, all your js,css will be precompiled into a single application.css & application.js file, so we don't need to bother about loading each manually.
I know it is an old question but this answers could help someone.
If you need to add an asset just in a specific place you need to add it to the precompile array. In Rails 3 you need to modify config/application.rb file by adding the asset in this way:
config.assets.precompile += %w( foo.js bar.js )
In Rails 4 and 5 you need to modify config/initializers/assets.rb file in this way:
Rails.application.config.assets.precompile += %w( foo.js bar.js )
Don't forget to restart the server.
This article is an excellent resource to learn about Asset Pipeline.

Non global coffee script and asset pipeline

I have a coffee script user.js.coffee, that is only used in certain views. I achieved this by using the following answer:
https://stackoverflow.com/a/6795533/784318
Now I have excluded the script from the application.js. I also removed the //= require_tree . entry.
So my file is available here: http://localhost:3000/assets/user.js however, when I deploy this to the server the assets will be combined in one application.js so how can I make sure that the user.js will be available on production like so: http://myserver.com/assets/user.js?
In environments/production.rb (or the environment you need precompile to occur) uncomment or add this file to the precompile array:
# environments/production.rb
config.assets.precompile += %w( user.js )
Other entries might be already present, just add any other file that you need to access separately.
This file will not get compiled in one big application.js file and will be accessible separately as user.js
You can try putting your user.js file to the public folder of your application directly and configure your asset pipeline to exclude it from the "zipping" process.

Additional Sprockets manifest file?

I'm trying to create another manifest file, called app/assets/javascripts/base.js that looks roughly like this:
//= require jquery
//= require jquery_ujs
//= require_tree ./backbone/tempaltes
My plan is to include this before my app/assets/javascripts/application.js file, which has my main backbone code, as such:
//= require ./backbone/app
// etc...
My thinking is that I can cache the stuff that won't change much (my templates, jquery, plugins, etc.) and cache-bust my app code, which will likely change quite frequently, reducing the page size to the client.
I'm requiring both files in my app/views/layouts/application.html.haml like so:
= javascript_include_tag "base"
= javascript_include_tag "application"
However, when I load up my developemnt server, only the files from application.js are loaded; none of the files in base.js are loaded. I've added this line in config/application.rb:
config.assets.precompile += %w(base.js)
... but that doesn't get any of the assets required in base.js to load in development. What do I have to do to get these files to load?

Categories