Урок 01. Автоматизация сборки проекта

 
Gulp - http://gulpjs.com/ - позволяет автоматизировать процессы связанные со сборкой готовых проектов, делает работу более быстрой, продуктивной и приятной.

Gulp умеет
- при использовании препроцессора компилировать less-код, sass-код в обычный css;
- объединить множество подключаемых js-файлов в один и подключать только его;
- оптимизировать изображения
Скомпиллиривать, сжать, соединить, оптимизировать, отследить изменения - всё это делает gulp как только вы нажмёте Ctrl+C. Это очень удобно.

Gulp устанавливаем с помощью node.js
Запускаем git, заходим в наш проект, запускаем команду

$ npm install gulp-cli -g

Установить gulp в проект можно несколькими способами.

Способ 1. Автоматически инсталлировать gulp и модули в проект командой

$ npm install

Благодаря файлу package.json эта команда сработает

Давайте рассмотрим содержимое данного файла

{
  "name": "project-title", // произвольное имя без пробелов и заглавных букв
  "version": "1.0.0", // версия
  "description": "project description", // небольшое описание
  "author": "author", // автор
  "email": "author@email.com", // е-mail автора
  "url": "https://project.ru", // адрес проекта
  "devDependencies": {
    "gulp": "^3.9.1", // версия gulp
    "gulp-autoprefixer": "^3.1.0", // добавляет вендорные префиксы для разных браузеров
    "gulp-cssnano": "^2.1.1", // сжимает сss-код, минифицирует его
    "gulp-imagemin": "^2.4.0", // сжимает и оптимизирует картинки
    "gulp-less": "^3.0.5", // компилирует less-файлы
    "gulp-rigger": "^0.5.8", // отвечает за импорт - можно создавать шаблоны и импортировать их. К примеру, шапка и футер сайта не добавляется в код на всех страницах, а импортируются и тогда достаточно внести изменения, если понадобится, только в один файл
    "gulp-uglify": "^1.5.3", // минифицирует js-код
    "gulp-watch": "^4.3.5", // отслеживает изменения в файлах проекта и вносит их в проект
    "rimraf": "^2.5.2" // очищает папку
  }
}

Способ 2. Установка gulp и каждого модуля отдельно

$ npm install gulp
$ npm install gulp-watch --save-dev
$ npm install gulp-autoprefixer --save-dev
$ npm install gulp-uglify --save-dev
$ npm install gulp-rigger --save-dev
$ npm install gulp-cssnano --save-dev
$ npm install gulp-less --save-dev
$ npm install gulp-imagemin --save-dev
$ npm install rimraf --save-dev

Способ 3. Установить gulp и все модули одной командой

$ npm install gulp gulp-watch gulp-autoprefixer gulp-uglify gulp-rigger gulp-cssnano gulp-less rimraf gulp-imagemin --save-dev 

В результате выполнения любого из этих способов в проекте появляется папка node_modules и в ней все необходимые модули. Их мы не трогаем больше

Дополнено.
Команда npm install gulp у меня выдавала ошибку  npm WARN deprecated minimatch@2.0.10: Please update to minimatch 3.0.2
Её решила изменив команду на npm install -g minimatch@3.0.2
Решение взяла здесь: https://github.com/npm/npm/issues/13323

Тем не менее, ошибка после установки осталась

npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@^1.0.0 (node_modules\chokidar\node_modules\fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@1.1.1: wanted {"os":"darwin","arch":"any"} (current: {"os":"win32","arch":"ia32"})
npm WARN project-title@1.0.0 No repository field.
npm WARN project-title@1.0.0 No license field.


И вместо аккуратной папки node_modules с установленными модулями как в видео на 07:20, у меня в этой папке  6 622 файлов и 1 356 папок.

Открываем файл gulpfile.js
В нём перечисляем какие модули подключаем и создаём gulp.task - задачи, которые эти модули будут выполнять

Создаём переменные с названиями и при помощи команды require() подключаем модули

var gulp = require('gulp'),
    watch = require('gulp-watch'),
    prefixer = require('gulp-autoprefixer'),
    uglify = require('gulp-uglify'),
    rigger = require('gulp-rigger'),
    cssnano = require('gulp-cssnano'),
    less = require('gulp-less'),
    rimraf = require('rimraf'),
    imagemin = require('gulp-imagemin');

Создаём переменную path

var path = {
    build: { // Куда складывать готовые файлы после сборки
        html: 'build/',
        js: 'build/js/',
        css: 'build/css/',
        img: 'build/i/',
        fonts: 'build/css/fonts/'
    },
    src: { // Откуда брать исходники
        html: 'src/*.html',
        js: 'src/js/*.js',
        css: 'src/css/style.less',
        img: 'src/i/**/*.*',
        fonts: 'src/css/fonts/**/*.*'
    },
    watch: { // За изменениями каких файлов мы хотим наблюдать
        html: 'src/**/*.html',
        js: 'src/js/**/*.js',
        css: 'src/css/**/*.less',
        img: 'src/i/**/*.*',
        fonts: 'src/css/fonts/**/*.*'
    },
    clean: './build'
};

build: указываем пути, где будут сохраняться файлы после сборки - папка build, файлы build/js/, build/css/, build/i/, build/css/fonts/

src: сейчас все файлы проекта хранятся в папке src и именно там мы с ними работаем.Указываем папки и подпапки папки src, анпример, путь 'src/i/**/*.*' это папка "i" со всеми вложенными подпапками  и картинками с любыми расширениями

watch: указываем за изменением каких файлов нужно следить, в каких папках они могут находиться и какие расширения могут иметь.

clean: './build' это очистка проекта, если там много лишнего ненужного оказалось, папку build удаляем, а затем создаём заново.

Таски - задания - объясняют gulp что он должен делать. Их можно вызывать как по одному, так и все вместе

gulp.task('html:build', function () {
    gulp.src(path.src.html) // Выберем файлы по нужному пути
        .pipe(rigger()) // Прогоним через rigger
        .pipe(gulp.dest(path.build.html)); // Переместим их в папку build
});


gulp.task('js:build', function () {
    gulp.src(path.src.js) // Выберем файлы по нужному пути
        .pipe(rigger()) // Прогоним через rigger
        .pipe(uglify()) // Сожмем js
        .pipe(gulp.dest(path.build.js)); // Переместим готовый файл в build
});


gulp.task('css:build', function () {
    gulp.src(path.src.css) // Выберем наш style.less
        .pipe(less()) // Скомпилируем
        .pipe(prefixer()) // Добавим вендорные префиксы
        .pipe(cssnano({zindex: false})) // Сожмем
        .pipe(gulp.dest(path.build.css)); // Переместим в build
});


gulp.task('image:build', function () {
    gulp.src(path.src.img) // Выберем наши картинки
        .pipe(imagemin({ // Сожмем их
            progressive: true,
            svgoPlugins: [{removeViewBox: false}],
            interlaced: true
        }))
        .pipe(gulp.dest(path.build.img)); // Переместим в build
});


gulp.task('fonts:build', function() {
    gulp.src(path.src.fonts)
        .pipe(gulp.dest(path.build.fonts)) // Переместим шрифты в build
});


gulp.task('clean', function (cb) {
    rimraf(path.clean, cb);
});


gulp.task('build', [
    'html:build',
    'js:build',
    'css:build',
    'fonts:build',
    'image:build'
]);


gulp.task('watch', function() {
    watch([path.watch.html], function(event, cb) {
        gulp.start('html:build');
    });
    watch([path.watch.css], function(event, cb) {
        gulp.start('css:build');
    });
    watch([path.watch.js], function(event, cb) {
        gulp.start('js:build');
    });
    watch([path.watch.img], function(event, cb) {
        gulp.start('image:build');
    });
    watch([path.watch.fonts], function(event, cb) {
        gulp.start('fonts:build');
    });
});

Запускаются команды через git
Соберёт все файлы вместе команда

$ gulp build

// с 20:00 про импорт файлов, использование бутстрапа, less и т.д