gulp, npm и bower - враги рутины

Я думаю многие из читающих заметку уже слышали о перечисленных в заголовке утилитах. Если Вы еще их не используете, рекомендую ознакомиться с ними немедленно!

Что это за ребята?


Наверняка вы слышали о node.js. По сути это тюнингованный движок JavaScript V8, предназначенный для запуска js вне браузерной среды, т.е. для использования JS в качестве серверного языка сценариев или для разработки утилит командной строки.


Как и у любой современной платформы, у node.js имеется менеджер пакетов, позволяющий установить любой необходимый пакет для Вашего приложения - npm.

 


На момент написания статьи, npm интегрирован в node.js, поэтому если Вы установили ноду, npm у вас уже есть.


 

Bower, как и npm, является пакетным менеджером, однако отличается тем, что нацелен на frontend библиотеки. К примеру, с помощью bower можно установить bootstrap или jquery со всеми зависимостями.

 

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

 

Зачем они мне?


Эти ребята способны сэкономить кучу вашего драгоценного времени! (нет, серьёзно!)

 

Как Вы начинаете новый проект? Заходите на getbootstrap.com, скачиваете архив с bootstrap, заходите на jquery.com, скачиваете jquery, заходите еще на n-ое количество сайтов в поиске нужных библиотек, а это, между прочим, довольно затратно по времени, да еще и требует кучи телодвижений и действий.

 

В тот момент, когда у Вас наконец сработает заветное - ЗАДОЛБАЛО, Вы и поймете выгоды от использования этих инструментов.

 

Один только bower дает возможность сэкономить кучу времени на поиске и установке нужных frontend библиотек. Буквально одной командой мы устанавливаем bootstrap, jquery, кучку других полезных и не очень библиотек, причем все необходимые зависимости будут разрешены без вашего участия. Все что вам остается сделать - подключить эти библиотеки в html файле.

 

Gulp позволяет автоматизировать сборку проекта, имеет огромную библиотеку плагинов для практически любых задач - от компиляции less/sass и запуска autoprefixer до сжатия изображений и автоматической перезагрузки страницы в браузере при изменении исходных файлов (так называемый live-reload).

 

На словах ты Лев Толстой...


Давайте рассмотрим пример небольшого проекта, в котором используем все перечисленные инструменты.

 

В нашем проекте мы будем использовать less в качестве препроцессора css. Также нам понадобятся bootstrap, jquery, autoprefixer.

 

Если bower и gulp еще не установлены, сделаем это:

npm install -g bower gulp

 

Ключ -g означает что пакеты нужно установить глобально, т.е. bower и gulp станут доступны как обычные утилиты командной строки.

 

Далее нужно создать папку с проектом и инициализировать в ней npm:

mkdir my_project && cd my_project
npm init
npm install --save gulp gulp-less gulp-autoprefixer gulp-concat-css browser-sync

 

Команда npm init задаст вам  пару вопросов и создаст файл package.json. В этом файле будет храниться информация о проекте, а также списки зависимостей. Это очень удобно при совместной разработке, поскольку позволяет не засорять cvs кучей библиотек.

В случае, когда вы получаете обновленный package.json следует выполнять команду npm update, чтобы обновить/доустановить библиотеки. Также это работает и в bower.

 


Здесь мы снова устанавливаем gulp, но на этот раз локально. Это нужно для того чтобы функционал gulp был доступен в gulpfile.


 

Затем инициализируем bower: 

bower init

 

Подобно npm - bower хранит списки установленных зависимостей в файле bower.json, поэтому в cvs достаточно будет добавить только его.

 

Итак, полдела сделано! Установим jquery и bootstrap (jquery является зависимостью bootstrap, поэтому его можно было бы опустить):

bower install --save bootstrap jquery

 

Ключ --save заставляет bower выставить в bower.json имена установленных пакетов. Также существует ключ --save-dev, который служит для разграничения пакетов по разным окружениям, но пока что мы этой темы касаться не будем.

На заметку

По умолчанию bower загружает все компоненты в папку bower_assets. Папку назначения можно переопределить, создав рядом с bower.json файл .bowerrc, со следующим содержанием:

{
	"directory" : "<DIRECTORY_PATH>"
}

 

ОК! С bower разобрались, теперь самое время написать gulpfile для сборщика проекта.

 

Вот небольшой пример gulpfile:

var gulp = require('gulp');
var less = require('gulp-less');
var autoprefixer = require('gulp-autoprefixer');
var concat = require('gulp-concat-css');
var browserSync = require('browser-sync');
var path = require('path');

// задача для компиляции less в css и проставления вендорных префиксов
gulp.task('less', function() {
    return gulp.src('./less/*.less')
        .pipe(less({
            paths: [ path.join(__dirname, 'bower_components') ]
        }))
        .pipe(autoprefixer({
            browsers: ['last 50 versions'],
            cascade: false
        }))
        .pipe(concat('style.css'))
        .pipe(gulp.dest('./css'))
});

// задача для вывода результата компиляции в браузере
gulp.task('browser-sync', ['less'], function() {
    browserSync.init({
        server: {
            baseDir: "./"
        }
    });
});

// задача для отслеживания изменений в файлах
gulp.task('watch', function () {
    gulp.watch('./less/*.less', ['less']);

    gulp.watch('./css/*.css').on("change", browserSync.reload);
    gulp.watch('./*.html').on('change', browserSync.reload);
});

// задача по умолчанию
gulp.task('default', ['browser-sync', 'watch']);

 

Основное предназначение - компилировать less → css, выставлять вендорные префиксы, а также синхронизировать изменения файлов с браузером. 

 

gulp

Как вы увидели выше - писать сборочные скрипты для gulp достаточно просто, ведь это ни что иное как обыкновенный JavaScript!

 

Сборочный скрипт состоит из списка задач (task). Задачи это как-бы именованные наборы действий, каждую задачу можно вызвать отдельно - приписав её имя в качестве параметра при вызове gulp. (Например, gulp less запустит только компиляцию less). При запуске gulp без параметров, будет запущена задача default

 

У задач могут быть зависимости от других тасков, это определяется вторым параметром функции task (если передать массив имен задач, то они будут выполнены перед зависимой задачей).

 


Например в нашем gulpfile задача browser-sync перед своим выполнением вызовет задачу less.


 

Тело задачи обычно состоит из вызовов gulp.src() - эта функция является началом gulp конвеера. Параметр функции обычно задает файл (или маску пути), который будет передан последующим функциям по цепочке.

 

Функция pipe  является элементом конвеера gulp и позволяет выполнить ту или иную обработку файла и передает результат своего выполнения следующей конвеерной функции. (Например, pipe(less(...)) преобразует less в css, после чего pipe(autoprefixer(...)) выставляет вендорные префиксы в готовом css).

 

По завершении конвеерной обработки результат нужно куда-то сохранить, для этого используется конвеерная функция dest, параметром которой является путь назначения (В примере обработанный css будет выгружен в папку css)

 

В принципе, для успешного юзинга gulp этой информации должно быть вполне достаточно, тем более что каждый gulp-пакет распространяется с примером подключения. (В большинстве случаев - юзаем стратегию ctrl+c, ctrl+v).

 

Верстаем

Со скриптами gulp мы разобрались, поэтому самое время испытать все это в бою. Я предлагаю создать такую html страницу (index.html):

<!doctype html>
<html>
    <head>
        <meta charset="utf-8">
        <title>Test gulp!</title>
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <link rel="stylesheet" href="css/style.css">
    </head>
    <body>
        <div class="row">
            <div class="col-md-8 col-md-offset-2">
                <h2 class="title">Hello!</h2>

                <p class="text">
                    lorem ipsum dolorem sit amet
                </p>

                <p class="footer-text">
                    2016 test page
                </p>
            </div>
        </div>
    </body>
</html>

 

Стилизуем

Теперь добавим в папку less файл style.less с таким текстом:

@import "bootstrap/less/bootstrap";

.title {
    // используем цветовые переменные bootstrap (bootstrap/less/variables.less)
    color: @gray-base;
    font-size: 20px;
}

.text {
    font-size: 14px;
}

.footer-text {
    color: @brand-primary;
    font-size: 12px;
    border-top: 1px solid @brand-primary;
    padding: 20px;
}

 

Запускаем

Все готово, можно попробовать запустить gulp. В результате выполнения в браузере откроется livereload вкладка, как на скриншоте:

Результат наших трудов

Если сейчас поменять что-то в верстке или в less файле, то файлы будут автоматически перекомпилированы, после чего страница перезагрузится с новым результатом.

 

На этом данную статью прошу считать завершенной, в будущем мы еще вернемся к более подробному рассмотрению css препроцессоров.

 

Что ж, с инструментами разобрались, самое время обезжиривать HTML!