Данная статья является попыткой осмыслить (в первую очередь для себя, конечно) такой вопрос, как создание git-репозитория на GitHub, клонирование этого репозитория на локальный компьютер, внесение изменений в клонированный репозиторий, отправка изменений обратно на GitHub.

Вот такие получаются шаги, которые нужно осветить. Profit у всех этих сложностей, описанных мною выше, один - но большой! Заключается он в том, что проект, над которым вы работаете (даже в гордом одиночестве) находится на удаленном сервере, к которому можно подключиться из любого места и с любой машины. Так как он находиться на remote server, то с ним ничего не случиться, даже если ваша машина упадет\утонет\разобьется.

В статье большая часть времени будет посвящена автоматизации процесса авторизации на сервисе GitHub с помощью такой вещи, как ssh-ключи. Такие ключи предназначены как раз для возможности авторизации пользователя на каком-либо сервисе, без необходимости каждый раз вводить логин\пароль. Естественно, на стороне сервиса должна быть настроена такая возможность - на GitHub она настроена и даже является почти обязательным условием настройки аккаунта.

Все действия, описанные в этой статье, будут производиться под операционной системой Linux Mint 17 Cinnamon, в консоли. Поэтому пользователи Mac OS X найдут для себя почти все идентичным. Система Windows остается в стороне.

Создание SSH-ключей под Linux

Первоначально необходимо создать (если их еще нет) ssh-ключи, которые будем использоваться для авторизации на GitHub. В системе Linux такие ключи расположены в домашней директории пользователя и выглядят примерно так:

$ ls ~/.ssh
  id_rsa id_rsa.pub known_hosts

Один из этих ключей id_rsa - это приватный ключ, который должен храниться только у пользователя. Другой ключ id_rsa.pub - это публичный ключ, который предоставляется всем и который я отправлю на GitHub. Представленные выше имена ключей являются создаваемыми по умолчанию, но можно указать и свои собственные.

Если показанная выше команда “скажет” вам, что директории .ssh не существует, то это означает, что у вас с системе установлен пакет SSH, отвечающий за создание и обработку ssh-ключей.

Установка пакета SSH

Под Linux Mint его нужно установить командой:

$ sudo apt-get install ssh

Создание пары ssh-ключей

Теперь можно приступать к созданию пары ssh-ключей. Выполняется это командой:

$ ssh-keygen -t rsa -C "g***e@gmail.com"

Чтобы было немного понятно, что это я сделал в данной команде, немного расшифрую ее. Утилита ssh-keygen входит в комплект пакета ssh и предназначена для одной цели - создания ssh-ключей. Часть команды - -t rsa - указывает, что необходимо создать ssh-ключи типа rsa.

Обязательный параметр "g***e@gmail.com" - электронный адрес, к которому “привязывается” создаваемый ssh-ключ; данный email будет также использоваться мною для регистрации на GitHub.

Как только будет введена представленная выше команда, утилита ssh-keygen запросит имя файла и местоположение для создаваемых ssh-ключей. Можно ничего не вводить, а просто нажать Enter. В этом случае программулька создаст и положит их по пути по умолчанию (который показан ею в скобочках):

$ ssh-keygen -t rsa -C "g***e@gmail.com"
  Generating public/private rsa key pair.
  Enter file in which to save the key (/home/aaron/.ssh/id_rsa):

Утилита задаст еще один вопрос, который крайне не рекомендуется игнорировать:

$ ssh-keygen -t rsa -C "g***e@gmail.com"
  Generating public/private rsa key pair.
  Enter file in which to save the key (/home/aaron/.ssh/id_rsa):
  Enter passphrase (empty for no passphrase):

Здесь passphrase - это пароль к создаваемым ssh-ключам. Каждый раз, когда придется использовать эти ключи, нужно вводить данный пароль. Это обезопасит их в случае кражи. В качестве пароля можно использовать любую текстовую строку.

После успешного ввода passphrase ssh-ключи будут созданы:

$ ssh-keygen -t rsa -C "g***e@gmail.com"
  Generating public/private rsa key pair.
  Enter file in which to save the key (/home/aaron/.ssh/id_rsa):
  Enter passphrase (empty for no passphrase):
  Enter same passphrase again:
  Your identification has been saved in /home/aaron/.ssh/id_rsa.
  Your public key has been saved in /home/aaron/.ssh/id_rsa.pub.

В состав пакета ssh входит утилита ssh-agent, задача которой в управлении созданными ssh-ключами. Передадим ей в пользование только созданные мною ssh-ключи:

$ eval "$(ssh-agent -s)"
  Agent pid 17461
  $ ssh-add ~/.ssh/id_rsa
  Enter passphrase for /home/aaron/.ssh/id_rsa:
  Identity added: /home/aaron/.ssh/id_rsa (/home/aaron/.ssh/id_rsa)

Можно посмотреть, что утилита shh-add “подхватила” и распознала предоставленные ею ssh-ключи:

$ ssh-add -l
  2048 e4:4d:fe:73:cb:b9:bb:ee:26:32:6b:f5:f1:6a:db:38 /home/aaron/.ssh/id_rsa (RSA)

Под операционную систему Linux имеется консольная утилита xclip, которая умеет получать содержимое любого файла и отправлять это содержимое в буфер обмена, и все это в консоли. По умолчанию такой утилиты нет в системе (в том числе и у меня), поэтому первоначально установлю ее:

$ sudo apt-get install xclip

… а затем передам ей на вход содержимое публичного ключа id_rsa.pub, который буду применять на сервисе GitHub:

$ xclip -sel clip < ~/.ssh/id_rsa.pub

Если вам, уважаемый читатель, такой путь покажется слишком сложным, то можно открыть файл id_rsa.pub в любом редакторе кода и скопировать его содержимое в буфер обмена.

Добавление ssh-ключа на GitHub

Переходим на сервис GitHub и создаем на нем новую учетную запись. Описывать процесс создания такой записи на GitHub не буду, так как там все просто. Более интересный момент - это добавление ssh-ключа в профиль пользователя GitHub.

Для этого нажимаю на значок шестеренки в правом верхнем углу окна браузера - настройки профиля пользователя. В открывшемся окне (в его левой части) находим строку SSH key и нажимаем ее:

SSH ключи на GitHub

Откроется окно для добавления новых ssh-ключей в учетную запись пользователя на GitHub. Здесь все элементарно просто - нажимаем кнопку Add SSH key. В поле Title вводим название (произвольное) для импортируемого ssh-ключа.

В поле Key просто нажимаем Ctrl+V - содержимое буфера обмена (которое я получил ранее с помощью утилиты xclip) вставиться в это поле:

Добавление ssh-ключа на GitHub

Жму на зеленую кнопку Add key внизу окна. Ключ добавлен на GitHub и появиться в списке SSH-ключей:

Добавленный на GitHub ssh-ключ

Проверка SSH-соединения с GitHub

В предыдущих шагах мною были созданы пара ssh-ключей, а также учетная запись на GitHub. В эту учетную запись был импортирован публичный ssh-ключ. Теперь неплохо было бы проверить, что все шаги пройдены мною успешно и ssh-связь с сервисом GitHub устанавливается. Проще сказать - что сервис GitHub авторизует меня у себя с помощью ssh-ключей.

Для этой цели ввожу команду:

$ ssh -T git@github.com
  The authenticity of host 'github.com (192.30.252.131)' can't be established.
  RSA key fingerprint is 16:27:ac:a5:76:28:2d:36:63:1b:56:4d:eb:df:a6:48.
  Are you sure you want to continue connecting (yes/no)? yes

На ошибку в строке The authenticity of host 'github.com (192.30.252.131)' can't be established. не стоит обращать внимание. В запросе командной строки печатаем yes и получаем:

Warning: Permanently added 'github.com,192.30.252.131' (RSA) to the list of known hosts.
Hi gearmobile! You've successfully authenticated, but GitHub does not provide shell access.

Отлично! GitHub “узнал” меня и поприветствовал в строке Hi gearmobile! You've successfully authenticated, but GitHub does not provide shell access.. Это говорит о том, что ssh-соединение моей машины с GitHub установлено успешно и GitHub авторизует меня.

Однако, при настройке ssh-соединения возможны и ошибки. В этом случае может помочь статья - Error: Permission denied (publickey).

Создание нового репозитория на GitHub

Создаем новый репозиторий на GitHub. Ввожу новое уникальное имя для репозитория, краткое его описание и включаю галочку “Initialize this repository with a README”:

Создание нового репозитория на GitHub

Отлично! На GitHub я только что создал новый репозиторий arbeit. Теперь можно скопировать (склонировать) его на свою локальную машину командами:

$ mkdir arbeit
$ git clone git@github.com:gearmobile/arbeit.git
  Cloning into 'arbeit'...
  Warning: Permanently added the RSA host key for IP address '192.30.252.130' to the list of known hosts.
  remote: Counting objects: 3, done.
  remote: Compressing objects: 100% (2/2), done.
  remote: Total 3 (delta 0), reused 0 (delta 0)
  Receiving objects: 100% (3/3), done.
  Checking connectivity... done

Переходим в локальную копию репозитория arbeit. Вношу изменения, а затем последовательно:

$ git add .
$ git commit -m 'Added changes'
$ git push

Команда git commit -m 'Added changes' фиксирует изменения в локальном репозитории. Команда git push отправляет внесенные и зафиксированные изменения в локальном репозитории на удаленный репозиторий.

Вот, таким образом я наладил Git-работу своей машины с GitHub.


В системе Git можно настроить возможность автоматического игнорирования файлов.

То есть, можно указать Git, что файлы определенного типа не нужно отслеживать. Выполняется такая настройка с помощью специального файла .gitignore. Подобная возможность отключения отслеживания файлов в системе Git может понадобиться в случае, когда автоматически генерируются служебные файлы.

К примеру, если развертывать в проекте Compass, то будет создан каталог .sass, в который данный фреймворк помещает свой кэш, генерируемый автоматически при каждом изменении любого из файлов проекта.

Давайте на практике разберемся, каким образом можно настроить игнорирование файлов в Git с помощью .gitignore.

Создание нового проекта

Создаю новый проект с именем git_ignore, в котором помещаю несколько файлов разного типа:

$ mkdir git_ignore
$ cd git_ignore/
$ touch index.html style.css

Инициализирую репозиторий Git в директории .git_ignore, индексирую созданные файлы и фиксирую их:

$ git init
Initialized empty Git repository in /home/aaron/Projects/git_ignore/.git/
$ git add .
$ git commit -m 'First Commit'

Вывод команды git status показывает, что все чисто:

$ git status
On branch master
nothing to commit, working directory clean

Настройка игнорирования в .gitignore

Для настройки игнорирования определенных типов файлов в системе Git необходимо первоначально создать файл .gitignore:

$ touch .gitignore

Откроем созданный файл .gitignore в любом редакторе:

$ nano -w .gitignore

… и пропишем в нем следующие строки:

*.txt
*.md

Тем самым мы говорим Git, что нужно игнорировать все файлы с расширением .txt и .md внутри директории git_ignore. То есть, система контроля не будет отслеживать изменения во всех файлах этих типов.

Проиндексируем и зафиксируем изменения (создание файла настроек .gitignore), а затем проверим данный факт. Для этого в рабочей директории git_ignore создаю еще несколько типов файлов:

$ touch main.css readme.txt humans.md

Затем выполняю индексацию всех файлов, которые были добавлены или изменены в рабочем каталоге:

$ git add .

И смотрю, что мне показывает команда git status:

$ git status
  On branch master
  Changes to be committed:
    (use "git reset HEAD <file>..." to unstage)

    new file:   main.css

Система Git увидела только новый файл main.css. Два других файла - readme.txt и humans.md - проигнорированы системой. Отлично! Зафиксирую изменения.

Можно создать еще пару файлов в разных директориях и посмотреть на вывод команды git status в консоли:

Результат настройки файла .gitignore

Усложнить задачу игнорирования в .gitignore

Можно усложнить задачу игнорирования в Git, добавив в файл .gitignore директорию, содержимое которой также должно игнорироваться. Пускай это будет обычная директория ignore и скрытая директория .ignore (с точкой перед именем):

Добавлю в файл .gitignore пару строк таким образом:

$ cat .gitignore
*.txt
*.md
ignore/
.ignore/

Проиндексирую изменения, а затем выполню операции по созданию директорий и файлов внутри них:

$ mkdir ignore
$ mkdir .ignore
$ touch ignore/reset.css
$ touch .ignore/normilize.css

