README.md in sprockets-4.0.0.beta6 vs README.md in sprockets-4.0.0.beta7
- old
+ new
@@ -3,11 +3,10 @@
Sprockets is a Ruby library for compiling and serving web assets.
It features declarative dependency management for JavaScript and CSS
assets, as well as a powerful preprocessor pipeline that allows you to
write assets in languages like CoffeeScript, Sass and SCSS.
-
## Installation
Install Sprockets from RubyGems:
``` sh
@@ -15,482 +14,609 @@
```
Or include it in your project's `Gemfile` with Bundler:
``` ruby
-gem 'sprockets', '~> 3.0'
+gem 'sprockets', '~> 4.0'
```
-## Using Sprockets
+## Upgrading to Sprockets 4.x
-For most people interested in using Sprockets, you will want to see [End User Asset Generation](guides/end_user_asset_generation.md) guide. This contains information about Sprockets' directive syntax and default processing behavior.
+These are the major features in Sprockets 4.x
+- Source Maps
+- Manifest.js
+- ES6 support
+- Deprecated processor interface in 3.x is removed in 4.x
+
+Read more about them by referencing [Upgrading document](UPGRADING.md)
+
+## Guides
+
+For most people interested in using Sprockets, you will want to see the README below.
+
If you are a framework developer that is using Sprockets, see [Building an Asset Processing Framework](guides/building_an_asset_processing_framework.md).
If you are a library developer who is extending the functionality of Sprockets, see [Extending Sprockets](guides/extending_sprockets.md).
-Below is a disjointed mix of documentation for all three of these roles. Eventually they will be moved to an appropriate guide, but for now, the recommended way to consume this documentation is to view the appropriate guide first and then supplement with docs from the README.
+If you want to work on Sprockets or better understand how it works read [How Sprockets Works](guides/how_sprockets_works.md)
-## Behavior
+## Behavior Overview
-### Index files are proxies for folders
+You can interact with Sprockets primarily through directives and file extensions. This section covers how to use each of these things, and the defaults that ship with Sprockets.
-In Sprockets, index files such as `index.js` or `index.css` inside of a folder will generate a file with the folder's name. So if you have a file named `foo/index.js`, it will compile down to `foo.js`. This is similar to Node.js's behavior of using [folders as modules](https://nodejs.org/api/modules.html#modules_folders_as_modules). It is also somewhat similar to the way that a file in `public/my_folder/index.html` can be reached by a request to `/my_folder`. This means that you cannot directly use an index file. For example this would not work:
+Since you are likely using Sprockets through another framework (such as the [the Rails asset pipeline](http://guides.rubyonrails.org/asset_pipeline.html)), there will be configuration options you can toggle that will change behavior such as what directories or files get compiled. For that documentation you should see your framework's documentation.
-```
-<%= asset_path("foo/index.js") %>
-```
+#### Accessing Assets
-Instead you would need to use:
+Assets in Sprockets are always referenced by their *logical path*.
-```
-<%= asset_path("foo.js") %>
-```
+The logical path is the path of the asset source file relative to its
+containing directory in the load path. For example, if your load path
+contains the directory `app/assets/javascripts`:
-Why would you want to use this behavior? It is common behavior where you might want to include an entire directory of files in a top level javascript. You can do this in Sprockets using `require_tree .`
+<table>
+ <tr>
+ <th>Logical path</th>
+ <th>Source file on disk</th>
+ </tr>
+ <tr>
+ <td>application.js</td>
+ <td>app/assets/javascripts/application.js</td>
+ </tr>
+ <tr>
+ <td>models/project.js</td>
+ <td>app/assets/javascripts/models/project.js</td>
+ </tr>
+ <tr>
+ <td>hello.js</td>
+ <td>app/assets/javascripts/hello.coffee</td>
+ </tr>
+</table>
-```
-//= require_tree .
-```
+> Note: For assets that are compiled or transpiled, you want to specify the extension that you want, not the extension on disk. For example we specified `hello.js` even if the file on disk is a coffeescript file, since the asset it will generate is javascript.
-This has the problem that files are required alphabetically. If your directory has `jquery-ui.js` and `jquery.min.js`, then Sprockets will require `jquery-ui.js` before `jquery` is required, which won't work (because jquery-ui depends on jquery). Previously the only way to get the correct ordering would be to rename your files, something like `0-jquery-ui.js`. Instead of doing that you can use an index file.
+### Directives
-For example, if you have an `application.js` and want all the files in the `foo/` folder you could do this:
+Directives are special comments in your asset file and the main way of interacting with processors. What kind of interactions? You can use these directives to tell Sprockets to load other files, or specify dependencies on other assets.
+For example, let's say you have custom JavaScript that you've written. You put this javascript in a file called `beta.js`. The javascript makes heavy use of jQuery, so you need to load that before your code executes. You could add a `require` directive to the top of `beta.js`:
+
+```js
+//= require jquery
+
+$().ready({
+ // my custom code here
+})
```
-//= require foo.js
-```
-Then create a file `foo/index.js` that requires all the files in that folder in any order you want:
+The directive processor understands comment blocks in three formats:
+``` css
+/* Multi-line comment blocks (CSS, SCSS, JavaScript)
+ *= require foo
+ */
```
-//= require ./foo.min.js
-//= require ./foo-ui.js
+
+``` js
+// Single-line comment blocks (SCSS, JavaScript)
+//= require foo
```
-Now, your `application.js` will correctly load the `foo.min.js` before `foo-ui.js`. If you used `require_tree` it would not work correctly.
+``` coffee
+# Single-line comment blocks (CoffeeScript)
+#= require foo
+```
-## Understanding the Sprockets Environment
+> Note: Directives are only processed if they come before any application code. Once you have a line that does not include a comment or whitespace then Sprockets will stop looking for directives. If you use a directive outside of the "header" of the document it will not do anything, and won't raise any errors.
-You'll need an instance of the `Sprockets::Environment` class to
-access and serve assets from your application. Under Rails 4.0 and
-later, `YourApp::Application.assets` is a preconfigured
-`Sprockets::Environment` instance. For Rack-based applications, create
-an instance in `config.ru`.
+Here is a list of the available directives:
-The Sprockets `Environment` has methods for retrieving and serving
-assets, manipulating the load path, and registering processors. It is
-also a Rack application that can be mounted at a URL to serve assets
-over HTTP.
+- [`require`](#require) - Add the contents of a file to current
+- [`require_self`](#require_self) - Change order of where current contents are concatenated to current
+- [`require_directory`](#require_directory) - Add contents of each file in a folder to current
+- [`require_tree`](#require_tree) - Add contents of all files in all directories in a path to current
+- [`link`](#link) - Make target file compile and be publically available without adding contents to current
+- [`link_directory`](#link_directory) - Make target directory compile and be publically available without adding contents to current
+- [`link_tree`](#link_tree) - Make target tree compile and be publically available without adding contents to current
+- [`depend_on`](#depend_on) - Recompile current file if target has changed
+- [`stub`](#stub) - Ignore target file
-### The Load Path
+You can see what each of these does below.
-The *load path* is an ordered list of directories that Sprockets uses
-to search for assets.
+### Specifying Processors through File Extensions
-In the simplest case, a Sprockets environment's load path will consist
-of a single directory containing your application's asset source
-files. When mounted, the environment will serve assets from this
-directory as if they were static files in your public root.
+Sprockets uses the filename extensions to determine what processors to run on your file and in what order. For example if you have a file:
-The power of the load path is that it lets you organize your source
-files into multiple directories -- even directories that live outside
-your application -- and combine those directories into a single
-virtual filesystem. That means you can easily bundle JavaScript, CSS
-and images into a Ruby library or [Bower](http://bower.io) package and import them into your application.
+```
+application.scss
+```
-#### Manipulating the Load Path
+Then Sprockets will by default run the sass processor (which implements scss). The output file will be converted to css.
-To add a directory to your environment's load path, use the
-`append_path` and `prepend_path` methods. Directories at the beginning
-of the load path have precedence over subsequent directories.
+You can specify multiple processors by specifying multiple file extensions. For example you can use Ruby's [ERB template language](#invoking-ruby-with-erb) to embed content in your doc before running the sass processor. To accomplish this you would need to name your file
-``` ruby
-environment = Sprockets::Environment.new
-environment.append_path 'app/assets/javascripts'
-environment.append_path 'lib/assets/javascripts'
-environment.append_path 'vendor/assets/bower_components'
```
+application.scss.erb
+```
-In general, you should append to the path by default and reserve
-prepending for cases where you need to override existing assets.
+Processors are run from right to left (tail to head), so in the above example the processor associated with `erb` will be run before the processor associated with `scss` extension.
-### Accessing Assets
+For a description of the processors that Sprockets has by default see the "default processors" section below. Other libraries may register additional processors.
-Once you've set up your environment's load path, you can mount the
-environment as a Rack server and request assets via HTTP. You can also
-access assets programmatically from within your application.
+When "asking" for a compiled file, you always ask for the extension you want. For example if you're using Rails, to get the contents of `application.scss.erb` you would use
-#### Logical Paths
+```
+asset_path("application.css")
+```
-Assets in Sprockets are always referenced by their *logical path*.
+Sprockets understands that `application.scss.erb` will compile down to a `application.css`. Ask for what you need, not what you have.
-The logical path is the path of the asset source file relative to its
-containing directory in the load path. For example, if your load path
-contains the directory `app/assets/javascripts`:
+If this isn't working like you expect, make sure you didn't typo an extension, and make sure the file is on a "load path" (see framework docs for adding new load paths).
-<table>
- <tr>
- <th>Asset source file</th>
- <th>Logical path</th>
- </tr>
- <tr>
- <td>app/assets/javascripts/application.js</td>
- <td>application.js</td>
- </tr>
- <tr>
- <td>app/assets/javascripts/models/project.js</td>
- <td>models/project.js</td>
- </tr>
-</table>
+## File Order Processing
-In this way, all directories in the load path are merged to create a
-virtual filesystem whose entries are logical paths.
+By default files are processed in alphabetical order. This behavior can impact your asset compilation when one asset needs to be loaded before another.
-#### Serving Assets Over HTTP
+For example if you have an `application.js` and it loads another directory
-When you mount an environment, all of its assets are accessible as
-logical paths underneath the *mount point*. For example, if you mount
-your environment at `/assets` and request the URL
-`/assets/application.js`, Sprockets will search your load path for the
-file named `application.js` and serve it.
+```js
+//= require_directory my_javascript
+```
-Under Rails 4.0 and later, your Sprockets environment is automatically
-mounted at `/assets`. If you are using Sprockets with a Rack
-application, you will need to mount the environment yourself. A good
-way to do this is with the `map` method in `config.ru`:
+The files in that directory will be loaded in alphabetical order. If the directory looks like this:
-``` ruby
-require 'sprockets'
-map '/assets' do
- environment = Sprockets::Environment.new
- environment.append_path 'app/assets/javascripts'
- environment.append_path 'app/assets/stylesheets'
- run environment
-end
+```sh
+$ ls -1 my_javascript/
-map '/' do
- run YourRackApp
-end
+alpha.js
+beta.js
+jquery.js
```
-#### Accessing Assets Programmatically
+Then `alpha.js` will be loaded before either of the other two. This can be a problem if `alpha.js` uses jquery. For this reason it is not recommend to use `require_directory` with files that are ordering dependent. You can either require individual files manually:
-You can use the `find_asset` method (aliased as `[]`) to retrieve an
-asset from a Sprockets environment. Pass it a logical path and you'll
-get a `Sprockets::Asset` instance back:
+```js
+//= require jquery
+//= require alpha
+//= require beta
+```
-``` ruby
-environment['application.js']
-# => #<Sprockets::Asset ...>
+Or you can use index files to proxy your folders.
+
+### Index files are proxies for folders
+
+In Sprockets index files such as `index.js` or `index.css` files inside of a folder will generate a file with the folder's name. So if you have a `foo/index.js` file it will compile down to `foo.js`. This is similar to NPM's behavior of using [folders as modules](https://nodejs.org/api/modules.html#modules_folders_as_modules). It is also somewhat similar to the way that a file in `public/my_folder/index.html` can be reached by a request to `/my_folder`. This means that you cannot directly use an index file. For example this would not work:
+
+```erb
+<%= asset_path("foo/index.js") %>
```
-Call `to_s` on the resulting asset to access its contents, `length` to
-get its length in bytes, `mtime` to query its last-modified time, and
-`filename` to get its full path on the filesystem.
+Instead you would need to use:
+```erb
+<%= asset_path("foo.js") %>
+```
-## Using Processors
+Why would you want to use this behavior? It is common behavior where you might want to include an entire directory of files in a top level JavaScript. You can do this in Sprockets using `require_tree .`
-Asset source files can be written in another format, like SCSS or CoffeeScript,
-and automatically compiled to CSS or JavaScript by Sprockets. Processors that
-convert a file from one format to another are called *transformers*.
+```js
+//= require_tree .
+```
-### Minifying Assets
+This has the problem that files are required alphabetically. If your directory has `jquery-ui.js` and `jquery.min.js` then Sprockets will require `jquery-ui.js` before `jquery` is required which won't work (because jquery-ui depends on jquery). Previously the only way to get the correct ordering would be to rename your files, something like `0-jquery-ui.js`. Instead of doing that you can use an index file.
-Several JavaScript and CSS minifiers are available through shorthand.
+For example, if you have an `application.js` and want all the files in the `foo/` folder you could do this:
-``` ruby
-environment.js_compressor = :uglify
-environment.css_compressor = :scss
+```js
+//= require foo.js
```
-If you are using Sprockets directly with a Rack app, don't forget to add
-the `uglifier` and `sass` gems to your Gemfile when using above options.
+Then create a file `foo/index.js` that requires all the files in that folder in any order you want using relative references:
-### Styling with Sass and SCSS
+```js
+//= require ./foo.min.js
+//= require ./foo-ui.js
+```
-[Sass](http://sass-lang.com/) is a language that compiles to CSS and
-adds features like nested rules, variables, mixins and selector
-inheritance.
+Now in your `application.js` will correctly load the `foo.min.js` before `foo-ui.js`. If you used `require_tree` it would not work correctly.
-If the `sass` gem is available to your application, you can use Sass
-to write CSS assets in Sprockets.
+## Cache
-Sprockets supports both Sass syntaxes. For the original
-whitespace-sensitive syntax, use the extension `.sass`. For the
-new SCSS syntax, use the extension `.scss`.
+Compiling assets is slow. It requires a lot of disk use to pull assets off of hard drives, a lot of RAM to manipulate those files in memory, and a lot of CPU for compilation operations. Because of this Sprockets has a cache to speed up asset compilation times. That's the good news. The bad news, is that sprockets has a cache and if you've found a bug it's likely going to involve the cache.
-### Scripting with CoffeeScript
+By default Sprockets uses the file system to cache assets. It makes sense that Sprockets does not want to generate assets that already exist on disk in `public/assets`, what might not be as intuitive is that Sprockets needs to cache "partial" assets.
-[CoffeeScript](http://jashkenas.github.io/coffeescript/) is a
-language that compiles to the "good parts" of JavaScript, featuring a
-cleaner syntax with array comprehensions, classes, and function
-binding.
+For example if you have an `application.js` and it is made up of `a.js`, `b.js`, all the way to `z.js`
-If the `coffee-script` gem is available to your application, you can
-use CoffeeScript to write JavaScript assets in Sprockets. Note that
-the CoffeeScript compiler is written in JavaScript, and you will need
-an [ExecJS](https://github.com/rails/execjs)-supported runtime
-on your system to invoke it.
+```js
+//= require a.js
+//= require b.js
+# ...
+//= require z.js
+```
-To write JavaScript assets with CoffeeScript, use the extension
-`.coffee`.
+The first time this file is compiled the `application.js` output will be written to disk, but also intermediary compiled files for `a.js` etc. will be written to the cache directory (usually `tmp/cache/assets`).
-### JavaScript Templating with EJS and Eco
+So, if `b.js` changes it will get recompiled. However instead of having to recompile the other files from `a.js` to `z.js` since they did not change, we can use the prior intermediary files stored in the cached values . If these files were expensive to generate, then this "partial" asset cache strategy can save a lot of time.
-Sprockets supports *JavaScript templates* for client-side rendering of
-strings or markup. JavaScript templates have the special format
-extension `.jst` and are compiled to JavaScript functions.
+Directives such as `require`, `link`, and `depend_on` tell Sprockets what assets need to be re-compiled when a file changes. Files are considered "fresh" based on their mtime on disk and a combination of cache keys.
-When loaded, a JavaScript template function can be accessed by its
-logical path as a property on the global `JST` object. Invoke a
-template function to render the template as a string. The resulting
-string can then be inserted into the DOM.
+On Rails you can force a "clean" install by clearing the `public/assets` and `tmp/cache/assets` directories.
-```
-<!-- templates/hello.jst.ejs -->
-<div>Hello, <span><%= name %></span>!</div>
-// application.js
-//= require templates/hello
-$("#hello").html(JST["templates/hello"]({ name: "Sam" }));
+## Default Directives
+
+Directives take a path or a path to a file. Paths for directive can be relative to the current file, for example:
+
+```js
+//= require ../foo.js
```
-Sprockets supports two JavaScript template languages:
-[EJS](https://github.com/sstephenson/ruby-ejs), for embedded
-JavaScript, and [Eco](https://github.com/sstephenson/ruby-eco), for
-embedded CoffeeScript. Both languages use the familiar `<% … %>`
-syntax for embedding logic in templates.
+This would load the file up one directory and named `foo.js`. However this isn't required if `foo.js` is on one of Sprocket's load paths. You can simply use
-If the `ejs` gem is available to your application, you can use EJS
-templates in Sprockets. EJS templates have the extension `.jst.ejs`.
+```js
+//= require foo.js
+```
-If the `eco` gem is available to your application, you can use [Eco
-templates](https://github.com/sstephenson/eco) in Sprockets. Eco
-templates have the extension `.jst.eco`. Note that the `eco` gem
-depends on the CoffeeScript compiler, so the same caveats apply as
-outlined above for the CoffeeScript engine.
+Without any prepended dots and sprockets will search for the asset. If the asset is on a sub-path of the load path, you can specify it without using a relative path as well:
-### Invoking Ruby with ERB
+```js
+//= require sub/path/foo.js
+```
-Sprockets provides an ERB engine for preprocessing assets using
-embedded Ruby code. Append `.erb` to a CSS or JavaScript asset's
-filename to enable the ERB engine.
+You can also use an absolute path, but this is discouraged unless you know the directory structure of every machine you plan on running code on.
-Ruby code embedded in an asset is evaluated in the context of a
-`Sprockets::Context` instance for the given asset. Common uses for ERB
-include:
+Below is a section for each of the built in directive types supported by Sprockets.
-- embedding another asset as a Base64-encoded `data:` URI with the
- `asset_data_uri` helper
-- inserting the URL to another asset, such as with the `asset_path`
- helper provided by the Sprockets Rails plugin
-- embedding other application resources, such as a localized string
- database, in a JavaScript asset via JSON
-- embedding version constants loaded from another file
+### require
-See the [Helper Methods](lib/sprockets/context.rb) section for more information about
-interacting with `Sprockets::Context` instances via ERB.
+`require` *path* inserts the contents of the asset source file
+specified by *path*. If the file is required multiple times, it will
+appear in the bundle only once.
+**Example:**
-## Managing and Bundling Dependencies
+If you've got an `a.js`:
-You can create *asset bundles* -- ordered concatenations of asset
-source files -- by specifying dependencies in a special comment syntax
-at the top of each source file.
+```js
+var a = "A";
+```
-Sprockets reads these comments, called *directives*, and processes
-them to recursively build a dependency graph. When you request an
-asset with dependencies, the dependencies will be included in order at
-the top of the file.
+and a `b.js`;
-### The Directive Processor
+```js
+var b = "B";
+```
-Sprockets runs the *directive processor* on each CSS and JavaScript
-source file. The directive processor scans for comment lines beginning
-with `=` in comment blocks at the top of the file.
+Then you could require both of these in an `application.js`
-``` js
-//= require jquery
-//= require jquery-ui
-//= require backbone
-//= require_tree .
+```js
+//= require a.js
+//= require b.js
```
-The first word immediately following `=` specifies the directive
-name. Any words following the directive name are treated as
-arguments. Arguments may be placed in single or double quotes if they
-contain spaces, similar to commands in the Unix shell.
+Which would generate one concatenated file:
-**Note**: Non-directive comment lines will be preserved in the final
- asset, but directive comments are stripped after
- processing. Sprockets will not look for directives in comment blocks
- that occur after the first line of code.
+```js
+var a = "A";
+var b = "B";
+```
-#### Supported Comment Types
+### require_self
-The directive processor understands comment blocks in three formats:
+`require_self` tells Sprockets to insert the body of the current
+source file before any subsequent `require` directives.
-``` css
-/* Multi-line comment blocks (CSS, SCSS, JavaScript)
- *= require foo
- */
-```
+**Example:**
-``` js
-// Single-line comment blocks (SCSS, JavaScript)
-//= require foo
-```
+If you've got an `a.js`:
-``` coffee
-# Single-line comment blocks (CoffeeScript)
-#= require foo
+```js
+var a = "A";
```
-### Sprockets Directives
+And an `application.js`
-You can use the following directives to declare dependencies in asset
-source files.
+```js
+//= require_self
+//= require 'a.js'
-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.
+var app_name = "Sprockets";
+```
-#### The `require` Directive
+Then this will take the contents of `application.js` (that come after the last require) and put them at the beginning of the file:
-`require` *path* inserts the contents of the asset source file
-specified by *path*. If the same file is required multiple times
-with different path expressions, it will appear in the bundle only once.
+```js
+var app_name = "Sprockets";
+var a = "A";
+```
-#### The `require_directory` Directive
+### require_directory
`require_directory` *path* requires all source files of the same
format in the directory specified by *path*. Files are required in
alphabetical order.
-#### The `require_tree` Directive
+**Example:**
+If we've got a directory called `alphabet` with an `a.js` and `b.js` files like before, then our `application.js`
+
+```js
+//= require_directory alphabet
+```
+
+Would produce:
+
+```js
+var a = "A";
+var b = "B";
+```
+
+You can also see [Index files are proxies for folders](#index-files-are-proxies-for-folders) for another method of organizing folders that will give you more control.
+
+### require_tree
+
`require_tree` *path* works like `require_directory`, but operates
recursively to require all files in all subdirectories of the
directory specified by *path*.
-#### The `require_self` Directive
+### link
-`require_self` tells Sprockets to insert the body of the current
-source file before any subsequent `require` directives.
-
-#### The `link` Directive
-
`link` *path* declares a dependency on the target *path* and adds it to a list
of subdependencies to automatically be compiled when the asset is written out to
disk.
-For an example, in a CSS file you might reference an external image that always
-needs to be compiled along with the css file.
+Example:
-``` css
-/*= link "logo.png" */
-.logo {
- background-image: url(logo.png)
-}
-```
+If you've got a `manifest.js` file and you want to explicitly make sure an `admin.js` file is
+generated and made available to the public you can link it like this:
-However, if you use a `asset-path` or `asset-url` SCSS helper, these links will
-automatically be defined for you.
-
-``` css
-.logo {
- background-image: asset-url("logo.png")
-}
```
+//= link admin.js
+```
-#### The `link_directory` Directive
+### link_directory
`link_directory` *path* links all the files inside the directory specified by the *path*
-#### The `link_tree` Directive
+### link_tree
`link_tree` *path* works like `link_directory`, but operates
recursively to link all files in all subdirectories of the
directory specified by *path*.
-#### The `depend_on` Directive
+Example:
+You can specify a file extension so any extra files will be ignored:
+
+```js
+//= link_tree path/to/folder .js
+```
+
+> Note: There is an intentional space between the path and the extension
+
+### depend_on
+
`depend_on` *path* declares a dependency on the given *path* without
including it in the bundle. This is useful when you need to expire an
asset's cache in response to a change in another file.
-#### The `depend_on_asset` Directive
+**Example:**
+If you have a file such as `bar.data` and you're using data from that file in another file, then
+you need to tell sprockets that it needs to re-compile the file if `bar.data` changes:
+
+```js
+//= depend_on "bar.data"
+
+var bar = '<%= File.read("bar.data") %>'
+```
+
+### depend_on_asset
+
`depend_on_asset` *path* works like `depend_on`, but operates
recursively reading the file and following the directives found. This is automatically implied if you use `link`, so consider if it just makes sense using `link` instead of `depend_on_asset`.
-#### The `stub` Directive
+### stub
`stub` *path* excludes that asset and its dependencies from the asset bundle.
The *path* must be a valid asset and may or may not already be part
of the bundle. `stub` should only be used at the top level bundle, not
within any subdependencies.
-## Processor Interface
+### Invoking Ruby with ERB
-Sprockets 2.x was originally designed around [Tilt](https://github.com/rtomayko/tilt)'s engine interface. However, starting with 3.x, a new interface has been introduced deprecating Tilt.
+Sprockets provides an ERB engine for preprocessing assets using
+embedded Ruby code. Append `.erb` to a CSS or JavaScript asset's
+filename to enable the ERB engine.
-Similar to Rack, a processor is any "callable" (an object that responds to `call`). This may be a simple Proc or a full class that defines a `def self.call(input)` method. The `call` method accepts an `input` Hash and returns a Hash of metadata.
+For example if you have an `app/application/javascripts/app_name.js.erb`
+you could have this in the template
-Also see [`Sprockets::ProcessorUtils`](https://github.com/rails/sprockets/blob/master/lib/sprockets/processor_utils.rb) for public helper methods.
+```js
+var app_name = "<%= ENV['APP_NAME'] %>";
+```
-### Input Hash
+Generated files are cached. If you're using an `ENV` var then
+when you change then ENV var the asset will be forced to
+recompile. This behavior is only true for environment variables,
+if you are pulling a value from somewhere else, such as a database,
+must manually invalidate the cache to see the change.
-The `input` Hash defines the following public fields.
+If you're using Rails, there are helpers you can use such as `asset_url`
+that will cause a recompile if the value changes.
-* `:data` - String asset contents.
-* `:environment` - Current `Sprockets::Environment` instance.
-* `:cache` - A `Sprockets::Cache` instance. See [`Sprockets::Cache#fetch`](https://github.com/rails/sprockets/blob/master/lib/sprockets/cache.rb).
-* `:uri` - String Asset URI.
-* `:load_path` - String current load path for filename.
-* `:name` - String logical path for filename.
-* `:content_type` - String content type of the output asset.
-* `:metadata` - Hash of processor metadata.
+For example if you have this in your `application.css`
-``` ruby
-def self.call(input)
- input[:cache].fetch("my:cache:key:v1") do
- # Remove all semicolons from source
- input[:data].gsub(";", "")
- end
-end
+``` css
+.logo {
+ background: url(<%= asset_url("logo.png") %>)
+}
```
-### return Hash
+When you modify the `logo.png` on disk, it will force `application.css` to be
+recompiled so that the fingerprint will be correct in the generated asset.
-The processor should return metadata `Hash`. With the exception of the `:data` key, the processor can store arbitrary valid JSON values in this Hash. The data will be stored and exposed on `Asset#metadata`.
+You can manually make sprockets depend on any other file that is generated
+by sprockets by using the `depend_on` directive. Rails implements the above
+feature by auto calling `depend_on` on the original asset when the `asset_url`
+is used inside of an asset.
-The returned `:data` replaces the assets `input[:data]` to the next processor in the chain. Returning a `String` is shorthand for returning `{ data: str }`. And returning `nil` is shorthand for a no-op where the input data is not transformed, `{ data: input[:data] }`.
+### Styling with Sass and SCSS
-### metadata
+[Sass](http://sass-lang.com/) is a language that compiles to CSS and
+adds features like nested rules, variables, mixins and selector
+inheritance.
-The metadata Hash provides an open format for processors to extend the pipeline processor. Internally, built-in processors use it for passing data to each other.
+If the `sass` gem is available to your application, you can use Sass
+to write CSS assets in Sprockets.
-* `:required` - A `Set` of String Asset URIs that the Bundle processor should concatenate together.
-* `:stubbed` - A `Set` of String Asset URIs that will be omitted from the `:required` set.
-* `:links` - A `Set` of String Asset URIs that should be compiled along with this asset.
-* `:dependencies` - A `Set` of String Cache URIs that should be monitored for caching.
-* `:map` - An `Array` of source maps for the asset.
-* `:charset` - The mime charset for an asset.
+Sprockets supports both Sass syntaxes. For the original
+whitespace-sensitive syntax, use the extension `.sass`. For the
+new SCSS syntax, use the extension `.scss`.
+In Rails if you have `app/application/stylesheets/foo.scss` it can
+be referenced with `<%= asset_path("foo.css") %>`. When referencing
+an asset in Rails, always specify the extension you want. Sprockets will
+convert `foo.scss` to `foo.css`.
+
+### Scripting with CoffeeScript
+
+[CoffeeScript](http://jashkenas.github.io/coffeescript/) is a
+language that compiles to the "good parts" of JavaScript, featuring a
+cleaner syntax with array comprehensions, classes, and function
+binding.
+
+If the `coffee-script` gem is available to your application, you can
+use CoffeeScript to write JavaScript assets in Sprockets. Note that
+the CoffeeScript compiler is written in JavaScript, and you will need
+an [ExecJS](https://github.com/rails/execjs)-supported runtime
+on your system to invoke it.
+
+To write JavaScript assets with CoffeeScript, use the extension
+`.coffee`.
+
+In Rails if you have `app/application/javascripts/foo.coffee` it can
+be referenced with `<%= asset_path("foo.js") %>`. When referencing
+an asset in Rails, always specify the extension you want. Sprockets will
+convert `foo.coffee` to `foo.js`.
+
+
+## ES6 Support
+
+Sprockets 4 ships with a Babel processor. This allows you to transpile ECMAScript6 to JavaScript just like you would transpile CoffeeScript to JavaScript. To use this, modify your Gemfile:
+
+```ruby
+gem 'babel-transpiler'
+```
+
+Any asset with the extension `es6` will be treated as an ES6 file:
+
+```es6
+// app/assets/javascript/application.es6
+
+var square = (n) => n * n
+
+console.log(square);
+```
+
+Start a Rails server in development mode and visit `localhost:3000/assets/application.js`, and this asset will be transpiled to JavaScript:
+
+```js
+var square = function square(n) {
+ return n * n;
+};
+
+console.log(square);
+```
+
+
+### JavaScript Templating with EJS and Eco
+
+Sprockets supports *JavaScript templates* for client-side rendering of
+strings or markup. JavaScript templates have the special format
+extension `.jst` and are compiled to JavaScript functions.
+
+When loaded, a JavaScript template function can be accessed by its
+logical path as a property on the global `JST` object. Invoke a
+template function to render the template as a string. The resulting
+string can then be inserted into the DOM.
+
+```
+<!-- templates/hello.jst.ejs -->
+<div>Hello, <span><%= name %></span>!</div>
+
+// application.js
+//= require templates/hello
+$("#hello").html(JST["templates/hello"]({ name: "Sam" }));
+```
+
+Sprockets supports two JavaScript template languages:
+[EJS](https://github.com/sstephenson/ruby-ejs), for embedded
+JavaScript, and [Eco](https://github.com/sstephenson/ruby-eco), for
+embedded CoffeeScript. Both languages use the familiar `<% … %>`
+syntax for embedding logic in templates.
+
+If the `ejs` gem is available to your application, you can use EJS
+templates in Sprockets. EJS templates have the extension `.jst.ejs`.
+
+If the `eco` gem is available to your application, you can use [Eco
+templates](https://github.com/sstephenson/eco) in Sprockets. Eco
+templates have the extension `.jst.eco`. Note that the `eco` gem
+depends on the CoffeeScript compiler, so the same caveats apply as
+outlined above for the CoffeeScript engine.
+
+### Minifying Assets
+
+Several JavaScript and CSS minifiers are available through shorthand.
+
+In Rails you will specify them with:
+
+```ruby
+config.assets.js_compressor = :uglify
+config.assets.css_compressor = :scss
+```
+
+If you're not using Rails, configure this directly on the "environment".
+
``` ruby
-def self.call(input)
- # Any metadata may start off as nil, so initialize it the value
- required = Set.new(input[:metadata][:required])
+environment.js_compressor = :uglify
+environment.css_compressor = :scss
+```
- # Manually add "foo.js" asset uri to our bundle
- required << input[:environment].resolve("foo.js")
+If you are using Sprockets directly with a Rack app, don't forget to add
+the `uglifier` and `sass` gems to your Gemfile when using above options.
- { required: required }
-end
+### Gzip
+
+By default when Sprockets generates a compiled asset file it will also produce a gzipped copy of that file. Sprockets only gzips non-binary files such as CSS, javascript, and SVG files.
+
+For example if Sprockets is generating
+
```
+application-12345.css
+```
+
+Then it will also generate a compressed copy in
+
+```
+application-12345.css.gz
+```
+
+This behavior can be disabled, refer to your framework specific documentation.
+
+### Serving Assets
+
+In production you should generate your assets to a directory on disk and serve them either via Nginx or a feature like Rail's `config.public_file_server.enabled = true`.
+
+On Rails you can generate assets by running:
+
+```term
+$ RAILS_ENV=production rake assets:precompile
+```
+
+In development Rails will serve assets from `Sprockets::Server`.
## Contributing to Sprockets
Sprockets is the work of hundreds of contributors. You're encouraged to submit pull requests, propose
features and discuss issues.