Case Study: Ruby Tools for non-Ruby Projects
Doug Avery, Former Senior Developer
Had this conversation with @trey on Twitter a few weeks back:
@trey nope, we use straight up ruby gems with bundler + guard. it works just fine— Doug N. Avery (@averydistracted) June 14, 2012
@averydistracted What about for non-Rails projects?— Trey Piepmeier (@trey) June 14, 2012
But wait — I was talking about non-Rails projects. Even though Viget's biggest projects use Rails, our front-end development team also works on static builds and ExpressionEngine sites. We use roughly the same stack of Ruby tools for almost all our front-end work.
There are a ton of great command-line tools for front-end development, mostly in Ruby and Node. Since we develop Rails sites, it makes sense for us to stick with Ruby tools (which isn't much of a restriction).
Of course, without the help Rails provides, some extra work needs to be done to manage the tools on these projects. The three challenges are:
- Distribution. How do we ensure that every dev on the project is using the same tools, and the same versions?
- Automation. How do our tools run themselves, saving us the hassle of remembering to manually use them before commits?
- Workflow. How can a group of devs work with the same tools simultaneously?
At Viget, our current solution is Bundler + Guard. Bundler maintains a package of Ruby gems that all devs can easily access and install, and Guard handles the automation of running them at the appropriate times (for example, when a .scss file is saved).
Case Study: BrianRegan.com
Late last year, we relaunched BrianRegan.com, complete with a new design and ExpressionEngine backend. Using Guard and Bundler, we were able to work with a number of powerful Ruby tools in a repeatable, distributed fashion. This setup enables a new dev to ramp up on the project with just a handful of commands:
Here's the file structure of the site. We've moved all the images, JS, CSS, and templates out of the ExpressionEngine core, which simplifies the development process a bit. Anything that needs compiling (in this case, just the SCSS files) is in "compile".
Before anything, a Gemfile needs to be written (basic example) to define the tools used on the project. Next step is setting up the automation, with a basic Guardfile:
# auto-compile with Compass and Sass guard 'compass' do watch /^.+(\.s[ac]ss)/ end # reload the browser when assets change guard 'livereload' do watch /templates/.+\.php/ watch /css/.+\.css/ watch /js/.+\.js/ end
Basically, that's all there is — once these files are in place, any new dev can jump into the project with just a few commands:
git clone [git repo] cd brianregan/assets bundle install bundle exec guard
After these run, devs are good to go. In the simple example above, Guard is just managing Compass and Livereload, but I'll show you how we used it to do more heavy lifting on brianregan.com:
BrianRegan.com has a desktop and mobile version, both highly graphical. The biggest challenge was keeping filesizes down wherever I could, and Compass helped with some simple, automated tools:
- Sprites. Once set up, Compass generated all my sprites on the fly, which was spectular in terms of file and time savings. If you're not automating your sprites, you're probably wasting time and making projects more brittle.
- Image-sized elements. BrianRegan.com used a number of text-replaced UI elements, and that usually means a lot of block-level elements with backgrounds, cut and sized by hand. Compass saved me the trouble by just sizing those elements automatically (gist). Once you have a few of these set up, the payoff is that you can tweak the sizes of controls, icons, and nav items just by modifying the background images. Pretty neat, right?
- Regular vs. retina images. Now that Sass has nested media queries, writing a mixin thats adjust the background-sizing/positioning for retina images is actually pretty simple. (gist)
Obviously, you don't need Guard to automate Compass compilation — "compass watch" works just fine, as do a number of GUI tools — Guard just rolls it into your whole automation suite, freeing you from having to manage any more tools.
Minifying files is a necessity, but it can be painful on static builds and ExpressionEngine sites. Since I was already running Sass, the CSS was minified — but the JS required a little extra work. It only took a few lines of guard code (gist) to auto-minify all the scripts.
BrianRegan.com had to look crisp on retina displays, which can be a challenge to manage when you have a lot of background images in your CSS. Thankfully, with a little setup, Guard can listen for image changes and automatically generate standard-sized images from retina-size ones (gist). Once you have the images sorted, including them in your SCSS is a simple matter (gist).
So there you have it — with Guard and a little ingenuity, you can put together an automated workflow that the whole team can share. Are you doing front-end development with local preprocessing, minification, and other command-line tools? We'd love to hear about your workflow in the comments.
Some other great reading on the subjects: