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

From Expertiza_Wiki
Jump to navigation Jump to search
No edit summary
 
(35 intermediate revisions by the same user not shown)
Line 1: Line 1:
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 4.x and Beyond==
 
==Asset Pipelining in Rails==


===What is asset pipelining, and why should it be used?===
===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">[http://guides.rubyonrails.org/asset_pipeline.html "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.
Generally speaking, [http://www.youtube.com/watch?v=xbjTlKC2Id8 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">[http://guides.rubyonrails.org/asset_pipeline.html "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.
# Asset concatenation
# 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.
#* Concatenating assets means that the browser needs to make fewer requests to render the page, which means that your application will load faster.
Line 13: Line 11:
#* When using an asset pipeline, assets may be coded in a higher-level language and then precompiled down to the actual assets.
#* 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"/>
#* 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"/>
[[File:asset_pipeline_flow.png|frame|alt=A simple diagram of the asset pipeline flow.|A simple diagram of the asset pipeline flow.<ref name="Dummies"/>]]
[[File:asset_pipeline_flow_75.png|frame|alt=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 Technology Behind the Pipeline====
Line 20: Line 18:
In its current form, the asset pipeline relies on two main technologies: sprockets and tilt.
In its current form, the asset pipeline relies on two main technologies: sprockets and tilt.
# Sprockets handles asset packaging. It searches for assets, compiles them together, and places them  in the target directory (public/assets by default).
# Sprockets handles asset packaging. It searches for assets, compiles them together, and places them  in the target directory (public/assets by default).
# 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">[http://coderberry.me/blog/2012/04/24/asset-pipeline-for-dummies/ "Asset Pipeline for Dummies"], ''coderberry''. 24 April 2012. Retrieved 17 September 2014.</ref>  
# 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">[http://coderberry.me/blog/2012/04/24/asset-pipeline-for-dummies/ "Asset Pipeline for Dummies"], ''coderberry''. 24 April 2012. Retrieved 17 September 2014.</ref>


==How to Use the Asset Pipeline==
==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"/>
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:
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:<ref name="Dummies"/>


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


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.
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===
===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 <code>app/assets/javascripts/application.js</code> manifest file contains this line by default: <code>//= require_tree .</code> This means that the Sprocket directive (<code>//=</code>) requires all JavaScript files in the <code>app/assets/javascripts</code> directory to be fed into the asset pipeline.
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 <code>app/assets/javascripts/application.js</code> manifest file contains this line by default: <code>//= require_tree .</code> This means that the Sprocket directive (<code>//=</code>) requires all JavaScript files in the <code>app/assets/javascripts</code> directory to be fed into the asset pipeline.<ref name="The Asset Pipeline"/>


You can include any file you like, and Sprockets will find it for you, as long as it is in the search path (the default search path is <code>assets/*</code>). For example the <code>application.js</code> manifest file also contains this line: <code>//= require jquery</code> 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.
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 <code>assets/*</code>). For example the <code>application.js</code> manifest file also contains this line: <code>//= require jquery</code> 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:
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 <code>config/initializers/assets.rb</code>:


<code>
<code>
Line 45: Line 46:
</code>
</code>


Or, you can opt to precompile all assets with something like this:
You can also precompile all assets with an approach like this:


<code>
<code>
<pre>
# config/initializers/assets.rb
# config/initializers/assets.rb
Rails.application.config.assets.precompile << Proc.new do |path|
Rails.application.config.assets.precompile << Proc.new do |path|
Line 64: Line 66:
   end
   end
end
end
</pre>
</code>
</code>


Be sure to always specify an expected compiled filename that ends with .js or .css, even if you want to add Sass or CoffeeScript files to the precompile array.<ref name="The Asset Pipeline"/>
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===
Heroku is a cloud application platform that allows developers to deploy and run their web applications, making them widely available. When you finish developing your application and deploy it to Heroku, you can take advantage of the asset pipeline in two ways:
# Compile your assets locally
# 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 <code>public/assets/manifest-<md5 hash>.json</code>. You can generate this file by running the following task locally on your app: <code>RAILS_ENV=production bundle exec rake assets:precompile</code>. This task uses the production environment to generate production versions of your assets.


Now, commit and push the contents of <code>public/assets</code> 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>
<code><pre>
-----> Preparing Rails asset pipeline
      Detected manifest-<md5 hash>.json, assuming assets were compiled locally
</pre></code>


====Relying on Heroku to Compile Assets====
If you choose to rely on Heroku, Heroku will attempt to run the <code>assets:precompile</code> task when you push. You should see output like this when you push:<ref name="Heroku"/>
<code><pre>
-----> Preparing Rails asset pipeline
      Running: rake assets:precompile
</pre></code>


===Rails 4 Asset Pipelines on Heroku===
====Troubleshooting====
<ref>[https://devcenter.heroku.com/articles/rails-4-asset-pipeline "Rails 4 Asset Pipeline on Heroku"], ''Heroku Dev Center''. 10 April 2014. Retrieved 16 September 2014</ref>
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"/>
<ref>[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>
 
Also, make sure that you include [https://github.com/schneems/sprockets_better_errors#raise-when-dependencies-improperly-used Sprockets dependency declarations] for asset files that are referenced in other files.<ref>[https://devcenter.heroku.com/articles/rails-4-asset-pipeline "Rails 4 Asset Pipeline on Heroku"], ''Heroku Dev Center''. 10 April 2014. Retrieved 16 September 2014</ref>
 
==Glossary==
; [http://coffeescript.org/ CoffeeScript]
: A programming language that compiles into JavaScript.
; [https://www.heroku.com Heroku]
: Heroku is a cloud application platform built for developers. It allows you to easily deploy applications to the cloud, and supports several different languages and technology stacks.
; [http://en.wikipedia.org/wiki/Minification_(programming) Minify]
: To remove as much extraneous data from a code file as possible, without changing its functionality. For example, a JavaScript file may be minimized by removing all spaces and newline characters.
; [http://sass-lang.com/ Sass]
: Sass (which stands for Syntactically Awesome Style Sheets) is a CSS extension language.
; [https://github.com/sstephenson/sprockets#sprockets-rack-based-asset-packaging Sprockets]
: Sprockets is a Ruby library for compiling and serving web assets. It allows you to write assets in languages like CoffeeScript and SCSS.
 
==Examples of Other Asset Pipelines==
Grails: [http://grails.org/plugin/asset-pipeline http://grails.org/plugin/asset-pipeline]
 
Laravel: [https://github.com/CodeSleeve/asset-pipeline https://github.com/CodeSleeve/asset-pipeline]
 
Statamic: [http://statamic.com/learn/advanced-features/static-asset-pipeline http://statamic.com/learn/advanced-features/static-asset-pipeline]


==References==
==References==
<references/>
<references/>

Latest revision as of 22:40, 25 September 2014

Asset Pipelining in Rails 4.x and Beyond

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:<ref name="Dummies"/>

[
   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

Heroku is a cloud application platform that allows developers to deploy and run their web applications, making them widely available. When you finish developing your application and deploy it to Heroku, you can take advantage of the asset pipeline in two ways:

  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">"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:<ref name="Heroku"/>

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

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"/>

Also, make sure that you include Sprockets dependency declarations for asset files that are referenced in other files.<ref>"Rails 4 Asset Pipeline on Heroku", Heroku Dev Center. 10 April 2014. Retrieved 16 September 2014</ref>

Glossary

CoffeeScript
A programming language that compiles into JavaScript.
Heroku
Heroku is a cloud application platform built for developers. It allows you to easily deploy applications to the cloud, and supports several different languages and technology stacks.
Minify
To remove as much extraneous data from a code file as possible, without changing its functionality. For example, a JavaScript file may be minimized by removing all spaces and newline characters.
Sass
Sass (which stands for Syntactically Awesome Style Sheets) is a CSS extension language.
Sprockets
Sprockets is a Ruby library for compiling and serving web assets. It allows you to write assets in languages like CoffeeScript and SCSS.

Examples of Other Asset Pipelines

Grails: http://grails.org/plugin/asset-pipeline

Laravel: https://github.com/CodeSleeve/asset-pipeline

Statamic: http://statamic.com/learn/advanced-features/static-asset-pipeline

References

<references/>