Setting up Gulp, Bower, Bootstrap Sass, & FontAwesome

Let’s face it. Managing front end dependencies is still a headache. As developers, we have a plethora of options for building dependencies. Some of the tools off the top of my head are Grunt, Gulp, Broccoli, Component, NPM, and probably 5 more have been released since I started writing this post. In this tutorial, I am going to focus on Gulp but I’m sure it can be modified to work with any of the others.

Lately I’ve started a few side projects and wanted to quickly build out a MVP, minimal viable product, and Bootstrap paired with FontAwesome is a great way of doing this. The problem comes in with trying to automate the setup and have a nice clean package. Sure you can use a CDN but that limits your ability to modify variables and makes working offline difficult. By setting up Gulp we have all the sources available to modify and extend as we need.

Tonight after integrating these for the fourth time I thought it would be something good to share with the goal of benefiting others. From this point forward I will assume you have both bower and npm installed. If you do not then just do a little searching for installation instructions for your operating system. Neither should be too difficult.

Bower

The first step is to setup Bower. Create a new local directory and “cd” into it. Next run bower init and following the instructions. I don’t believe any of the answers to the questions matter as this will only be used locally.

After that finishes install our required bower packages:

bower install bootstrap-sass-official --save  
bower install fontawesome --save

By default, this will put them in the bower_components directory which can be changed if you prefer. I will leave it as default.

NPM

Now we need to setup our gulp dependencies, which pull from NPM. Create a new package.json file and just add an empty object, {} and save it.

Head back to the terminal and install our NPM dependencies:

npm install gulp gulp-ruby-sass gulp-notify gulp-bower --save-dev

This will install all the needed dependencies in a node_modules folder and also automatically update our package.json file with these dependencies.

Here is an example package.json showing the versions of dependencies I’m using:

{
  "devDependencies": {
    "gulp": "^3.8.11",
    "gulp-bower": "0.0.10",
    "gulp-notify": "^2.2.0",
    "gulp-ruby-sass": "^0.7.1"
  }
}

PLEASE NOTE: – gulp-ruby-sass is going through some changes. To follow along be sure and use the “^0.7.1” version as I did.

Gulp

Finally, we need to setup the gulpfile.js. Create this file and we’ll step through all the settings.

If you’ve looked at gulp files before then you might know they all start by including the dependencies by using the node require function. Here is the start:

var gulp = require('gulp'),
    
    sass = require('gulp-ruby-sass')

    notify = require("gulp-notify")

    bower = require('gulp-bower');

These are everything we installed in the NPM step above and at this point just included and not actually doing anything.

Next up, I create a config object to hold various settings:

var config = {

    sassPath: './resources/sass',

    bowerDir: './bower_components'

}

I find by doing this it keeps the rest of the file simpler. The sassPath is the folder where I store the sass files I create. I’m using Laravel 5.0 and as you can see I just put them in resources/sass. These will end up being parsed and put in a ./public directory. Next is the bowerDir which is just the path to the bower_components.

Next let’s setup up our first gulp task for running bower.

gulp.task('bower', function() {

    return bower()

        .pipe(gulp.dest(config.bowerDir))

});

This task basically runs bower install but by including in the gulpfile other contributors only have to run gulp bower and have them all setup and ready.

FontAwesome

Now that we have FontAwesome in bower_components we need to move the fonts out and place them into the ./public directory. Here is a simple move task to handle this:

gulp.task('icons', function() {

    return gulp.src(config.bowerDir + '/fontawesome/fonts/**.*')

        .pipe(gulp.dest('./public/fonts'));

});

All this is doing is taking whatever is in bower_components/fontawesome/fonts/ directory and moving those to ./public/fonts.

Bootstrap Sass

The next piece to the puzzle is setting up Sass and linking bootstrap and fontawesome into our path so our sass files can access them. Here is the task:

gulp.task('css', function() {

    return gulp.src(config.sassPath + '/style.scss')

        .pipe(sass({

            style: 'compressed',

            loadPath: [

                './resources/sass',

                config.bowerDir + '/bootstrap-sass-official/assets/stylesheets',

                config.bowerDir + '/fontawesome/scss',

            ]

        })

            .on("error", notify.onError(function (error) {

                return "Error: " + error.message;

            })))


        .pipe(gulp.dest('./public/css'));

});

This task is a little complex but shouldn’t be to0 difficult to follow. The important parts of this task is the loadPath which tells gulp-ruby-sass all the locations it should look for files. The .on(“error” uses the notify plugin to alert something failed in the build.

With this setup our main style.scss can import bootstrap and fontawesome easily. Here is an example:

@import url(http://fonts.googleapis.com/css?family=Raleway:400,700,300);
$font-family-base: 'Raleway', sans-serif;
// Import bootstrap and fontawesome
@import "bootstrap";
@import "font-awesome";
//...

I imported a new font and set it as bootstraps $font-family-base. When bootstrap is later pulled in it will see the variable is defined and use our setting. You can also do this for any bootstrap variables.

Watch and Default Task

Finally, we are almost finished. Now we need a watch task and a default task.

// Rerun the task when a file changes

gulp.task('watch', function() {

    gulp.watch(config.sassPath + '/**/*.scss', ['css']);

});



gulp.task('default', ['bower', 'icons', 'css']);

The first is the watch task which just listens for changes in the path and then runs the “css” task. Finally, we have a default task which when called runs bower, icons, and the css task. This is useful so contributors can pull down your code, cd into it, run npm install, and finally gulp. Everything should be easily shared and used.

If you would like to see the final files used for this tutorial take a look at this demo repo. Also, if you have any questions or if anything isn’t clear let me know in the comments.

Setting up Gulp, Bower, Bootstrap Sass, & FontAwesome

0 thoughts on “Setting up Gulp, Bower, Bootstrap Sass, & FontAwesome

  1. Hi Eric, I’m getting the following error when I run gulp: gulp-ruby-sass: stderr: ‘sass’ is not recognized as an internal or external command, operable program or batch file.

    I needed to install gulp with the -g flag from npm, I tried that with gulp-ruby-sass too but that didn’t fix this error. Any ideas?

    1. You may need to install sass from the Ruby gem first:

      `gem install sass`

      Then I believe it should work. An alternative would be to use gulp-sass but that changes the gulp css task I included in the post.

  2. Raphael Essoo-Snowdon says:

    Fantastic writeup! Didn’t realise `gulp-ruby-sass` existed, let alone supported loadPath.

    One question I had, what is the Bower task for. Is it purely for contributors that want the bower_components to be downloaded when they run gulp for the first time?

  3. Hey Eric!

    Great post! Really enjoy seeing how other developers setup their build systems. Always end up learning a few new things! Really like your config idea for file paths. That definitely will help keep code a little neater!

    If you’re curious, check out this post over at Viget (http://viget.com/extend/gulp-browserify-starter-faq) regarding using Gulp & Browserify. It was also insightful to me and cool to learn how to split each task into little task files to help modularize it all a bit more 🙂

    Thanks for posting!

  4. Mike B says:

    Hi Eric,

    I’m trying to troubleshoot why I can’t seem to compile bootstrap by using:

    gulp.task(‘css’, function() {
    return gulp.src(“app/assets/bootstrap-sass-official/assets/stylesheets/_bootstrap.scss”)
    .pipe(sass({
    style: ‘compressed’
    })).on(‘error’, util.log)
    .pipe(gulp.dest(‘public/test’));
    });

    and came across your post while googling around. Like you, I used bower to add the bootstrap-sass assets. But I don’t get any output when running gulp sass. If I point gulp.src to one of my own scss files, it works just fine. Any ideas?

    1. Mike B says:

      OK, so I figured it out. Turns out you can’t reference files with leading underscores in gulp, so the workaround is to create a custom scss file, import the bootstrap file (sans underscore, even though its in the file name), run gulp against your custom file, and everything is running again. whew.

      1. Guest says:

        Thanks. Where I can add my custom CSS files? I have compiled the all SASS from bootstrap into public/css/style.css but I want add more files inside style.css..I mean that I want compile with gulp SASS another css/sass out of bower_components folder

          1. Guest says:

            Yes Eric. Sorry about this noob question. I figured it out now. Thanks for your time writing this tutorial and btw great post!

  5. Chris says:

    When I create my ‘style.scss’ file in the ‘./resources/sass’ directory I get a sass compile error. It can’t locate the ‘bootstrap/mixins’ partial. What have I done wrong?

  6. Tina says:

    Thanks for this great post
    I got an error when running gulp:
    TypeError: Arguments to path.join must be strings

    It semes gulp-ruby-sass syntax has updated:
    http://stackoverflow.com/questions/28140012/gulp-typeerror-arguments-to-path-join-must-be-strings

    https://github.com/sindresorhus/gulp-ruby-sass/tree/rw/1.0#usage

    “gulp-ruby-sass is a gulp source adapter. Use it instead of gulp.src.”
    var gulp = require(‘gulp’);
    var sass = require(‘gulp-ruby-sass’);

    gulp.task(‘sass’, function() {
    return sass(‘source/’)
    .on(‘error’, function (err) {
    console.error(‘Error!’, err.message);
    })
    .pipe(gulp.dest(‘result’));
    });

    So I change to gulp-sass https://github.com/dlmanning/gulp-sass

    var gulp = require(‘gulp’);
    var sass = require(‘gulp-sass’);

    gulp.task(‘sass’, function () {
    gulp.src(‘./scss/*.scss’)
    .pipe(sass())
    .pipe(gulp.dest(‘./css’));
    });

  7. FYI not sure when the option changed but it is no longer ‘loadPath’ to include other paths, it is ‘includePaths’. Took me forever to debug that, hope this helps the next reader!

      1. Hey, thanks a lot for this tutorial! I think you forgot to update the post! I’ve been scratching my head to why it wouldn’t work, and the problem was loadPath.

  8. guest says:

    Eric,
    Can you please show your entire project structure, not just the content of the gulpfile and bower.json files? I’ve looked at the gist, and it only has 3 files.

    1. ericbarnes says:

      I think you are looking for something different than this tutorial as it focuses only on the css aspect. Are you using a server side language? Or a template engine?

  9. Hayden Hancock says:

    Good article! I am doing something similar but I am not using Bower to manage/install Bootstrap. Instead, I downloaded Bootstrap Sass directly from the website and added the bootstrap folder to my src/scss folder.

    I am having issues with the mixins. When I create a new file called _layout.scss and include the following code:

    section {
    @include make-row();

    article {
    @include make-lg-column(2);
    }
    }

    Unfortunately, this doesn’t seem to be working as expected. The output is:

    section {
    margin-left: -15px;
    margin-right: -15px; }
    section:before, section:after {
    content: ” “;
    display: table; }
    section:after {
    clear: both; }
    section article {
    position: relative;
    min-height: 1px;
    padding-left: 15px;
    padding-right: 15px; }
    @media (min-width: 1200px) {
    section article {
    float: left;
    width: 16.66667%; } }

    Has anyone else experienced issues with the sass mixins?

  10. Maciej P says:

    Hi,

    I was about to start setting up my env. the way you have described but then I’ve read about Yeoman – is there a generator creating the same configuration as you have described?

  11. Hello Eric,

    great post. Inspired by you I’ve prepared the separate repo (https://github.com/pnowy/bimper) with Gulp, Bower, Boostrap Less, Browser-Sync and asset-builder. I’ve also introduce the PHP templating for easier prototyping. I’ve build it on the top of Sage WordPress theme and your Github repo (http://oneslashtoofar.com/2015/04/26/setting-up-gulp-bower-bootstrap-less-browser-sync-with-php-templating/).

    I think it would be good to think about some Yeoman generator for that kind of stuff.

    Best,
    Przemyslaw

  12. Bruno says:

    Just a tip for begignners: You can type npm init and hit enter and follow the instructions instead of create the package.json by yourself.

  13. Hemant says:

    I was curious what path is required for the following lines in style.scss. :

    @import “bootstrap”;
    @import “font-awesome”;

    I’m finding I get an error whenever I add these lines.

    Error: /Users/hemant/sites/angular-gulp-kss/src/app/styles/_base:4: error: file to import not found or unreadable: “bootstrap”

  14. Hi, great article, but I have a problem with css on run gulp: “TypeError: glob pattern string required”

    I have tried to install npm glob, but doesn’t work although.

    Could you help me?

    1. Key says:

      Ralph: As noted in the article:
      PLEASE NOTE: – gulp-ruby-sass is going through some changes. To follow along be sure and use the “^0.7.1” version as I did.

  15. grex22 says:

    What if you wanted to actually use Bootstrap’s Javascript plugins? How would you compile those to the public directory? Anyone sorted this out?

  16. Gaz says:

    I assume you are missing a few lines of code in the “Bootstrap Sass” code as you mention “auto prefix” in the text below it but don’t have any code for this? :/

Leave a Reply