To understand how to better work with a build tool such as Grunt, in this recipe we will customize the available Gruntfile.js
and package.json
. We will perform these changes without physically deleting these important files from the default installation. That way, we will be able to play around with customization and not lose the original files.
To start working on this recipe, we first need to navigate to the workspace
folder, and rename the original Gruntfile.js
and package.json
:
cd && cd workspace mv Gruntfile.js Gruntfile.jsORIGINAL mv package.json package.jsonORIGINAL
Now, we are ready to create new versions of these two files and add a custom Grunt task.
- Let's create new files:
cd && cd workspace touch Gruntfile.js package.json
- Open the
package.json
file:
c9 package.json
Note
An important thing to note is that if you had the old package.json
file open before, during, and after the file renaming using the mv
command, using the c9 <filename>
command might point to the tab that was not closed, and show the old version of the file. Feel free to close this file's tab by middle-clicking on it (this works just like browser tabs, at least on c9.io running in Chrome).
- The package file is completely empty, so let's add some code to it:
{ "name": "customGrunt", "version": "", "devDependencies": { "grunt": "~1.0.1" } }
What are we doing in the package.json
file? We are giving our package just some key:value pairs. Specifically, we are giving it a name, a version, and devDependencies
. Right now, only the devDependency
grunt is listed.
- Now we will add another plugin,
grunt-contrib-copy
, by typing the following command in our Bash console:
npm install grunt-contrib-copy --save-dev
Now, we can see that the grunt-contrib-copy
plugin has been added to the list of devDependencies in our custom package.json
:
{ "name": "customGrunt", "version": "", "devDependencies": { "grunt": "~1.0.1", "grunt-contrib-copy": "^1.0.0" } }
More information about this plugin can be found at https://www.npmjs.com/package/grunt-contrib-copy. In a nutshell, this plugin copies files as we specify.
- Now that we have prepared our
package.json
file, we can tell Grunt how to use it, by codingGruntfile.js
. We will begin by opening the currently emptyGruntfile.js
:
c9 Gruntfile.js
- We will add the following code to our
Gruntfile.js
:
'use strict'; module.exports = function (grunt) { grunt.initConfig({ pkg: grunt.file.readJSON('package.json'), // Define the copy task copy: { main: { expand: true, src: 'dist/css/bootstrap.css', dest: 'copy', }, }, }); grunt.loadNpmTasks("grunt-contrib-copy"); grunt.registerTask("default", ['copy']); };
Note
If you need a detailed explanation of how the above Gruntfile.js
code works, take a look at the How it works… section.
- Finally, it is time to run our default Grunt task, with verbose logging:
grunt -v
Running the preceding command will create a new folder and will copy the bootstrap.css
file in the workspace/copy/dist/css/bootstrap.css
path.
- Now that we have a basic understanding of just how Grunt runs its tasks, as well as how to modify its tasks to our liking, let's undo the changes we did. However, we will still keep our experimental files, just to have them handy if needed. What follows are the commands used to achieve this. The following commands will get to the root, navigate to
/workspace
, and make a new folder calledGruntExperiment
:
cd; cd workspace; mkdir GruntExperiment
- Now, let's move our custom
Gruntfile.js
andpackage.json
files, with the following two commands:
- Finally, we need to rename our original files to their original names, running the following commands (note that there are two commands here, for two files; each command was split on two rows so they can fit this page width):
mv node_modules/bootstrap/Gruntfile.jsORIGINAL node_modules/bootstrap/Gruntfile.js;
mv node_modules/bootstrap/package.jsonORIGINAL
node_modules/bootstrap/package.json
In this recipe, we have provided some custom code needed for a very simple Gruntfile.js
file to work in step 6 . What follows is the breakdown of what the code does.
On line 1, we use the strict
mode. On line 3, we call the grunt
module. Line 4 instructs grunt
to read our package.json
file. Lines 7-13 specify the copy
task. Line 17 is the entry point that registers the 'copy'
task as the default
task.