Gulp on Rails: Replacing the Asset Pipeline
Just over a year ago I started using Gulp and created gulp-starter. The setup works great out of the box on projects that are unopinionated about assets. Rails, unfortunately, is very opinionated, and it's taken me a year of trial and error to land on a solution that fully integrates a Gulp-based asset pipeline with Rails without compromising existing features or sacrificing speed, power, or flexiblity. The following setup is specifically customized for Rails with Heroku, but is easily adaptable to whatever tech stack you're using.
The Gulp Rails Pipeline
- Leaves Sprockets and manifest files intact for use with gem installed assets
- Transform and bundle CommonJS modules (js or coffee) with Browserify
- Compile .sass/.scss with Libsass (node-sass through gulp-sass)
- Autoprefix CSS
- Optimize images (could be expanded to further proccess or resize images)
- Compile an icon font + sass from a folder of SVGs
- Full BrowserSync integration (the original Rails Asset Pipeline didn't work with live stylesheet injection)
- Revision filenames in production for caching
- Build assets on deploy with Heroku
The ONLY thing in
app/assets are manifest files. This lets us continue to use Sprockets to require gem assets if necessary (e.g.,
//=require jquery_ujs). The compiled files are
.gitignore’d and rebuilt on deploy. All of our source assets (sass, js/coffee, images, svgs, etc.) exist in
gulp/assets, and compile to
public/assets. Check out the README for full details.
Why leave Sprockets in place?
In an early attempt to replace the Rails Pipeline (in a fit of frustration), I completely ripped it out. I disabled Sprockets, removed relevant gems, and replicated (and improved) every feature with Gulp tasks. It worked great for a while, until the development team we were handing the project off wanted to know how to include assets from a gem they'd installed. Normally, you'd just add a sprockets
//=require some_asset to the relevant css or js manifest file. But I'd removed the Pipeline altogether, and manifest files weren't a thing anymore.
We had to backtrack and re-think the problem. My goal was to completely replace the pipeline with full feature parity, including support for gem installed assets. So, because some gems rely on the asset pipeline, removing it altogether was no longer an option. Instead, I needed figure out a way to work with it (that I didn't hate), and that's the solution detailed above.
Why bother at all?
If you're already a Gulp fan, skip this section and get started with the repo. If you are currently using the Rails Asset Pipeline, and are wondering why you should bother changing up your workflow, read on!
For me, there's no better tool than Gulp to glue these incredible build tools together. Unfortunately, Rails disagrees and reeeally wants us to use its tech stack to handle assets. Sure, there are a few gems out there that let you cobble together some of the technology above, but I've found that they quickly fall behind, don't expose all the same options, and some things just aren't possible.
I believe I've finally settled on an integration that feels right, and doesn't compromise any existing features or new workflows we're looking add. If you have ideas, suggestions, or questions, comment below or head on over to GitHub and start contributing!