CSC/ECE 517 Fall 2014/ch1a 22 sp: Difference between revisions
No edit summary |
|||
(44 intermediate revisions by the same user not shown) | |||
Line 1: | Line 1: | ||
==Asset Pipelining in Rails 4.x and Beyond== | |||
== | ===What is asset pipelining, and why should it be used?=== | ||
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 10: | ||
# Precompilation (preprocessing) | # Precompilation (preprocessing) | ||
#* 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. | #* 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_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 asset pipeline was first introduced in Ruby 3.1 as a core feature of Ruby.<ref>[http://guides.rubyonrails.org/3_1_release_notes.html "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. | |||
# 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> | |||
==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"/> | |||
<code><pre> | |||
[ | |||
Proc.new { | |||
|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. | |||
===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.<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 <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 <code>config/initializers/assets.rb</code>: | |||
<code> | |||
Rails.application.config.assets.precompile += ['admin.js', 'admin.css', 'swfObject.js'] | |||
</code> | |||
You can also precompile all assets with an approach like this: | |||
<code> | |||
<pre> | |||
# 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 | |||
</pre> | |||
</code> | |||
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=== | ===Rails 4 Asset Pipelines on Heroku=== | ||
<ref>[https://devcenter.heroku.com/articles/rails | 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: | ||
<ref>[https://devcenter.heroku.com/articles/rails-asset-pipeline "Rails Asset Pipeline on Heroku | # 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> | |||
====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 [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.
- 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.
- 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>
- 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"/>
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.
- 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">"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:
- 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 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/>