Вновь ввожу команду просмотра состояния репозитория Git:

$ git status
  On branch master
  nothing to commit, working directory clean

Все сработало - Git не захотел видеть директории ignore, .ignore, а также их содержимое. Отлично!

Шаблоны в файле .gitignore

Для файла .gitignore доступны шаблоны, с помощью которых можно задать маски для выборки необходимых типой файлов. Однако, обширная тема шаблонов выходит за рамки данной статьи. При желании можно почитать по теме шаблонов в книге “Pro Git - профессиональный контроль версий”.


Сегодня рассмотрим еще один очень нужный и полезный плагин для web-разработчика. Это плагин gulp-livereload под Gulp, который должен иметь каждый веб-разработчик в своей копилке.

Суть плагина gulp-livereload в автоматизации обновления страниц в окне браузера. Это тоже самое, что и связка - плагин LiveReload под Sublime Text + плагин LiveReload под браузер. Но в данном случае получается связка - плагин gulp-livereload + плагин LiveReload под браузер.

Сказать честно, предыдущий опыт настройки LiveReload, описанный в этой статье - “Установка LiveReload в Sublime Text 2” меня полностью не удовлетворял и я им не пользовался. Причина заключалась в том, что иногда эта связка работала, а иногда - почему-то нет. Нестальность работы плагина под Sublime Text (у меня) отбивала всякое желание иметь с ним дело.

А вот связка плагин gulp-livereload + плагин LiveReload под браузер работает стабильно. Кроме того, если Node.js + Gulp уже настроен для текущего проекта, то не возникает никакой проблемы в установке дополнительного плагина gulp-livereload.

Установка плагина gulp-livereload

Плагин gulp-livereload проживает по указанному адресу - gulp-livereload. Установка в проект производиться командой:

$ npm install --save-dev gulp-livereload

В виде зависимостей проекта запись в файле package.json должна выглядеть (как минимум) так:

{
 "name": "test",
 "version": "0.0.1",
 "devDependencies": {
  "gulp": "~3.8.7",
  "gulp-livereload": "~2.1.1"
 }
}

Добавляем переменную livereload в файл gulpfile.js для инициализации плагина gulp-livereload и дальнейшей работы с ним:

var gulp = require('gulp'),
    livereload = require('gulp-livereload');

Установка плагина LiveReload под браузер

Следующим шагом будет установка расширения LiveReload под браузер. В моем случае это будет Mozilla Firefox, однако расширение LiveReload существует и под два других популярных браузера - Google Chrome и Safari.

Для установки расширения под Firefox не стоит искать его на странице расширений Mozilla - LiveReload 0.6.4. Там находится устаревшая версия плагина, которая наверняка не подойдет для вашего браузера.

Лучше посетим домашнюю страницу проекта LiveReload с описанием установки расширений под каждый из браузеров - How do I install and use the browser extensions. Скачиваем по указанной на странице ссылке расширение под нужный браузер (Firefox) и автоматически устанавливаем его.

На панели инструментов браузера появиться значок плагина LiveReload в виде круга из двух стрелок. Однократное нажатие на значок запускает плагин - он принимает вид, похожий на компас со стрелкой. Еще одно нажатие выключает плагин LiveReload.

Создание задачи под gulp-livereload

В принципе, плагин gulp-livereload не требует для себя создания отдельной задачи. Все, что нужно для него - это запуск его как локального сервера. Если вы скажете, что не устанавливали сервер LiveReload, то могу успокоить вас - устанавливали! Инсталляция плагина gulp-livereload подразумевает автоматическую установку сервера LiveReload.

Поэтому нам нужно всего лишь предварительно активировать, запустить его. Кстати, если у вас вдруг при попытке включения плагина LiveReload в браузере появляется окно с такой ошибкой:

Ошибка запуска сервера LiveReload

… то это говорит всего лишь о том, что перед этим не был запушен в консоли сам сервер LiveReload. Для этого я создам задачу watch, внутрь которой помещу вызов функции livereload():

// Watch Task
 gulp.task('watch', function(){
  livereload.listen();
  gulp.watch('sass/*.scss', ['sass']).on('change', livereload.changed);
});

