Gulp-Example for SCSS, JS and BrowserSync

The following setup is based on “tristanisfeld” which I found on Github. See

The complete setup: DOWNLOAD

In the following setup you will have the ability to:

  • Generate one minifed CSS from SCSS files (incl. Autoprefixer)
  • Concatinate and minify multiple JS Modules into one JS file
  • use “Browsersync” so you don’t need to reload the tab everytime

Also there will be a boolean variable called “production” which activates or deactivates the “minification”, “uglyfication” and generation of sourcemaps.


  "name": "my_custom_gulp_setup",
  "author": "Kevin Pfeifer",
  "license": "WTFPL",
  "version": "2.0.0",
  "description": "Generate minified CSS and JS from source files",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  "devDependencies": {
    "browser-sync": "^2.26.7",
    "gulp-autoprefixer": "^7.0.1",
    "gulp-concat": "^2.6.1",
    "gulp-if": "^3.0.0",
    "gulp-load-plugins": "^2.0.1",
    "gulp-minify-css": "^1.2.4",
    "gulp-rename": "^1.4.0",
    "gulp-sass": "^4.0.2",
    "gulp-sourcemaps": "^2.6.5",
    "gulp-uglify-es": "^2.0.0",
    "gulp-watch": "^5.0.1",
    "node-sass": "^4.13.0"
  "dependencies": {
    "gulp": "^4.0.2"

Don’t know what the package.json does? See npm vs. yarn – Package Managers for JavaScript


const gulp = require('gulp'),
      gulpLoadPlugins = require('gulp-load-plugins'),
      plugins = gulpLoadPlugins(),
      config = require('./gulp/config');

// --------------------function to get tasks from gulp/tasks
function getTask(task) {
  return require('./gulp/tasks/' + task)(gulp, plugins, config);

// ---------------------------------------------- Gulp Tasks
gulp.task('sass',             getTask('sass'));
gulp.task('scripts',          getTask('scripts'));
gulp.task('styles',           getTask('styles'));
gulp.task('watch',            getTask('watch'));
gulp.task('browsersync',      getTask('browsersync'));

// --------------------------------------- Default Gulp Task
gulp.task('default', gulp.series('watch'));

Each Gulp setup starts with a “gulpfile.js“.

  • gulp = require(‘gulp’)
    • Load the gulp default functionality into the variable gulp
  • gulpLoadPlugins = require(‘gulp-load-plugins’)
    • Load the additional modul “gulp-load-plugins” which helps us use gulp modules later on
  • plugins = gulpLoadPlugins()
  • config = require(‘./gulp/config’)
    • Load the config file “./gulp/config” into the variable config
function getTask(task) {
  return require('./gulp/tasks/' + task)(gulp, plugins, config);

Here we define a rather generic function which helps us load tasks from the folder “./gulp/tasks/“. With this function gulp allows us to have 1 file per task and not cram all the tasks into the gulpfile.js

gulp.task('sass',             getTask('sass'));
gulp.task('scripts',          getTask('scripts'));
gulp.task('styles',           getTask('styles'));
gulp.task('watch',            getTask('watch'));
gulp.task('browsersync',      getTask('browsersync'));

Here we load all the tasks from each JS file in “./gulp/tasks/“.

Gulp Plugin Loader

Since we don’t want to require every module inside every seperate task file we can use the previously loaded module “gulp-load-plugin” to provide us all the modules in one variable.

Basically this module does the following (so we don’t have to do it):

plugins.sourcemaps = require('gulp-sourcemaps');
plugins.concat = require('gulp-concat');
plugins.uglifyEs = require('gulp-uglify-es');

This happens at the start of the gulpfile.js in the following 2 lines:

gulpLoadPlugins = require('gulp-load-plugins'),
plugins = gulpLoadPlugins()

One important thing here is the fact, that the module changes the name of the loaded modules so we can more easily use it inside our tasks.

Node Module NameFunction name

And with that we now have a variable “plugins” from which we can access all modules which are defined in the package.json.

Structure of tasks

// =========================================================
// Gulp Task: sass
// Description: transpiles sass, adds sourcemaps, prefixes
// npm install --save-dev node-sass gulp-sass gulp-sourcemaps gulp-autoprefixer gulp-load-plugins
// =========================================================

module.exports = function(gulp, plugins, config) {
  return function() {
    return gulp.src(config.sass.src)
      .pipe(plugins.if(!config.production, plugins.sourcemaps.init()))
      .pipe(plugins.sass(config.sass.opts).on('error', plugins.sass.logError))
      .pipe(plugins.if(!config.production, plugins.sourcemaps.write('.')))

Now what does each line?

module.exports = function(gulp, plugins, config) {

With the “module.exports” we define, that this function can be included in other JS files. The parameters used inside the function() are the same gulp, plugins and config variables used in our generic getTask(task) function.

return function() {

The actual functionality of the task needs to be wrapped inside a function() so gulp can use it as a “Callback” in the background and therefore allow tasks to be executed in parallel or series.

return gulp.src(config.sass.src)

Now the “usual” Gulp code is being done where the different functionalites of the tasks are defnied. You just need to be sure that a valid “Gulp stream” is being returned here.

Difference between dev and production build

The above example already has the “if production” logic implemented.

.pipe(plugins.if(!config.production, plugins.sourcemaps.init()))

The base module here is called “gulp-if“. See

This means, if we have “production” set to false in our Config-JSON gulp will also create additional Sourcemaps for the SASS.

In the “scripts” tasks we also have a similar code example:

.pipe(plugins.if(config.production, plugins.uglifyEs.default(), plugins.sourcemaps.init()))

Autoprefixer settings

With the current version of Autoprefixer it is not recommended to define the autoprefixer rules inside the JS-File and use a separate file named “.browserslistrc” instead.

You can see all available rules here:

# Browsers that we support

last 2 version
> 1%
maintained node versions
not dead


The following JSON describes how the gulp setup should behave and therefore how the different tasks should output their code.

  • opts => Options for the corresponding Gulp task
  • src => Path to the source files
  • dest => Path where the generated files should be placed

There is also inline documentation present for basically every option

module.exports = {
  production: false,
  rename: {
    min: { suffix: '.min' }
  // --------------------------------------------- browsersync
  browsersync: {
    opts: {
      proxy: "http://localhost", // The URL of the website you want to browsersync
      port: 4000, // The port, from which the browsersync tab will be opened
      serveStatic: [{
        route: '/', // The route, from which the "live" website serves CSS and JS files
        dir: './dist' // Your local path coming from the gulpfile.js where the newly local generated files are laying
    watch: [
  // ---------------------------------------------------- sass
  sass: {
    src: [
    opts: { }, // add sass options here
    dest: "./dist/assets/css"
  // ------------------------------------------------- scripts
  scripts: {
    src: [
    base: 'source/js', // common base folder of all concatenated JS files so sourcempas are working correctly
    filename: 'main.js', // filename of outputted, concatenated JS file
    dest: "./dist/assets/js" // folder where the JS files should be populated
  // -------------------------------------------------- styles
  styles: {
    src: [
    dest: './dist/assets/css'

Gulp – Automating Tasks

What is Gulp?

Gulp is a Node.js based tool to allow recurring tasks to be automated.

Here some typical examples z.B.

  • (Re-)Generate CSS when you change SASS files
  • (Re-)Generate JS when you change JS files
  • Use sourcemaps and not minified JS/CSS in a local environment but remove sourcemaps and use minified versions on live environment

Gulp 3 vs Gulp 4

Currenty (Mai 2021) ithe current verson of Gulp is 4.0.2
This version is a breaking change in comparison to the old version 3.X

What has changed since Gulp 3?

Gulp 4 changed how the “Task” system works and now allows parallel and series tasks to be defined.

E.g. in the following Task named “default” Gulp executes the tasks “sass” and “scripts” in parallel:

gulp.task('default', gulp.parallel('sass', 'scripts'));

Besides “gulp.parallel” there is also “gulp.series

gulp.task('default', gulp.series('lint', gulp.parallel('sass', 'scripts'), 'deploy'));

In this example the task “lint” will be executed first. After it is done the tasks “sass” and “scripts” are executed in parallel and after that finally the task “deploy

To execute tasks iniside another task use:

(gulp.parallel('sass', 'scripts'))();

How all this comes together in a rather nice SCSS/JS/BrowserSync Setup see the next post.