# Gulp
- Gulp is a JavaScript task runner toolkit that allows to automate painful and/or time-consuming tasks during development
- On this page, we will explain the most important concepts of Gulp by examining the contents of the file gulpfile.js
REMARK
You don't have to be able to setup a Gulp-based workflow yourself, but you should understand what is going on!
READING TIP
# gulpfile.js
- All code related to the Gulp workflow of a project is written in gulpfile.js
- This file contains a list of the included Node packages and the tasks related to the project
# Included packages
- At the top of gulpfile.js, you will find some import ... from ...statements that include/import the Node packages to be used further on in this file- These same packages should be installed using npm installand, as such, they should be included in the"devDependencies"section of the project's package.json file
 
- These same packages should be installed using 
- Example: gulpfile.js (and package_json) of sass-bs-example (opens new window)
REMARKS
- Don't be confused by the occurence of gulp (in gulpfile.js, line 1 and package.json, line 30). This is a local package that we need, on top of gulp-cli (which we installed globally earlier on).
- Package names containing the prefix gulp-are so-called Gulp plugins that transform files (see below under Tasks)- For example, gulp-sass is a plugin that uses the Dart Sass package/compiler we installed earlier in the course
- For other operations, (non-plugin) Node packages can/should be used
 
# Tasks
- The second part of gulpfile.js contains the tasks
- Example: gulpfile.js of sass-bs-example (opens new window)
// Copy Bootstrap JS-files
gulp.task('copy-js', () => {
    return gulp.src([
        'node_modules/bootstrap/dist/js/bootstrap.bundle.min.js',
    ])
        .pipe(newer('./dist/js'))
        .pipe(notify({message: 'Copy JS files'}))
        .pipe(gulp.dest('./dist/js'));
});
// Compile sass into CSS (/dist/css/)
gulp.task('sass', () => {
    return gulp.src('./scss/**/*.scss')
        .pipe(
            plumber({
                errorHandler: notify.onError({
                    title: 'SASS compile error!',
                    message: '<%= error.message %>',
                }),
            })
        )
        .pipe(sourcemaps.init())
        // outputStyle: expanded or compressed
        .pipe(sass({outputStyle: 'expanded'}).on('error', sass.logError))
        .pipe(prefix('last 2 versions'))
        .pipe(gcmqp())
        .pipe(sourcemaps.write())
        .pipe(gulp.dest('./dist/css'));
});
// Live-reload the browser
gulp.task('browser-sync', () => {
    browserSync.init({
        server: {
            baseDir: './dist',
            directory: true,
        },
        startPath: '/index.html',
        port: 6600,
        ui: {
            port: 6602
        }
    });
    gulp.watch('./scss/**/*.scss', gulp.series('sass'));
    gulp.watch('./dist/**/*.{html,css,js}').on('change', browserSync.reload);
});
gulp.task('default', gulp.series('copy-js', 'sass', 'browser-sync'));
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
40
41
42
43
44
45
46
47
48
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
40
41
42
43
44
45
46
47
48
- In this task, the Bootstrap JS-file is copied from the node_modules folder to the folder dist/js
- You start with gulp.src()to read the Bootstrap JS file (lines 3-5), after which additional operations/transforms can be applied using.pipe():- newer()only lets pass files that are newer than the ones in dist/js (line 6)
- notify()prints the message 'Copy JS files' in the terminal window (line 7)
- gulp.dest()writes/copies the files to the folder dist/js (line 8)
 
# Task 'sass'
// Compile sass into CSS (/dist/css/)
gulp.task('sass', () => {
    return gulp.src('./scss/**/*.scss')
        .pipe(
        plumber({
            errorHandler: notify.onError({
                title: 'SASS compile error!',
                message: '<%= error.message %>',
            }),
        })
        )
        .pipe(sourcemaps.init())
        // outputStyle: expanded or compressed
        .pipe(sass({outputStyle: 'expanded'}).on('error', sass.logError))
        .pipe(prefix('last 2 versions'))
        .pipe(gcmqp())
        .pipe(sourcemaps.write())
        .pipe(gulp.dest('./dist/css'));
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
- This task takes care of the Sass compilation
- Again, it starts with gulp.src()to read all SCSS files (line 4), after which the following operations/transforms are "piped":- sass()takes care of the compilation, and allows you to choose the output style. Errors are shown in the console. (line 14)
- compilation errors are also shown in a pop-up using plumber()(lines 5-10)
- the resulting CSS is automatically prefixed by prefix(), taking into account that the result should be rendered correctly on the last 2 versions of all major browsers (line 15)
- all similar media queries are grouped/sorted bypostcss()andgcmqp()(line 16)
- sourcemaps are included (lines 12 and 17)
- gulp.dest()writes/copies the resulting CSS files to the folder dist/css (line 18)
 
# Task 'browser-sync'
// Live-reload the browser
gulp.task('browser-sync', () => {
    browserSync.init({
        server: {
            baseDir: './dist',
            directory: true,
        },
        startPath: '/index.html',
        port: 6600,
        ui: {
            port: 6602
        }
    });
    gulp.watch('./scss/**/*.scss', gulp.series('sass'));
    gulp.watch('./dist/**/*.{html,css,js}').on('change', browserSync.reload);
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
- In this task, browser-sync is set up to serve the dist folder (starting at index.html) on port 6600(lines 3-13)
- The Sass code is watched, and when a change is observed, the task sassis called (line 14)
- When there is a change in HTML, CSS or JS code in the dist folder, the browser content is reloaded (line 15)
# Task 'default'
gulp.task('default', gulp.series('copy-js', 'sass', 'browser-sync'));
1
- This defaulttask start the previous tasks in series, i.e., sequentially- First, the task copy-jscopies the needed JS file (if that hasn't been done before)
- Next, the task sasscompiles your Sass code
- Finally, the task browser-synclaunches your browser and "watches" for changes in your Sass code (after which the tasksassis relaunched) or HTML/CSS/JS files (after which the browser is reloaded)
 
- First, the task 
 
 