Все - мне больше ничего не нужно дописывать для задачи компилирования из Sass в CSS (эта задача приведена здесь в качестве примера использования плагина gulp-livereload):

// Sass Complie Task
 gulp.task('sass', function(){
 gulp.src('sass/*.scss')
  .pipe(sassSCSS())
  .pipe(gulp.dest('build/css'));
});

Полностью листинг файла gulpfile.js в данном случае будет выглядеть таким образом:

var gulp = require('gulp'),
    sassSCSS = require('gulp-sass'),
    minifyHTML = require('gulp-minify-html'),
    rename = require('gulp-rename'),
    livereload = require('gulp-livereload');

// Default Task
gulp.task('default', ['sass', 'watch']);

// Watch Task
 gulp.task('watch', function(){
  livereload.listen();
  gulp.watch('sass/*.scss', ['sass']).on('change', livereload.changed);
});

// Sass Complie Task
gulp.task('sass', function(){
 gulp.src('sass/*.scss')
  .pipe(sassSCSS())
  .pipe(gulp.dest('build/css'));
});

Все готово для тестирования работы плагина gulp-livereload.

Тестирование плагина gulp-livereload

Осталось выполнить две маленькие вещи. Первая - включаю плагин LiveReload в браузере. Вторая - запускаю Gulp для мониторинга изменений и работы плагина gulp-livereload:

$ gulp
Using gulpfile ~/Projects/gulp_test/gulpfile.js
Starting 'sass'...
Finished 'sass' after 11 ms
Starting 'watch'...
Finished 'watch' after 17 ms
Starting 'default'...
Finished 'default' after 19 μs
Live reload server listening on: 35729

Видим, как последняя строка в консоли говорит нам, что сервер LiveReload запустился и прослушивает порт по умолчанию - 35729. Вношу изменения в файл стилей style.scss:

figure{
  border: 1px solid #000;
  padding: 5px;
 }

… и смотрю на вывод в консоли:

$ gulp
Using gulpfile ~/Projects/gulp_test/gulpfile.js
Starting 'sass'...
Finished 'sass' after 10 ms
Starting 'watch'...
Finished 'watch' after 15 ms
Starting 'default'...
Finished 'default' after 11 μs
Live reload server listening on: 35729
style.scss was reloaded.
Starting 'sass'...
Finished 'sass' after 3.58 ms

Изменение было отслежено, файл перекомпилирован задачей sass. А что же плагин gulp-livereload - он тоже подхватил изменения?

Смотрим:

Изменения в gulp-livereload

О, да! Изменение было подхвачено плагином gulp-livereload - “картинка” в окне браузера изменилась без перезагрузки последнего.

Еще раз проверим и внесем какое-нибудь изменение в файле стилей:

$ gulp
Using gulpfile ~/Projects/gulp_test/gulpfile.js
Starting 'sass'...
Finished 'sass' after 10 ms
Starting 'watch'...
Finished 'watch' after 15 ms
Starting 'default'...
Finished 'default' after 11 μs
Live reload server listening on: 35729
style.scss was reloaded.
Starting 'sass'...
Finished 'sass' after 3.58 ms
style.scss was reloaded.
Starting 'sass'...
Finished 'sass' after 1.97 ms

Изменения в gulp-livereload

Отлично! Вот мы и изучили еще одну полезную сторону работы с Gulp - использование плагина gulp-livereload.


Крайне необходимая задача, возникающая в работе каждого верстальщика - это оптимизация графики, нарезанной из psd-макета или используемой в HTML-шаблоне.

Для этой цели существует много разных инструментов, начиная с RIOT и заканчивая утилитами Linux. Но гораздо более удобной возможностью является автоматизация процесса сжатия картинок с помощью плагина под Gulp.

Таким плагином является gulp-imagemin. Он умеет сжимать картинки форматов PNG, JPEG, GIF и SVG. Все остальные (не поддерживаемые) форматы графических файлов просто игнорируются плагином gulp-imagemin.

Установка gulp-imagemin

Установка плагина gulp-imagemin стандартная и производиться командой npm install с ключом --save-dev для внесения пакета в список зависимостей проекта:

$ sudo npm install --save-dev gulp-imagemin

Создание задачи под gulp-imagemin

