Gulp Workflow For Building Web Projects
In this quick tip, we will build a simple and fast gulp workflow for building web projects.
If you are building a small web project, or testing an idea, and you just want to quickly get up and running, you will find gulp useful to help you handle your workflow tasks.
You can also check out the example github repo.
This is a list of essential gulp tasks we will setup:
For development, we need to bundle ES6 code for the browser, and include source maps, so we can easily debug it in the browser. We also watch source files for changes and re-bundle so we can quickly see the result of our changes. Optionally, we lint our code, so it helps detect errors in our code, we add it because it’s simple.
For production, again we bundle ES6 code for the browser, this time, we minify it. We also minify our CSS. Finally, we copy other assets to our build folder.
This is the simplest setup we need to get things working. Use
http-server to serve our project for development, and reload browser manually when the code changes, so we don’t have to complicate our setup to handle these jobs.
Setting Up The Project
Setup the file structure, and initialize our Node.js project, it will add a
package.json to our project.
Install npm dependencies for development:
gulp and some gulp plugins to handle gulp tasks.
babelify is browserify transform to transform ES6 code with babel and bundle it for the browser.
babel needs some plugins to work properly, so we include them as well.
watchify is browserify plugin for watching source files, and re-bundle on code changes. and
vinyl-source-stream is for gluing
Now add an
examples/index.html file to test our project:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
build folder. This folder and the files will be created by our build workflow. In the body section, we have a single div element
#gulpp. Finally inside the
script block we have a self invoking function. Our code is exposed with the
Gulpp global name, we will see later how this is done. We can use it inside this function to test our code, we call it as a function and pass the
#gulpp DOM element, so that our app will hopefully render into it.
http-server to serve our project folder, and visit
1 2 3
gulpfile.js file in the root of our project to define gulp tasks:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
First, we require our dependencies, next we define where our source files are and our destination folder, where our bundled project is put.
Then we define our
browserify will take our source files, and bundle them into a single file.
debug option is for generating source maps and
standalone option will export the code as a window global.
babelify will transform ES6 before bundling.
watchify will emit
update event when the files change, and
log event when the bundle is created.
We define a
rebundle function to do the actual bundling and call it on
update event so it will re-bundle on source changes. After calling
vinyl-source-stream passing a filename
gulpp.js in to the mix to make it more gulp friendly, and finally write it inside
./build folder. See this article for a more detailed explanation of how this works. Also notice that we added handlers for the
error events, so the bundle errors and logs can be logged.
dev task as the
default task for gulp. So run
gulp to test if our gulp task is working:
src/main.js file to define our application starting point:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
./view module, So add a
src/view.js file to define it.
1 2 3 4 5 6 7
To simply describe our code, we set up an MVC style project.
./view module takes the
ctrl.data and returns a data structure so we can render it.
./main module sets up the
ctrl.data and gives it to
render function, so it renders it to DOM. Remember the
Gulpp global variable inside our HTML file, we called is as a function and passed a DOM element. It is what we export from inside
src/main.js, in this case the
If we want to add an external dependency, first we install it:
Then import and use it (inside
1 2 3 4 5 6
This will update our
ctrl.data and re-render our app.
dev task if it’s not already running, and refresh the browser to see the code working. We can see the ES6 source files and set breakpoints on browser:
If we want to serve assets like stylesheets or images, we can copy these files into build folder using a gulp task:
1 2 3 4 5 6
We can hook this task to
dev task so it will run every time we run
dev task. Change our
1 2 3 4 5
esversion: 6 option we pass to
jshint so it works with ES6. All setup for development. Write some code and reload the browser to see the changes.
We need to minify code for production use.
First, add a task to minify CSS:
1 2 3 4 5 6 7
Add some CSS files in
assets folder, then run
gulp css to run this task, and see the minified output in
1 2 3 4 5 6 7 8 9 10 11 12
This task is similar to our
dev task, except we don’t have the
debug option, and we have an extra step for minifying code, using
gulp-uglify and we have to wrap that with
gulp-streamify, see why here. Finally since the output is minified, we change our output filename to
We are done with our gulp tasks. Add a script to
package.json to clean build folder and compile your project into it.
1 2 3
npm run compile and check out our bundled project inside
Next step is to include this project inside another project, which we will call our main project. Although we can publish this to npm, we can also specify this project as a local dependency and use it locally.
Add main entry point to
gulp prod task:
npm link in this project to specify it as a local module.
Next, go to our main project and install this project, when first time installing make sure you specify the local path to this project:
Now you can import and use gulpp. Next time we update something on this project, we have to run
npm run compile to re-build our project, and go to our main project and run
npm install gulpp to re-install the updated version. Enjoy!