I had an issue the other day where I needed my Gruntfile.js to “know” what environment I was deploying to so it could use choose the correct parameter values.
Specifically, my Critical CSS Task needed to know whether it should use my Local, Dev, or Prod server to determine what CSS is critical.
TL;DR
Adding this to my Gruntfile.js…
grunt.config('environment', (function(){ var env = grunt.option('env') || 'local', domain; if (grunt.option('env') === 'prod') { domain = 'http://www.netbiscuits.com/'; } else if (grunt.option('env') === 'dev') { domain = 'http://dev.www.netbiscuits.com/'; } else { domain = 'http://netbiscuits-com:1234/'; } return domain; })());
… allows me to pass the environment to Grunt via the command line, like this…
grunt --env=dev
… and then tell my Critical CSS Task which environment I am deploying to, like this…
criticalcss : { 'home' : { options: { outputfile : 'css/critical/home.css', filename : 'css/style.min.css', url : grunt.config('environment') } },
Say What?
Okay, let’s break that down a bit…
Starting at the Start
Starting with the second block of code above, because that’s how the code actually flows:
grunt --env=dev
This is how you tell Grunt to get off its lazy butt and get to work. This can happen via command line, or, in the case of this project, via command line locally, but via DeployBot for Dev and Prod.
Typically you would start Grunt by simply typing grunt
and hitting Enter. You might also be familiar with something like grunt svgmin
which will start Grunt, but only run the svgmin
Task. But in our case we’re adding this --env=dev
at the end…
What’s happening here is we are essentially passing a variable called env
and setting a value to that variable, and in the above case that value is dev
.
Retrieving the Option
Next, we jump to the first code block from above:
grunt.config('environment', (function(){ var env = grunt.option('env') || 'local', domain; if (grunt.option('env') === 'prod') { domain = 'http://www.example.com/'; } else if (grunt.option('env') === 'dev') { domain = 'http://dev.example.com/'; } else { domain = 'http://www.example.local/'; } return domain; })());
This gets inserted just after the opening:
module.exports = function (grunt) { ...
So what’s happening?
- The first line creates a new Grunt
config
variable, calledenvironment
, and sets, as the value of that variable, a SIAF. - The SIAF checks to see if any command line options were passed along with the
grunt
command, specifically if there was one calledenv
(grunt.option('env')
). - If the
env
option was passed, it’s value is set as a local variable (also calledenv
); if not, it’s value is set aslocal
(thus giving us a default, so I don’t have to pass the option when working locally!). - The function then checks a couple possible values of the
env
variable, specificallyprod
anddev
, setting the appropriate value for thedomain
variable, and again, defaulting to local. - And finally returns the value of
domain
, thus setting the value of the Gruntconfig
variableenvironment
.
Putting it into Play
Finally, we make use of the env
variable by sending it to the Critical CSS Task:
criticalcss : { 'home' : { options: { outputfile : 'css/critical/home.css', filename : 'css/style.min.css', url : grunt.config('environment') } },
This is pretty standard Critical CSS stuff here, except for the url
parameter value, which is set using grunt.config('environment')
.
This grabs whatever value we set in that environment
config
variable and passes it to the Critical CSS Task.
All the Options
So, for my three environments, I use one of these Grunt commands to get the correct Critical CSS for my site:
- Local:
grunt
- Dev:
grunt --env=dev
- Prod:
grunt --env=prod
Again, local
is the default, so no options need to be passed there, making local development, where I manually start Grunt, the easiest. And Dev and Prod are both DeployBot-driven, so I just paste that command into the configuration page and save it.
Summation
This kind of dynamic variable passing could be really useful for all kinds of situations, including testing new methods or trying any different parameter values really easily, without having to keep editing and saving your Gruntfile.js.
Happy Grunting,
Atg