I have a problem with js files being compiled in development.
I have an application.js file that includes multiple other files like this:
//=require_tree .
the files in the directory are
app/assets/javascripts/user_row.coffee
app/assets/javascripts/index.coffee
Whenever I make a change to one of those files a corresponding js file gets created in the app/assets/javascripts directory, so I change user_row.coffee and I get:
app/assets/javascripts/user_row.js
This is in development mode, with the default asset configuration (I haven't changed development.rb from what the rails generator creates).
If I change the user_row.coffee file again, it gets overlooked and the already existing js file gets included by application.js.
What I don't understand are why these js files being created in the app/assets/javascript directory rather than under tmp/cache/...
Any ideas?
You should name the coffee files name.js.coffee instead of just name.coffee.
This turned out to be an issue with nodes v0.8.9. I'm using node as the javascript runtime, and after updating from v0.8.9 to v0.8.16, the problem went away.
Related
So we have an app made with rails that we are we are deploying to Heroku. We have been having very odd CSS, JS issues on the heroku build of our app. We noticed that currently all JS files are in one single 22000 line file after compiling our files. Did we 'mis-compile'? Messed up file structure possibly? Thanks, let me know if I can clarify anything.
Why do you say it is an odd issue? According to the docs:
Sprockets concatenates all JavaScript files into one master .js file and all CSS files into one master .css file.
What you call an 'issue' seems to be a 'feature'.
I am new to rails and I'm a bit confused about how assets are loaded. I can get things working but I would like to understand what really happens behind the scenes.
I have been reading the documentation but there are things that I don't understand completely.
MANIFEST FILE
First thing that confuses me is the usage of manifest files.
For instance if in my app/assets/javascripts/application.js file I have:
//= require_tree .
Rails documentation says:
tells Sprockets to recursively include all JavaScript files in the
specified directory into the output
What isn't clear to me is which directory? app/assets/javascripts/?
Does that mean that if I add a file in app/assets/javascripts/ it will be loaded and served?
If I add a gem that requires to add a file example.js I need to add to the manifest file:
//= require example.js
But why is this necessary if //= require_tree already loads and serve files in app/assets/javascripts/ which is the location where I have put my example.js? Ok that allows me to specify the order if later I add more requires. But other than that?
HTML FILE
And then the script to be included in application.html.erb
<%= javascript_include_tag ('application'), 'data-turbolinks-track' => true %>
I understand this loads the application.js file mentioned above and therefore the various //= require in it.
Sometimes happens that is required to script the particular file as:
<script src="js/example.js"></script>
Is this scenario wouldn't be <script src="js/example.js"></script> doing the exact same thing of //= require example.js?
PUBLIC VS APP ASSETS
I understand that if I place my example.js file on public/assets folder it won't be compiled but served separately. Why would I do that? Is it reasonable to do it in case a file is not served correctly when concatenated and compiled and works only if served separated? In other words, if I include a .js file on app/assest and it has problems to load or break things, is it worth to try to remove it from there and move it to public/assets or does this just not make sense?
APP ASSETS VS VENDOR ASSETS
On which scenario should I add a file to vendor assets instead of app assets? What is the difference between adding it to a place or another?
And in my vendor/assets/javascripts I have only an empty .keep file. So there'n so such thing as manifest file on app/assets. How are files in this folder referenced then?
For directives that take a path argument, you may specify either a
logical path or a relative path. Relative paths begin with ./ and
reference files relative to the location of the current file.
So //= require_tree . tells sprockets to load any files in app/assets/javascripts/ and concatenate them into application.js.
Is this scenario wouldn't be <script src="js/example.js"></script>
doing the exact same thing of //= require example.js?
No. Rails serves the assets as seperate files in development so that you get a meaningful line number and file reference when errors occur.
In production it concatenates and minifies the assets which is important for performance.
Sprockets does not check your views / layouts for script tags. So the the former would result in two requests.
I understand that if I place my example.js file on public/assets
folder it won't be compiled but served separately. Why would I do
that?
The public directory is placed under the servers web root. Since the files there are served without much intervention its a good place for things like error pages or where you need assets that have a static name without a cache busting fingerprint.
On which scenario should I add a file to vendor assets instead of app
assets? What is the difference between adding it to a place or
another?
/vendor/assets is the place to put assets that are not created by you or which are not part of the application. Both are added to the sprockets load paths so the results are identical. Its rather just a question of code organisation.
https://github.com/rails/sprockets
http://guides.rubyonrails.org/asset_pipeline.html
If we include js/css files using application.css (like //=require_tree), then those files are working. But, I have stopped doing like that because it loads all js files of the project everytime.
So, I am adding (including) only required files per view basis. But they are not working when pushed to Heroku.
Including them on a per-view basis is not the right approach. First, you skip compilation (and thus you should store the assets in the public folder as static files), then you don't take advantage of the asset pipeline.
You can keep using the pipeline by splitting the assets in bundles and include only the bundle you want.
For example, you can remove the application.css file and split into alpha.css and beta.css, each file with its own includes. Add the files to the compilation in your production.rb file and you're done. Include those selectively, so that when you include alpha you will not load files included in beta.
I used a editor lib, that will load language related js files dynamically when you selected a language. In the development environment, that's fine, because assets is accessible, so the lib can access any files under assets. But in production environment, i did not add those files to precompile list, so those files are missing, and i also don't want to add them to precompile list.
So my question is whether there is a way to access javascript files even i did not add them to precompile listi on production app?
Any suggestion is welcome,thanks!
You could simply add them to the public folder, preferably in a js subfolder.
For an application built on top of Rails (3.1.8) with ExtJS 4.1, we have the following files layout:
app/
assets/
javascript/
application.coffee
WID/
Lots of coffeescript files and folders.
public/
extjs/
ext-all-debug-w-comments.js and the whole ExtJS framework.
Our application heavily relies on the Ext loader (Ext.Require) to dynamically load files based on users rights / allowed modules. We would like to keep this functionality as much as possible, so only the required files are requested from the server. Bandwidth isn't really an issue, as the application is intranet-based (On a LAN).
In development environment, everything runs smooth. In production environment however, we are having problems. It looks like either the "rake assets:precompile" task is concatenating all files into an application.js file, and then when accessing our application the Ext loader complains that it can't find individual files (Because assets/WID/.../file.js isn't being served by the rails server).
So right now, i'm not sure what would be the best move to take... Is there anyone able to help us with a successful Rails + ExtJS production setup taking the best from the assets pipeline?
Thank you,
Pierre.
I think you should move your javascripts (and generally all the assets) from your public into vendor/assets/javascripts when you are in development environment. This way the asset-pipeline gets in charge.
EDIT: You may consider reverting your manifest file to application.js, not application.coffee. Generally it is a bad idea to rename these special files : application.css and application.js .In case you have some coffescript to add , just create a new file and place it in an asset directory.