После установки плагина gulp-imagemin необходимо создать задачу сжатия картинок под этот плагин. Ничего необычного в этом нет и задача создается стандартно. Сначала создаем переменную imagemin, в которую помещаем сам плагин gulp-imagemin:

var imagemin = require('gulp-imagemin');

А затем создаем задачу с произвольным именем compress:

// Compress Task

gulp.task('compress', function() {
  gulp.src('images/*')
  .pipe(imagemin())
  .pipe(gulp.dest('build/images'))
});

Задачу compress можно запускать однократно вручную или автоматически, доверив это дело Gulp и поместив ее внутрь встроенной функции gulp.watch.

Создаю в проекте gulp_test директорию images и размещаю в ней несколько изображений формата .jpg, но достаточно большого размера:

$ ls images/
black (22).jpg  black (23).jpg  black (28).jpg  black (31).jpg  black (36).jpg  black (41).jpg

Цель - проверить, действительно ли происходит сжатие графических файлов. Давайте опробуем работу плагина gulp-imagemin однократно, запустив в консоли команду gulp compress:

$ gulp compress
Using gulpfile ~/Projects/gulp_test/gulpfile.js
Starting 'compress'...
Finished 'compress' after 8.56 ms
gulp-imagemin: Minified 6 images (saved 83.02 kB - 7.2%)

Отлично! Задача compress запустилась и выполнилась за 8.56 миллисекунд. При этом было обработано 6 изображений, над которыми была произведена операция сжатия. Экономия размера в результате компресии составила 7.2%.

Давайте посмотрим на изображения в оригинале, расположенные в директории images:

Оригинальные изображения в проекте

… запомним примерные размеры каждого из файлов. А затем взглянем на содержимое директории build/images/, в которой располагаются сжатые плагином gulp-imagemin изображения:

Обработанные плагином gulp-imagemin изображения

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

Gulp-imagemin - автоматический мониторинг

Давайте доведем нашу задачу до логического завершения и настроим Gulp таким образом, чтобы он автоматически отслеживал добавление в директории images новых изображений.

И как только они появляются там, то немедлено производил бы их сжатие при помощи плагина gulp-imagemin.

Для этого создам задачу мониторинга watch:

// Watch Task

gulp.task('watch', function() {
  gulp.watch('images/*', ['compress']);
});

… которую добавлю в очередь на выполнение для дефолтной задачи default:

// Default Task

gulp.task('default', ['watch']);

Полностью листниг файла gulpfile.js для данного случая выглядит следующим образом:

var gulp = require('gulp'),
    imagemin = require('gulp-imagemin');

// Default Task
gulp.task('default', ['watch']);

// Watch Task
gulp.task('watch', function() {
  gulp.watch('images/*', ['compress']);
});

// Compress Task
gulp.task('compress', function() {
  gulp.src('images/*')
  .pipe(imagemin())
  .pipe(gulp.dest('build/images'));
});

Запускаю в консоли команду gulp, а затем по одному добавлю в директорию images два файла-скриншота, созданных мною для этой статьи.

Видим, что каждый раз, как в директорию images был добавлен файл, Gulp запускал задачу compress на выполнение:

$ gulp
  Using gulpfile ~/Projects/gulp_test/gulpfile.js
  Starting 'watch'...
  Finished 'watch' after 8.42 ms
  Starting 'default'...
  Finished 'default' after 12 μs
  Starting 'compress'...
  Finished 'compress' after 13 ms
  gulp-imagemin: Minified 7 images (saved 93.43 kB - 7.7%)
  Starting 'compress'...
  Finished 'compress' after 2.13 ms
  gulp-imagemin: Minified 8 images (saved 103.77 kB - 8%)

На выполнение первой задачи ушло 7 миллисекунд:

gulp-imagemin: Minified 7 images (saved 93.43 kB - 7.7%)

… на вторую задачу - 2.13 миллисекунд:

gulp-imagemin: Minified 8 images (saved 103.77 kB - 8%)

При этом я “выиграл” 7.7% и 8% размера, что скажется на скорости загрузки страницы в браузере. Также обратите внимание, что Gulp продолжает работать, находясь в фоновом режиме.

Усложним задачу для gulp-imagemin

Можно немного усложнить и усовершенствовать процесс оптимизации изображений. Для этого немного перепишу задачу compress таким образом:

