I’ve been working on a framework (good marketing term, right) for one of my teams at work for a while now and have been using Grunt to keep things in order. This framework is intended to be used on our internal “admin” forms that are used by our Business Analysts to configure our programs. One of the key requirements of this framework was that it be skinnable for each of our client systems so we can easily tell which one we’re in (since many BAs work across clients and many of the forms are identical across systems). The other key requirements was that the codebase be kept up-to-date in all of the client-specific CVS repos (yes, you read correctly, we’re still on CVS).
The Problem
I’d been using grunt for small projects for a while to lint and concatenate JS, compile SCSS, merge my SVG into one file and various other little tasks as needed. But this was different. I wanted to have a single location for the dev files where I could have my SCSS files, individual JS files and a little dev setup for mock JSON responses (and whatever else I might need). Then the compilation process that I needed grunt to do was to compile those source files into the appropriate client-specific folders (this destination is variable definition number 1, more on that later) using the client skin settings (just scss variables at this time) (this is variable definition number 2). And then my PHP header and footer files would read the files from the directories within one of those clients (variable definition number 3).
This was all well and good for initial development where I was focusing on one client as the test case. Everything always pointed to their CVS directory, their skin variables and their directory mapping within the PHP files. But then, once things were working there, we quickly wanted it in three clients. This was great, people liked the new framework and what it offered. But maintainability dropped like a rock. Now I had to run Grunt 3 times whenever I made a change (and this framework is very much in its alpha stage) but for each time I had to provide a new grunt CLI variable, change the variables in my scss files and change my PHP files to reference the right directories. No good. No good at all.
The Solution
As the boys on Top Gear like to say: How hard can it be? My plan was two step (mostly because I couldn’t stop updating the framework for a few weeks to make the change all at once): 1) change the scss and php variable locations to somehow read from a configuration file that grunt would generate as part of it’s duties and then 2) change the grunt file to iterate through the provided CVS locations all-at-once to distribute the updated code to each location.
Round One
To get start I installed grunt-php-set-constant, a Node module for setting PHP constants from within a grunt task. Seemed pretty straightforward, I would pass in whatever variable I was already passing into the grunt CLI and that would translate to the php constant being set appropriately in the header.php and footer.php files that control where to get the compiled CSS and minified JS files.
Then use Daniel Auener‘s approach for setting up color schemes in SCSS using Grunt. So this would easily take my goal for step one and would also make it very simple to update to step two once the rest of the application was ready to be distributed en masse. Ideally I wanted all my variables in one scss file so I could easily compare values and whatnot but I can get over that. I’m also using the autoprefixer package to make sure I’m good on all the vendor prefixes (really it’s mostly because I’m using Flexbox on this project) so each color scheme will be setup to compile to the common CVS location that the framework files reside in and then autoprefixer will distribute (as it’s already setup to do) to the right CVS location.
Round Two
The update of how Round One went and how Round Two shaped up will come later once things are actually up and running for a bit to make sure I’m not giving some poor advice on something.