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!