Когда я только–только заинтересовался системой сборки, оптимизации, проверки и упаковки разрабатываемого сайта gulp, установил её у себя и начал с ней «играться», мне постоянно попадались примеры, в которых использовался плагин gulp–notify и демонстрировались его возможности по выводу на экран компьютера сообщений о ходе выполнения задач — оповещения об удачном или неудачном завершении, произошедшей ошибке и т.п.
Когда же я принял судьбоносное решение об использовании в качестве базового прототипа сборник задач gulpfile.js из пакета WebStarterKit, там ничего похожего на процедуры дополнительного оповещения не обнаружилось. По здравому размышлению, я пришёл к мысли, что особой острой необходимости в в таких процедурах (например, gulp–notify), вроде бы, нет: «глоток» самостоятельно и интенсивно выводит на экран консоли достаточное количество сведений о процессах, которые происходят при выполнении инициированных задач. Однако, совершенно очевидно, что такое положение дел не в полной мере соответствует представлениям о комфорте работы: разработчик вынужден постоянно наблюдать за экраном, не побоюсь этого слова, таращиться в монитор, при том, что в некоторых случаях работа задачи может растянуться на довольно продолжительное время. Кроме того, если уж взялся автоматизировать процесс разработки, то нужно идти до конца, то есть, упрощать себе, любимому, работу по максимуму, создавая всяческие удобства по тому же самому максимуму.
В общем, я бы тоже охотно и радостно попользовал бы плагин gulp–notify, чтобы просто и незатейливо передать в операционную систему команду, которая выведет на экран нужное мне сообщение. Но в моём случае решение оказалась невозможнім: чтобы использовать функционал gulp–notify с Windows, операционка должна иметь версию не ниже восьмой, то есть, моя Windows XP, а также некоторые другие версии помоложе моей (Vista, Win7) оказываются «лишними на этом празднике жизни».
Надежда забрезжила, когда оказалось, что этот плагин можно «прикрутить» к системе оповещения Growl. Я быстренько установил себе «рычалку» (вольный перевод английского growl), но что–то там не заладилось и скрипты никак не хотели выдавать долгожданные сообщения: то ли я что–то не так настроил, то ли просто они (плагин или Growl) меня невзлюбили (я, действительно, бываю порой неприятным). Недолго думая, решил сменить и плагин, и «рычалку».
Оказалось, что gulp–notify при работе «в тандеме» с Growl использует плагин node-notifier, и я решил «припасть к истокам», то есть, обратиться к первоисточнику. Поскольку мой предыдущий негативный опыт взаимодействия с Growl ещё был свеж в памяти, и горючие слёзы разочарования не высохли на упитанных ланитах, я обратил внимание на возможность вызова с помощью этого плагина всплывающей подсказки из системного лотка, широко известной среди пользователей винды как WindowsBalloon. Для этого, правда, требовалась дополнительная программа notifu — бесплатная утилита из двух не требующих инсталляции файлов (notifu.exe и notifu.pdb для 32–битных систем, notifu64.exe и notifu64.pdb для 64–битных; каждая пара размером около 4,5М).Но, оказалось, что эта утилита поставляется вместе с пакетом node-notifier (потому–то он и «весит» в общей сложности 10М).
Итак, взял я рекомендованный пример и попробовал «проиграть» его на примере задачи JShint (проверка корректности сценария Javascript):
var WindowsBalloon = require('node-notifier').WindowsBalloon;
var notifier = new WindowsBalloon();
gulp.task('jshint', function () {
var proc = gulp.src('js/*.js')
.pipe($.jshint())
.pipe($.jshint.reporter('jshint-stylish'));
notifier.notify({
title: 'GULP JShint',
message: 'Выполнение задачи завершено',
sound: true, // При выводе сообщения подаётся звуковой сигнал
time: 5000, // Сообщение демонстрируется в течение 5 секунд
wait: false});
return proc;
});
В правом нижнем углу экрана всплыло жёлтое облачко с текстом в две строки (см. скриншот внизу). И всё бы хорошо, но выполнение задачи при этом остановилось на заказанные пять секунд (или до тех пор, пока я не клацну мышкой по облаку). Вроде бы, директива wait: false (см. строку 16 в приведенном выше фрагменте кода) должна обеспечить завершение работы задачи, независимо от поведения сообщения, но на практике она ждёт и «задерживает очередь». Замена в этой строке false на true не привело к заметному изменению в поведении плагина. В общем, получилось не совсем то, что ожидалось, и комфорта сложившаяся ситуация совершенно не прибавила.
Вместе с тем, мне когда–то попадался на глаза пример вызова внешней команды (а notifu является именно такой внешней командой), поражающий своей простотой и изяществом: используется вызов стандартного метода дочернего процесса (child_process), изначально встроенного в пакет node.js, то есть, никакие плагины не нужны:
var exec_f = require('child_process').execFile;
exec_f('C:\\Program Files\\Accessories\\notifu',
['/p', 'GULP JShint', '/m', 'Работа сценария завершена', '/i', 'info'],
{timeout: 250}
);
что аналогично вызову команды с аргументами:
> notifu /p 'GULP JShint' /m 'Работа сценария завершена' /i 'info'
У этого способа использования системы оповещения есть несколько особенностей. Во–первых, необходимо обзавестись утилитой notifu (я её загрузил с сайта разработчика и поместил в каталоге C:\Program Files\Accessories). Во–вторых, директива timeout: 250 позволяет прервать этот child_process через 250 мс (продолжительность таймаута должна быть кратной 250): в результате, сообщение в жёлтом «облачке» продолжает «висеть» над системным лотком, а выполнение задачи продолжается практически сразу (ну, что такое 250 миллисекунд!). Похоже, удалось обойти досадный баг с wait в node-notifier.
Итак, приемлемое решение было найдено, осталось уничтожить следы неудачных экспериментов, то есть «снести» node-notifier и Growl, после чего твёрдой поступью зашагать в светлое будущее под знаменем notifu.
«Не введи в искушение, но избавь от лукавого» — гласит основная христианская молитва (кстати, единственная рекомендованная Спасителем). Не получилось: и в искушение ввёл, и от лукавого не избавил. А всё потому, что решил я напоследок попробовать, работает ли node-notifier с growl′ом — просто так попробовать, на всякий случай. Попробовал. Работает.
Получилось гораздо выразительнее, красивее и нагляднее — никакого сравнения с notifu
var Growl = require('node-notifier').Growl;
var notifier = new Growl({
name: 'Growl @ zaliv.info',
host: 'localhost',
port: 23053
});
gulp.task('jshint', function () {
var proc = gulp.src('js/*.js')
.pipe($.jshint())
.pipe($.jshint.reporter('jshint-stylish'));
notifier.notify({
title: 'GULP JShint',
message: 'Выполнение задачи завершено',
wait: false});
return proc;
});
Здесь отказ от ожидания реакции пользователя wait: false (см. строку 17) работает исправно, а продолжительность показа сообщения на экране и куча других свойств регулируются уже в настройках Growl. В общем, моё сердце дрогнуло…
А потом я «встретил» growly и понял, что это — судьба. Я таки удалил node-notifier со всеми его десятью мегабайтами разного мотлоха, включая пять подвязанных к нему плагинов, входящих в его зависимости. Потому, что node-notifier для «общения» с Growl′ом использовал именно growly, а я, как уже заметил мой читатель, стараюсь добраться до первоисточников.
Итак, знакомьтесь: конечная цель моих изысканий — плагин growly.
var growly = require('growly');
growly.register('GULP @ zaliv.info');
gulp.task('jshint', function () {
var proc = gulp.src('js/*.js')
.pipe($.jshint())
.pipe($.jshint.reporter('jshint-stylish'));
growly.notify('Скрипт выполнен', { title: 'JShint'});
return proc;
});

