I'm using browserify-rails to include Angular UI Grid in my Rails project. My application.coffee contains the following:
require('angular-ui-grid')
This works in the sense that includes node_modules/angular-ui-grid/ui-grid.js, but it doesn't handle any of the stylesheets.
How can I get Angular UI Grid's stylesheets into my application as well?
The JavaScript includes and CSS includes are handled separately.
Your require('angular-ui-grid') call above handles the JS side of things since it's in the application.coffee manifest file.
To include the stylesheets, you'll need an additional require in the application.scss (or whichever file is your main CSS manifest).
browserify-rails does not include the node_modules directory in its asset load paths by default, so you have to add it inside the assets.rb file like this
# Add additional assets to the asset load path
# Rails.application.config.assets.paths << "node_modules"
Related
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
I am developing a rails application starting from webarch template. I know that adding the whole assets folder in the public/ folder will link the assets with my views, but it would not be taking advantage of the assets pipeline functions. The template has a lot of plugins and different options and one generally does not use all of it. The assets folder's size is 30MB.
I though about putting it inside vendor/assets and using it with the asset pipeline but this generates two problems:
I would be serving 30MB of minified code and using a small percentage of it in my app.
I would have to manually rewrite the whole assets folder to use links the way asset pipeline wants it (javascript_include_tag "file" to serve file.js). Of course, I would do this via a script but it still seems like a problem someone should have encountered first.
Since neither vendor/assets and public/ folders seem to be a proper location for these files I would like a better option (or a way to make the later options work better).
A solution to keep your files under asset pipeline when they are too big to reasonably be left in one single minimified asset file is to split your assets by categories, compile those categories in different minimified files, and include them in your views when needed.
I do it for an app that contains several "heavy" javascripts components that are located in different area of my app and are not often used.
1- Organize your file structure
In app/assets/javascrips and app/assets/stylesheets create one directory per category we are going to create. Examples:
app/assets/javascrips/common
app/assets/javascrips/admin
app/assets/javascrips/user_account
2- Create your manifests
In app/assets/javascrips and app/assets/stylesheets create one manifest file per category and have them included the related directory
File app/assets/javascrips/common.js
//= require jquery
//= require_tree ./common
File app/assets/javascrips/admin.js
//= require_tree ./admin
File app/assets/javascrips/user_account.js
//= require_tree ./user_account
3- Add your manifests to rails precompile list
You can do it in config/application.rb file, but when it gets big it is preferable to create an initializer file config/initializers/assets.rb
Rails.application.configure do
config.assets.precompile += %w[common.js admin.js user_account.js]
end
4- Include them in your views and layouts, and set-up your javascript libraries.
Import the assets files into layouts and views. It can be a good idea to create several layouts for different area of your application that would be using common assets files. The methods to use are
stylesheet_link_tag 'manifest_file' and javascript_include_tag 'manifest_file'
And keep in mind you may have to tell your javascript plug-ins they need to use the miniminied file when dynamically loading files. For them you can use a configuration .js.erb file. Example:
File app/assets/javascrips/admin/plug-in_config.js.erb
PLUGIN.config('dynamicFileName', '<%= javascript_path('manifest_file') %>');
Question 1:
I've heard of creating div class' to cater to certain areas of the HTML but is there another way out there? Here's a link that I found related to what I mean.
http://brandonhilkert.com/blog/page-specific-javascript-in-rails/
Question 2:
Is there a way in order for me to organize my CSS and JavaScripts in my asset folder in the rails app IN SPECIFIC FOLDERS while accessing the asset pipeline benefits?
Eg.
Normal way:
assets
images(under assets)
stylesheets(under assets)
mycss1 CSS scss
mycss2 CSS scss
mycss3 CSS scss
javascripts(under assets)
myjava1 js
myjava2 js
myjava custom js
The Idea:
assets
images(under assets)
stylesheets(under assets)
myview(this is a subfolder of the stylesheets folder)
mycss1 CSS scss
mycss2 CSS scss
homepage(subfolder)
mycss3 CSS scss
javascripts(under assets)
myview(subfolder of javascripts)
myjava1 js
homepage(subfolder)
myjava2 js
myjava2 custom js
As far as I understand, you want to add your custom folders under the assets directory, put some files with specific CSS and JS and use them whenever you need it.
To achieve this you should include those files somewhere. By default, you have an appplication layout which includes application.js and application.css files which includes the rest of the related files. Those files known as manifest files and they are using sprockets gem to handle dependencies, preprocessing, compressing and other stuff (you can read more about it here). You can change the assets folder using config.assets.prefix or add new paths to look up for sprockets using config.assets.paths (This might be what you are looking for. Further reading here)
I have a script that's basically a "widget" that users embed.
It's got just simple vanilla javascript and doesn't have any require's to other resources. It's located at /app/assets/javascripts/delivery.js
What I want to do is have the file get compressed/compiled and then let users link directly to it from a script tag, ie. <script src="http://example.com/assets/delivery.js"></script>
But right now...that's a no-go. That file doesn't exist in production.
So, how can I compress that file like any other JS file in the pipeline, and then link directly to it?
If you add
config.assets.precompile += ['delivery.js']
to your application.rb, then delivery.js will be treated as a manifest file: it will be precompiled and served up as delivery.js in production. Manifest files are often just a series of //= require (or //= require_directory) statements, but any javascript they contain will also be added to the generated file.
By default the application.js manifest includes everything - you way want to tweak this so that it doesn't include javascript which is intended only to be served standalone.
First, make sure that your app/assets/javascripts/delivery.js is not among the includes of your top-level "manifest" javascript file, i.e. app/assets/javascripts/application.js. application.js usually includes //= require_tree ., so it includes your delivery.js by default. You need to change that. Replace "require_tree" with individual "require" statements for all your assets that you want to have precompiled and combined in the application.js.
Next, update your environment files (config/environments/production.rb for production env) to include your file in the list of precompiled assets:
config.assets.precompile += %w( delivery.js )
Now you'll have it as a separate file in your public/assets directory, compiled and compressed in the same way as application.js. Just keep in mind that it has a digest attached to it's name similarly to your application.js (unless, of course, you serve the files without digests by setting config.assets.digest = false).
How do I install a custom theme for twitter-bootstrap with the rails asset pipeline?
Should I create a new folder under assets and dump in all of the css, js, image and font files for the theme?
Update:
I put all files in my downloaded theme (except the html example files) into a folder in app/assets and added this folder to my asset paths in application.rb:
config.assets.paths << Rails.root.join("app", "assets", "bootstrap_theme")
I added some markup using css classes from the theme but it's not using the theme..
Update: I see that the boostrap theme has the compiled core bootstrap files included inside it. Should I take this to mean it's not intended to be used with Less?
Also, should I precompile every asset file individually for production (in application.rb) and in each view include the specific ones needed (and include them after the core bootstrap files)? Then I guess to make any overrides to the theme they'd need to be made directly in the theme files?
Update: I think the problem was that I was requiring the theme css files in my manifest after the bootstrap_and_overrides, assuming the idea of the theme was to change the bootstrap defaults. But requiring some of the theme css before the standard bootstrap_and_defaults works better. It means needing to manually pick and choose which css to load before and after bootstrap.
I never proved the twitter bootstrap in a rails application but I searched before how can I do it.
If you install the gem less-rails-bootstrap or bootstrap-sass, you can follow the instructions to modify the theme here.
I hope it helps.