Front-End Task Automation – Part 2
Work on a web integration project includes a lot of repetitive and not-so-interesting tasks. The following lines describe several very useful tools that can significantly facilitate and accelerate our work. These tools include Bower, Grunt, Gulp and Yeoman.
In the previous part, we explained what Bower, Grunt, Gulp and Yeoman are based on and now we can move on to introducing them further.
Bower
Bower is a package manager from Twitter and, as opposed to npm, which deals with the “server side”, Bower deals with client components, such as jQuery, Angular, Bootstrap, etc. Modules can be browsed at bower.io/search/.
Bower is available as an npm module and, since we will use it in all projects, we install it globally in the following way:
npm install bower -g
The commands are similar to npm and the installation of Bootstrap, for example, will look like this:
bower install bootstrap
Here you can see that the bootstrap module is also dependent on jQuery, and both were downloaded in the bower_components folder. From this folder, we can start using jQuery or Bootstrap in the project.
During the installation, we can again enter either the module names directly or refer to URL, local file, git repo, github, etc.
New project initialization is then executed by the following command:
bower init
After a brief questionnaire, it will create the file bower.json in the project (with a structure similar to package.json from npm), which describes the given project. The content of bower.json file is shown in the picture above.
Therefore, if we receive a new project from someone, it should contain both the package.json and bower.json files, on the basis of which we then perform the given project installation:
npm install
bower install
and everything important will be downloaded into the project. It should be noted, that although the command bower install bootstrap
itself, in an already existing project, physically adds bootstrap to this project, it does not update the bower.json file (dependencies section). If we want the given project to include this module, we must add the --save
parameter.
Grunt
Grunt “The JavaScript Task Runner” is an automation tool for front-end tasks and thus enables, for example, automatic minification of CSS and JavaScript, conversion of preprocessor codes (LESS, SASS …) to CSS, compilation of Coffee Script into JavaScript, etc. There are thousands of modules for Grunt, enabling a variety of interesting tasks:
- automatic change tracking by grunt-contrib-watch – the base of other modules for minification, compilation of LESS, SASS, etc.
- merging files by grunt-contrib-concat,
- minification of CSS by grunt-contrib-cssmin and JavaScript by grunt-contrib-uglify,
- compilation of LESS into CSS by grunt-contrib-less, compilation of SASS into CSS by grunt-contrib-sass,
- adding CSS3 vendor prefixes by grunt-autoprefixer,
- possible optimizing of images by grunt-contrib-imagemin,
- conversion of SVG vector images into PNG by grunt-svg2png,
- creating CSS sprites and generation of corresponding CSS by grunt-spritesmith,
- producing images of various sizes for responsive use by grunt-responsive-images,
- running JavaScript tests by, for example, grunt-contrib-jasmine,
- and much more…
The installation of Grunt itself is executed by npm in the following way:
npm install -g grunt-cli
When working with Grunt, there are two key files – package.json and a so called Gruntfile (Gruntfile.js, alternatively Gruntfile.coffee). Both files are already installed in an already existing project, only the dependencies remain to be installed by the npm install
command. In a new project, we can create the package.json file either manually by the npm init
command, or by the grunt-init template.
Then, using npm, we install Grunt itself between so called devDependencies, together with its modules, such as the uglify module used for the minification of JavaScript, in the following way:
npm install grunt-contrib-uglify --save-dev
Gruntfile
Gruntfile (Gruntfile.js or Gruntfile.coffee) is a file containing the configurations of individual Grunt tasks.
module.exports = function(grunt) {
//loading package.json
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
//uglify module definition - for
JavaScript minification
uglify: {
options: {
banner: '/*! <%= pkg.name %>
<%= grunt.template.today("dd-mm-yyyy") %>
*/\n'
},
dist: {
files: {
'js/input.min.js': ['js/input.js']
}
}
},
//watch module definition - this monitors
changes of js files and minifies them
watch: {
files: ['js/*.js'],
tasks: ['uglify']
}
});
//loading the required Grunt modules
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.loadNpmTasks('grunt-contrib-watch');
//registering of the default task executed
by entering the command grunt into
the command line
grunt.registerTask('default', ['watch']);
};
The example above shows a created simple Gruntfile with two modules (uglify and watch), where one module (watch) is added to the default Grunt task and is executed by entering the command grunt into the command line. This task monitors changes in JavaScript files and when such change happens, it runs the module uglify, which takes the input.js file and minifies it as input.min.js file. We can also run the uglify task separately by the grunt uglify command in command line.
Gulp
Gulp has the same use as Grunt. It only works in a slightly different way. Because Grunt focuses on configurability, it is more suitable for users preferring to configure code rather than write their own. To write our own code, we use Gulp instead. There is a variety of modules, although the amount is lower than in case of Grunt. Gulp does not need that much anyway. What would otherwise require a module in Grunt, you can write by yourselves using Gulp. Gulp also focuses on speed, although that can be increased in Grunt too, by the module jit-grunt, which ensures that other modules are loaded only when needed.
Another difference between Grunt and Gulp is in their approach to processing files. While in Grunt you can see individual intermediate steps of, for example, JavaScript merging and minification, Gulp works with so called Node.js streams. In this case, there are no intermediate results generated on the drive, but data are transferred between individual tasks via the pipeline instead.
The installation of Gulp itself is executed by npm in the following way:
npm install -g gulp
When working with Gulp, there are two key files – package.json and a so called Gulpfile (Gulpfile.js), it is therefore very similar to Grunt, including the installation of Gulp modules.
Gulpfile
//loading Gulp itself into an object named gulp
var gulp = require('gulp');
//loading watch module
var watch = require('gulp-watch');
//creating a new task "test", which only puts text into the command line
gulp.task('test', function() {
console.log('Hello, this is test ...');
});
//creating a new "default" task, which monitors the contents of input folder and copies every file created or modified in this folder into the output folder
gulp.task('default', function() {
gulp.src('input/*')
.pipe(watch())
.pipe(gulp.dest('output/'))
});
This simple example shows two tasks, one named test and the other one default. The default task is executed by entering gulp into the command line. The default task uses the gulp-watch module. The “test” task is executed by entering the command gulp test. It is obvious from this code what is the difference between the files Gruntfile and Gulpfile and why Gulp users require less modules.
Yeoman
Yeoman is used to generate code according to previously set templates (scaffolding). The templates in this case are not text files, but a pattern, according to which a base for an application or a part of it can be generated. This way we can generate, for instance, the base of a WordPress website, AngularJS application, etc.
Installation is performed in the following way:
npm install yo -g
We also need a so called generator, which decides what is created, where and how. We can either use a prearranged generator or create it ourselves.
Useful Tools – Alternative to Command Line
If you are not fans of the command line, I have good news for you. Bower, Grunt and Gulp are all natively supported in IDE Webstorm (PhpStorm) and the projects using these tools can thus be managed directly in IDE. The modules can be easily managed, but Gruntfile or Gulpfile still have to be edited manually.
Interesting links with examples of working with these tools:
- Grunt in WebStorm 8 shows how tasks are managed and executed
- Using Bower in WebStorm
Conclusion
Using these tools greatly facilitates and accelerates work of a web developer. It facilitates and, more importantly, unifies work in team, since individual configuration files are versioned (as opposed to separate modules). This way the unified configuration is shared by the whole team and one does not have to worry that every developer creates, for example, different CSS from SASS, or that there will be problems in JavaScript if the whole team uses JSHint.
You can now follow to the next part – article called: Putting Continuous Integration (CI) into Practice – Part 1.
Was this article helpful?
Support us to keep up the good work and to provide you even better content. Your donations will be used to help students get access to quality content for free and pay our contributors’ salaries, who work hard to create this website content! Thank you for all your support!
Reaction to comment: Cancel reply