Make sure that you're running the latest Sprockets 3 release. This document is a work in progress and not at all authoritative. It is meant to underline the biggest features and changes from Sprockets 3 to 4. If you're not already on Sprockets 3 check out https://github.com/rails/sprockets/blob/3.x/UPGRADING.md. Sprockets 3 was a compatability release to bridge to Sprockets 4, and many deprecated things have been removed in version 4.
This upgrading guide touches on:
- Source Maps
- Manifest.js
- ES6 support
- Deprecated processor interface in 3.x is removed in 4.x
Source maps are a major new feature. As a word of warning, source maps were half finished when this project was transitioned between maintainers. Please try things and if they don't work correctly open an issue with what you expected to happen, what happened and a small sample app showing the problem.
First, what is a source map? Source maps are a standard way to make debugging concatenated or compiled assets easier. When using Rails and Sprockets in development mode, no assets are concatenated. If your app used 10 JS files, all of them would be served independently. This helped with debugging: you got helpful errors like Error in file <file.js> on line <number>
that pointed at the problem instead of at an unrelated, minified JS file.
Source maps eliminate the need to serve these separate files. Instead, a special source map file can be read by the browser to help it understand how to unpack your assets. It "maps" the current, modified asset to its "source" so you can view the source when debugging. This way you can serve assets in development in the exact same way as in production. Fewer surprises is always better.
How do you know if source maps are working correctly? Try adding a syntax error to one of your assets and use the console to debug. Does it show the correct file and source location? Or does it reference the top level application.js
file?
Here's the last issue where source maps were discussed before the beta release. Here's a guide that talks about what a source map is and how it is used by the browser and generated by Sprockets.
Previously, if you wanted Rails to serve a non-standard named asset (any CSS not called application.css
or JS not called application.js
) you would have to add those files to a precompile list. For example, if you needed a marketing page with its own CSS you might add something like this:
# In your Rails configuration
config.assets.precompile += ["marketing.css"]
Sprockets 3 introduced the concept of a "manifest" file that could list all assets you want to make available using the link
directive. In this case, to compile the marketing.css
you would set precompile to:
config.assets.precompile = ["manifest.js"]
Then you will link
to that css file in your manifest.js
file. In Sprockets the link
directive declares that your file has a dependency on the thing you are linking, so it guarantees it will be compiled. Here's our example manifest file:
// app/assets/config/manifest.js
//
//= link application.css
//= link marketing.css
//
//= link application.js
Caution: the "link" directive should have an explicit content type or file extension.
Now you'll be able to use a <%= stylesheet_link_tag "marketing" %>
in your code. This is a standard way to let Sprockets know what files need to be compiled.
Some assets will be compiled when they are referenced from inside of another asset. For example, the asset_url
erb helper will automatically link assets:
.logo {
background: url(<%= asset_url("logo.png") %>)
}
When you do this Sprockets will "link" logo.png
behind the scenes. This lets Sprockets know that this file needs to be compiled and made publicly available. If that logo file changes, Sprockets will automatically see that change and re-compile the CSS file.
One benefit of using a manifest.js
file for this type of configuration is that now Sprockets is using Sprockets to understand what files need to be generated instead of a non-portable framework-specific interface.
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:
gem 'babel-transpiler'
Any asset with the extension es6
will be treated as an ES6 file:
// 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:
var square = function square(n) {
return n * n;
};
console.log(square);
If you are extending Sprockets you may want to support all current major versions of Sprockets (2, 3, and 4). The processor interface was deprecated from Sprockets 2 and a legacy shim was put into Sprockets 3. Now that Sprockets 4 is out, that shim no longer is active. You'll need to update your gem to either only use the new interface or use both interfaces.
Please see the "Supporting all versions of Sprockets in Processors" section in the extending Sprockets guide for details.