Automating tasks using Gulp

Gulp is a tool for task automation. Gulp helps in many automated tasks like parsing, watching files for changes, refreshing, bundling and minification, executing tests before build, checking against jslint, csslint and many more. Follow these links for a brief introduction to Gulp.

We will be using Gulp in this application only for Parsing, Watching and Refreshing.


The App Source code:

You can get the app from below link Sample App


Folder structure:

The folder structure is a very important factor to consider when using Gulp. There may be many resources like - .ts,. scc files that our browser doesn’t understand. Browser understands files like js, css, html. But we need to use many such extensions in our app. Gulp comes very helpful when dealing with such situations. Gulp parses those files and organizes our folder automatically according to the configuration set up in gulpfile.js.


We need a folder named assets where all other files that the browser doesn’t understand are placed. Then, we will have a folder called app where we will have all the files that the browser understands. Then the files from the assets folder are parsed and organized in the app folder specified in gulfile.js. The app folder will be executed in the dev environment.


The folder structure doesn’t require to be the same as this but it should be organized in a manner that distinguishes app files easily.

Initial Folder structure:

initial-folder

  • app folder: It will contain our app’s script, style and HTML files
  • assets: It will contain all the files used for development like typescript and sass files. These files will then be parsed into js and css files respectively in the app folder as shown in the next image
  • node_modules: It will contain our npm packages
  • gulpfile: At least one Gulp file is required in the application folder for the building process. It is kept in the root folder of this app
  • package.json: It will have a list of all the dependent packages for the app
  • tsconfig.json: It is a configuration file required for typescript. We are using typescript in the app


Folder structures after parsing:

folder-after-parsing

A new file and folder is created in the app folder:

  • app/scripts/app.js: The app.js is created by parsing the assets/scripts/main.ts file. All the other script files may belong to this app/scripts folder
  • app/styles/style.css: The style.css is created by parsing the assets/styles/style.scss. All the other style files may belong to this app/styles folder


Application Build Process:


Parsing: In this app, we have two types of file extensions: typescript and sass. These files need to be converted into javascript and css files respectively.

Script Parsing: In gulpfile.js, install the required dependency for Gulp and typescript files.

npm install –save-dev gulp gulp-typescript gulp-rename browser-sync

Create a file tsconfig.js in the root folder as shown in the image above. This is the config file or the typescript.

{ "files": [ "assets/scripts/main.ts" ], "compilerOptions": { "noImplicitAny": true, "target": "es5" } }

files property holds the list of typescript files.

In gulpfile.js, we imported these modules

var gulp = require("gulp"); var ts = require("gulp-typescript"); var rename = require("gulp-rename"); var browserSync = require('browser-sync').create(); var tsProject = ts.createProject("tsconfig.json"); 

Create a task name typescript.

//Typescript parsing  gulp.task("typescript", function () { return tsProject.src() .pipe(tsProject()) .js.pipe(rename('app.js')) .pipe(gulp.dest("app/scripts")) .pipe(browserSync.reload({ stream: true })); });


Explanation:

The typescript task will read the typescript file and convert the typescript to a JavaScript file.

  1. The task is reading the files mentioned in tsconfig
  2. It then parses the files
  3. ‘Rename’ is used to rename the file with js instead of main.js. Without renaming, it would have created the file main.js, same name as source file
  4. ‘gulp.dest’ is used for dumping the in-memory file to the physical location
  5. ‘browserSync.reload’ is used to refresh the browser whenever any change is made in the typescript file. We will come to it later on refresh part.

To check the task, run the following command on command prompt

gulp typescript


Style Parsing:

In gulpfile.js, install the required dependency for gulp and typescript files.

npm install –save-dev gulp-sass gulp-util

Import these modules in gulpfile.js

var sass = require('gulp-sass'); var gutil = require('gulp-util'); 

Create the SASS task

//SASS parsing gulp.task('sass', function () { return gulp.src('./assets/styles/style.scss') .pipe(sass({ style: 'expanded' })) .on('error', gutil.log) .pipe(gulp.dest('app/styles')) .pipe(browserSync.reload({ stream: true })); });


Explanation:

  1. The scss file in assets/styles/style.scss is read by the src method
  2. sass({ style: 'expanded' })) is transforming the scss to css file
  3. log will log on error
  4. dest('app/styles') is creating the physical css file in the specified location
  5. reload will refresh the browser whenever any change is made in style.scss file

To check the task run the following command on command prompt

gulp sass


Build Both the Tasks Together:

Create the build task

//Building the app gulp.task("build", ["typescript", 'sass'], function () { gutil.log('== Build done =='); }); 

run gulp build

It will execute both the tasks simultaneously. Both typescript and sass are tasks dependent on build. The build task is executed only when the dependent tasks are finished. A single build task with all other dependent tasks helps to have a single point to build the whole app.


Loading the App on the Browser:

Create a server task

gulp.task('serve', ["build"], function () { browserSync.init({ server: { baseDir: "app", index: "index.html" }, }); }); 

run gulp serve on command prompt

It will load the app with the browsersyn config after building the app.

To know more about browsersync, read the below link:

https://www.browsersync.io


The app is served from the app folder as configured in the config section of serve task of gulpfile.js. It loads the app/index.html file.

Gulp Parsing


Watching and Refreshing:

Create a task which will build the app, load the app and watch all the files for any changes.

//Start Point gulp.task("default", ["serve"], function () { //Watching changes in the file gulp.watch('assets/styles/style.scss', ['sass']); gulp.watch('assets/scripts/main.ts', ['typescript']); gulp.watch("app/index.html").on("change",function(){ console.log("html changed"); browserSync.reload(); }); }); 

run gulp

default is the task which executes when we just enter Gulp in the command prompt without any task name. It has a dependency on serve task which in turn has a dependency on the build task and so on.

gulp.watch is watching files for any changes and executes the tasks mentioned in the array.

gulp.watch('assets/styles/style.scss', ['sass']);

is watching for style.scss file for changes and executes the task sass whenever any change is made on this file.

//SASS parsing gulp.task('sass', function () { return gulp.src('./assets/styles/style.scss') .pipe(sass({ style: 'expanded' })) .on('error', gutil.log) .pipe(gulp.dest('app/styles')) // .pipe(connect.reload()); .pipe(browserSync.reload({ stream: true })); }); 


The sass task is having browserSync.reload method which will refresh the browser whenever this task is executed.

The same process is used for main.ts and app/index.html file for changes and refreshing


Conclusion:

In this app, the Gulp is used for a very simple and important process of parsing, watching and refreshing the app. Although the example is very basic, the approach could be used for other real-world applications.

Write a comment
Cancel Reply
  • Prasanjeet Debnath November 8, 2016, 10:01 am
    Hi Amit, Yes right. ".js" is not mandatory . The typescript example is taken from the typescript official documentation https://www.typescriptlang.org/docs/tutorial.html. It will then show you typescript parsing error but still your application will work and run. In this case, you can fix the typescript error by specifying datatype to Student class properties in assets\scripts\main.js. You can get the sample project mentioned in this post and play around.
    reply
  • Amit Trivedi November 8, 2016, 9:27 am
    In the statement `.js.pipe(rename('app.js'))` from the task "typescript", the `.js` is not required and causes Syntax Error.
    reply