Можно было бы на этом и остановиться, но я ударился в усовершенствования и украшательства — соорудил три иконки для основных типов сообщений и наваял универсальную функцию для вызова «рычалки»:
var growly = require('growly');
growly.register('GULP @ zaliv.info', 'zaliv.png', [
{label: 'success', dispname: 'Успешно'},
{label: 'warning', dispname: 'Предупреждение'},
{label: 'error', dispname: 'Ошибка'}
]);
function depesha (header, message, mode) {
var labels = {
'i': 'success',
'w':'warning',
'e':'error'},
t = new Date();
growly.notify(message, {
title: header + " [" + t.toLocaleTimeString() + "]",
label: labels[mode],
icon: 'zaliv-' + mode + '.png'
})
};
gulp.task('jshint', function () {
gulp.src('js/*.js')
.pipe($.jshint())
.pipe($.jshint.reporter('jshint-stylish'));
depesha("JShint", "Задача выполнена", "i");
depesha("JShint", "Есть незначительные погрешности", "w");
depesha("JShint", "Ошибка выполнения", "e");
});
В настройках Growl установил «липкий» (sticky) режим отображения сообщений, то есть, они будут болтаться на экране, пока я их сам не закрою — лучше так, чем пропустить что–нибудь, пока на кухне чайком с зефиркой баловался. Получилась такая картина:
Если будет время, можно ещё «пошаманить» с темами в настройках Growl (настроить свою для каждого типа сообщений в зависимости от метки), но это не к спеху.
Комментариев нет:
Отправить комментарий