// Compress Task
  gulp.task('compress', function() {
    gulp.src('images/*')
    .pipe(imagemin({
      progressive: true
    }))
    .pipe(gulp.dest('images/'));
  });

Первое изменение - это добавлена опция progressive: true к плагину gulp-imagemin. Эта опция управляет методом сжатия графических файлов и приведена мною для наглядности примера.

Второе изменение - изменена директория назначения. Теперь директория-источник изображений gulp.src('images/*') и директория-“выхлоп” gulp.dest('images/'), куда помещаются обработанные изображения - одна и та же.

Таким образом, достаточно положить в директорию images какое-либо изображение и оно тут же преобразуется в точно такое же изображение, но меньшего размера! Удобно, не правда ли?

На этом все.


Кто не знаком с тем, что при написании кода очень часто возникают ошибки или банальные опечатки?

И даже если установлены такие палочки-выручалочки, как Emmet, это не всегда спасает из ситуации. А если представить, что вы пишете большой проект и в нем закралась ошибка, то нелегко будет ее найти в куче кода.

При использовании Gulp, который автоматически отслеживает события и выполняет соотвествующие задачи, ситуация несколько “облегчается” тем, что при возникновении ошибки можно увидеть тот момент, когда она произошла.

Например, Gulp настроен на автоматическое фиксирование изменений через gulp.watch. Если возникла ошибка, то выполнение мониторинга в Gulp прерывается:

Прерванная работа Gulp

Но даже в этом случае довольно трудно разобраться, где именно закралась ошибка. В этой ситуации может помочь плагин gulp-plumber, который формирует вывод об ошибке. Но при этом работа Gulp не прерывается.

Давайте установим и попробуем в работе плагин gulp-plumber.

Установка плагина gulp-plumber

Установка плагина gulp-plumber стандартная, через менеджер пакетов npm с ключом --save-dev:

$ sudo npm install --save-dev gulp-plumber

Использование плагина gulp-plumber

Для применения плагина gulp-plumber в проекте необходимо создать переменную plumber:

var plumber = require('gulp-plumber');

А затем дописать строку .pipe(plumber()) в ту задачу, в которой необходимо включить возможность отслеживания ошибок. Например, пусть это будет задача минификации всех js-файлов проекта uglify. Тогда в ней сразу после строки gulp.src('js/*.js') добавляем строку .pipe(plumber()), чтобы отслеживались возможные ошибки во всех нижеследующих задачах, таких как .pipe(uglify()) или .pipe(gulp.dest('build/js')):

// Uglify Task
gulp.task('uglify', function(){
  gulp.src('js/*.js')
    .pipe(plumber()) // plumber
    .pipe(uglify())
    .pipe(gulp.dest('build/js'))
});

Точно также можно поступить, если необходим контроль ошибок в другой задаче, к примеру конкатенации CSS-файлов:

// Concat Task
gulp.task('concat', function(){
  gulp.src('css/*.css')
    .pipe(plumber())
    .pipe(concatCSS('concatenate.css'))
    .pipe(minifyCSS())
    .pipe(gulp.dest('build/css'))
});

Запуск мониторинга ошибок gulp-plumber

Для удобства проверки работы плагина gulp-plumber создам задачу gulp.watch и помещу ее в задачу по умолчанию default:

// Watch Task
gulp.task('watch', function() {
  gulp.watch('js/*.js', ['uglify']);
  gulp.watch('css/*.css', ['concat']);
});

// Default Task
gulp.task('default', ['watch']);

Запускаю в консоли процесс мониторинга в Gulp командой:

$ gulp

… и смотрю на вывод в консоли:

Gulp в фоновом режиме

Теперь намеренно вношу ошибку в файл jquery-1.11.1.js и снова перевожу взгзляд на консоль:

Плагин gulp-plumber отследил ошибку

Отлично! Плагин gulp-plumber выполнил свою задачу - сформировал ясный и четкий отчет об ошибке. И при этом не прервал работу самого Gulp.

Возвратим все назад и исправим ошибку, допущенную ранее. Снова взглянем на консоль:

Плагин gulp-plumber - ошибка исправлена

Плагин gulp-plumber снова справился со своей задачей - ошибка нами исправлена и он прилежно ее зафиксировал.