Gulp: how I put together a project for production, livereload started and error capture made

    image


    I want to share the story of my acquaintance with gulp and how I solved some problems during development. The material is aimed at those who are familiar with nodejs and are just starting to get acquainted with gulp , as well as those who are looking for a solution to a similar problem. As the name suggests, the article consists of three chapters.

    At the beginning


    My acquaintance with gulp began two months ago, when, being unemployed for some time, I began to think about getting a job in an office. After monitoring the vacancies, I decided to retrain from php developer to frontend - the benefit of experience and knowledge allowed me to do this quickly. And now, after some time, not without effort, they took me for a trial period. I vaguely imagine how I managed to do this, but, having come to work on the first day, I wrote down a notebook page on both sides with terms that I heard for the first time ... That day I realized that I was lost in the age of web developers.

    Introduction


    I will tell you about three of my problems in the process of getting to know gulp:
    1. How to build compressed (production) and uncompressed versions of a project without much effort?
    2. How to make the browser automatically reload the project when changes are made?
    3. How to catch errors in the code so that watch tasks do not crash if an error is made in the code?

    For clarity, I made a small project. You can see the link . Download with all the variations of gulpfile.js from the current article by the archive link .

    Project Structure:
    gulpfile.habrahabr.webulla.ru/
    - assets/
    - - core/
    - - - components/
    - - - - woman.js
    - - - application.js
    - web/
    - - assets/
    - - index.html
    - gulpfile.js
    - package.json
    

    Working gulpfile.js , which I will supplement with the solutions analyzed in the article (in the archive - gulpfile-0-original.js ):
    'use strict';
    // подключаем компоненты gulp
    var gulp = require('gulp');
    var browserify = require('gulp-browserify');
    // настройки путей к файлам
    var rootDir = '.';
    var sourceDir = rootDir + '/assets'; // здесь хранятся все исходники
    var destDir = rootDir + '/web/assets'; // здесь хранится все на выходе
    // блок с настройками компонентов
    // здесь я храню настройки для задач
    // удалил отсюда все кроме scripts для наглядности
    var components = {
      scripts: {
        source: sourceDir + '/core/application.js',
        dest: destDir,
        watch: sourceDir + '/core/**/*.js',
        options: {
          paths: ['./node_modules', sourceDir],
          debug: false,
          fullPaths: true
        }
      }
    };
    // задача для компиляции скриптов
    gulp.task('scripts', function () {
      gulp.src(components.scripts.source)
        .pipe(browserify(components.scripts.options))
        .pipe(gulp.dest(components.scripts.dest));
    });
    // задача для слежения за изменениями в скриптах
    gulp.task('watch:scripts', ['scripts'], function () {
      // если отслеживаемые файлы изменились, запускаем задачу компиляции скриптов
      gulp.watch(components.scripts.watch, ['scripts']);
    });
    gulp.task('default', ['scripts']);
    gulp.task('watch', ['watch:scripts']);
    

    Assembling a project from the console:
    gulp
    

    Launching a task to track changes in files:
    gulp watch
    

    Chapter 1 - Build compressed (production) and uncompressed versions of the project


    Problem


    To reduce the size of the compiled application.js, I use the gulp-uglify package . The problem is that it’s more convenient for me to search for jambs and debug code in uncompressed code (without using gulp-uglify ). In general, how to make it possible to build both the uncompressed version of the project for debugging and the compressed version for production without editing in gulpfile.js ?

    Decision


    I don’t remember where I spotted this solution, but I liked it and want to share it with you. It consists in passing a certain flag when starting gulp from the console:
    # сборка uncompressed версии
    gulp
    # сборка compressed версии
    gulp --production
    

    For such an implementation, I used:
    • yargs package to access command arguments;
    • Service gulp-uglify compression code of the project;
    • gulp-if package to run gulp-uglify only when needed.

    First, I installed all the necessary packages:
    npm install --save-dev yargs gulp-uglify gulp-if
    

    Connected packages in gulpfile.js :
    var argv = require('yargs').argv;
    var gulpif = require('gulp-if');
    var uglify = require('gulp-uglify');
    

    Added pipe to the scripts task:
    gulp.src(components.scripts.source)
        .pipe(browserify(components.scripts.options))
        .pipe(gulpif(argv.production, uglify())) // <- добавляем вот эту строчку
        .pipe(gulp.dest(components.scripts.dest));
    

    Adding this line is equivalent to the following code:
    var src = gulp.src(components.scripts.source)
        .pipe(browserify(components.scripts.options));
    // проверяем, передан ли флаг production
    if(argv.production) {
        src.pipe(uglify());
    }
    src.pipe(gulp.dest(components.scripts.dest));
    

    Explanation: in the case where argv.production == true , uglify will be applied .

    Now I build the uncompressed version of the project with the command:
    gulp
    

    A compressed version assembly :
    gulp --production
    

    The condition if (argv.production) {...} I use in other places, for example, when assembling styles for production.

    Result


    Complemented by the solution from this chapter, gulpfile.js is in the archive and is called gulpfile-1-production.js .

    Chapter 2 - Automatically reloading the project tab in the browser after changes


    Problem


    Each time, after making changes to the files and when gulp watch is running, the project is reassembled, but the page with the project does not reload. I need to switch to chrome and update the project tab. It is convenient to do so when edits are made to the files, and on another screen the browser window with the project automatically reloads with the new code.

    Decision


    That I decided to help package the problem gulp-livereload and expansion livereload for chrome. This extension is also available for other browsers: http://livereload.com/ .

    Installed the necessary package:
    npm install --save-dev gulp-livereload
    

    Connected Package:
    var livereload = require('gulp-livereload');
    

    Added a server start command to the watch: scripts task:
      // запускаем сервер
      livereload.listen();
    

    Added a server reboot command to the scripts task:
    gulp.src(components.scripts.source)
        .pipe(browserify(components.scripts.options))
        .pipe(gulpif(argv.production, uglify()))
        .pipe(gulp.dest(components.scripts.dest))
        .pipe(livereload()); // <- добавляем вот эту строчку
    

    Launched gulp watch :
    gulp watch
    

    Installed the chrome livereload extension . Let's say the web folder of my project is available at gulpfile.habrahabr.ru.local . I open it in the browser, click on the Enable LiveReload button in the bar and you 're done! Each time you save any files monitored by the watch task, the browser page automatically reloads.

    Result


    Augmented gulpfile.js in the archive - gulpfile-2-livereload.js .

    Chapter 3 - Interception of errors made in the project during development


    Problem


    If I made a mistake in the project scripts, then the working gulp watch task stopped with a compilation error. I wanted this to not happen and gulp watch continued to work.

    Decision


    For myself, I solved the problem like this: created a separate function for catching errors with logging to the console.
    /**
     * Обработчик ошибок.
     * @param e
     */
    var error = function (e) {
      console.error('Error in plugin "' + e.plugin + '"');
      console.error('   "' + e.message + '"');
      console.error('   In file "' + e.fileName + '", line "' + e.lineNumber + '".');
      console.log('--------------------------------------');
      console.log(e);
    };
    

    Added event handling to gulp scripts task:
      gulp.src(components.scripts.source)
        .pipe(browserify(components.scripts.options).on('error', error)) // <- добавил .on('error', error) на этой строчке
        .pipe(gulpif(argv.production, uglify()))
        .pipe(gulp.dest(components.scripts.dest))
        .pipe(livereload());
    

    Now, even if I make a mistake in the code, I see a notification in the console and I do not need to restart gulp watch.

    Result


    The updated gulpfile.js in the archive is gulpfile-3-error.js .

    Conclusion


    In this article, I did not want to retell the documentation or tell something innovative, but shared my experience with gulp and important findings. All documentation is available at the links indicated in the article.

    I would also like to hear the opinion of experienced and knowledgeable people both about the technical part and about the text: is the material clear, maybe somewhere it is worth saying differently or something else. I would like to learn how to convey my thoughts to people :) Thank you for your attention!

    See an example .
    Download the sample archive .

    Additions to the article


    Update as of November 6, 2015 at 12:22
    For error handling there is gulp-plumber
    agatische

    Also popular now: