CSC/ECE 517 Fall 2014/ch1a 22 sp: Difference between revisions

From Expertiza_Wiki
Jump to navigation Jump to search
No edit summary
Line 45: Line 45:
</code>
</code>


You can also precompile all assets:
You can also precompile all assets with an approach like this:


<code>
<code>

Revision as of 01:06, 19 September 2014

Sprockets gem provides Sprockets implementation for Rails 4.x (and beyond) Asset Pipeline. This wiki must describe importance of using asset pipelining in Rails (now called rake pipelining), how its done? A Pipeline is responsible for taking a directory of input files, applying a number of filters to the inputs, and outputting them into an output directory. Also include details to implement Rails 4 asset pipeline on Heroku.

Asset Pipelining in Rails

What is asset pipelining, and why should it be used?

Generally speaking, asset pipelining refers to the practice of using a provided framework to combine and/or minify (compress) assets. This framework also allows these assets to be written and precompiled with different languages such as CoffeeScript and embedded Ruby.<ref name="The Asset Pipeline">"The Asset Pipeline", Rails Guides. Retrieved 16 September 2014.</ref> These three main features are all good reasons to include an asset pipeline in a Rails application.

  1. Asset concatenation
    • Concatenating assets means that the browser needs to make fewer requests to render the page, which means that your application will load faster.
  2. Asset minification
    • Apart from GZIP compression, minification can also have a significant impact on the number of bits that your application needs to send down the wire.
    • Remember, it's not just about the amount of data, it's also about the number of requests required to get the data from the server to the browser. Too many requests can have a greater impact on application performance than file size.<ref>"The Importance (and Ease) of Minifying your CSS and JavaScript and Optimizing PNGs for your Blog or Website", Scott Hanselman. 1 September 2011. Retrieved on 16 September 2014.</ref>
  3. Precompilation (preprocessing)
    • When using an asset pipeline, assets may be coded in a higher-level language and then precompiled down to the actual assets.
    • Furthermore, multiple levels of preprocessing may be used simply by appending additional file extensions to the file name. For example, 'app/assets/stylesheets/projects.css.scss.erb' can be first processed as ERB, then SCSS, and finally served as CSS.<ref name="The Asset Pipeline"/>
A simple diagram of the asset pipeline flow.
A simple diagram of the asset pipeline flow.<ref name="Dummies"/>

The Technology Behind the Pipeline

The asset pipeline was first introduced in Ruby 3.1 as a core feature of Ruby.<ref>"Ruby on Rails 3.1 Release Notes", Rails Guides. Retrieved 17 September 2014.</ref> As of Ruby 4.1, the asset pipeline has been broken out of the framework into the sprockets-rails gem.<ref name="The Asset Pipeline"/>

In its current form, the asset pipeline relies on two main technologies: sprockets and tilt.

  1. Sprockets handles asset packaging. It searches for assets, compiles them together, and places them in the target directory (public/assets by default).
  2. Tilt (a dependency of sprockets) is a template engine that allows filetypes like scss and erb to be used in the application.<ref name="Dummies">"Asset Pipeline for Dummies", coderberry. 24 April 2012. Retrieved 17 September 2014.</ref>

How to Use the Asset Pipeline

Using the asset pipeline with the default configuration is actually very simple. All you need to do is place your assets (JavaScript, CSS, and images) into the asset path (public/assets) by default.<ref name="Dummies"/>

The default matcher for compiling files includes the application.js manifest file, the application.css manifest file, and all non-JS/CSS files (this will include all image assets automatically) from app/assets folders including your gems:

[ Proc.new { |path, fn| fn =~ /app\/assets/ && !%w(.js .css).include?(File.extname(path)) }, /application.(css|js)$/ ]

Before compilation, the asset pipeline uses Sprockets to parse through the directives in the manifest files and concatenates all of the referenced files together into the application .js and .css files.

Manifest Files

Sprockets uses manifest files to determine which assets to process and serve. To begin customizing the resources that are available, check the automatically-generated manifest files. For example, the app/assets/javascripts/application.js manifest file contains this line by default: //= require_tree . This means that the Sprocket directive (//=) requires all JavaScript files in the app/assets/javascripts directory to be fed into the asset pipeline.<ref name="The Asset Pipeline"/>

You can include a directive for any file with the same file extension as the manifest that you like, and Sprockets will find it for you, as long as it is in the search path (the default search path is assets/*). For example the application.js manifest file also contains this line: //= require jquery This means that the jquery.js file that exists somewhere in the assets directory or any descendant directories will be processed. You do not need to add the file extension - Sprockets assumes that you are requiring a .js file if you do so in a .js manifest.<ref name="The Asset Pipeline"/>

You can have as many manifests as you want, which can help break up and organize your assets. If you have other manifests or individual stylesheets and JavaScript files to include, you can add them to the precompile array in config/initializers/assets.rb:

Rails.application.config.assets.precompile += ['admin.js', 'admin.css', 'swfObject.js']

You can also precompile all assets with an approach like this:

# config/initializers/assets.rb
Rails.application.config.assets.precompile << Proc.new do |path|
  if path =~ /\.(css|js)\z/
    full_path = Rails.application.assets.resolve(path).to_path
    app_assets_path = Rails.root.join('app', 'assets').to_path
    if full_path.starts_with? app_assets_path
      puts "including asset: " + full_path
      true
    else
      puts "excluding asset: " + full_path
      false
    end
  else
    false
  end
end

Because Sass or CoffeeScript files will always be compiled down to .css or .js files, only specify .js and .css files in the precompile array.<ref name="The Asset Pipeline"/>

Rails 4 Asset Pipelines on Heroku

There are two ways you can use the asset Pipeline on Heroku:

  1. Compile your assets locally
  2. Rely on Heroku to compile the assets

Compiling Assets Locally

Heroku will know that you are compiling your assets locally if it finds a file called public/assets/manifest-<md5 hash>.json. You can generate this file by running the following task locally on your app: RAILS_ENV=production bundle exec rake assets:precompile. This task uses the production environment to generate production versions of your assets.

Now, commit and push the contents of public/assets to your Git repository to make it available to Heroku. You should see the following output when you push:

<ref name="Heroku">[https://devcenter.heroku.com/articles/rails-asset-pipeline "Rails Asset Pipeline on Heroku Cedar"], ''Heroku Dev Center''. 25 August 2014. Retrieved 16 September 2014</ref>

-----> Preparing Rails asset pipeline
       Detected manifest-<md5 hash>.json, assuming assets were compiled locally

Relying on Heroku to Compile Assets

If you choose to rely on Heroku, Heroku will attempt to run the assets:precompile task when you push. You should see output like this when you push:

-----> Preparing Rails asset pipeline
       Running: rake assets:precompile

ref name="Heroku"/>

Troubleshooting

If there is no debug output and your asset:precompile task is not run, ensure that rake is in your Gemfile and properly committed.<ref name="Heroku"/>

References

<references/>