Заказать звонок
Заказ обратного звонка

Использование Gulp. Часть 2 - css плагины.


В данной статье рассмотрим как компилировать SASS, объединять все файлы стилей в один и минифицировать css средствами Gulp.

gulpfile.js - файл управлениея проектом.
Открываем наш проект в редакторе кода и в корневой папке создаем файл gulpfile.js.
В нем будут содеражаться все инструкции для сборки нашего проекта.
Первым делом подключим gulp:

var gulp = require('gulp');

require указывает, что надо проверить папку node_modules и найти там папку gulp. 
Если такая имеется, то ее содержимое записывается в переменную gulp.

Научимся писать задачи.
Обычно, в задаче содержится два дополнительных метода Gulp и различные плагины.
Например:

gulp.task('task_name', function () {
    return gulp.src('source_files') // путь к файлам-исходникам
    .pipe(plugin_name()) // прогоняем их через плагин
    .pipe(gulp.dest('destination_derictory')) // путь к папке, куда помещаем конечные файлы
})

Первый пример - классика жанра:

gulp.task('hello', function() {
    console.log('Hello Valentina');
});

Находясь в корне проекта, запускаем коммандную строку и вводим:
gulp hello



Удалим учебную задачу, и переходим к реальным.

gulp.task('default', function() {
    //здесь будет код задачи
});

Если у задачи  имя default - это значит, что она будет выполняться по умолчанию.
Даже если в командной консоли мы не указываем имя задачи, а просто пишем gulp, задача default все равно выполняется.

Плагин gulp-sass - компилирует SASS файлы.
Сначала из коммандной косоли устанавим сам пакет:
npm install gulp-sass --save-dev

В корне проекта создадим папку с исходными файлами с назовем ее src.
Внутри нее создадим папку для файлов стилей, назовем ее sass.
А папка для конечных файлов - это папка css шаблона, с которым мы работаем.
По идее она должна быть пустая, там не должно быть никаких файлов.
Но так как мы сейчас учимся на на дефолтном шаблоне OkayCMS, для наглядности давайте перенесем файлы style.css, responsive.css и libs.css (поэкспериментируем пока только с этими тремя) из папки CSS в только что созданную папку sass и сменим расширение css на scss. Но внутри все-таки остался обычный css. Давайте изменим ситуацию.
Откроем style.scss (папка src в корне) и запишем sass-код:
В самом верху сайта запишем переменные, например:

$color: #f00;
$border: 2px solid $color; 
$bold: bold;

И  придумаем какие-нибудь стили для верхнего меню сайта:

.menu_item {
    color: $color;
    font-weight: $bold;
    border: $border;
}

В файле gulpfile.js добавляем переменную для плагина

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

И создаем задачу:

gulp.task('default', function () {
    return gulp.src('./src/sass/**/*.scss')
    .pipe(sass().on('error', sass.logError))
    .pipe(gulp.dest('./design/okay_shop/css'));
});

.pipe(sass().on('error', sass.logError)) означает проганяем файлы .scss через плагин и, если есть ошибки, выводим в консоль.

*.scss - выбирает все файлы, имеющие определенное расширение (в данном случае, .scss) в корневой папке проекта.
**/*.scss - выбирает все файлы с расширением .scss во всех подпапках.
!header.scss - исключает файл из общей выборки

Весь код gulpfile.js:

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

gulp.task('default', function () {
    return gulp.src('./src/sass/**/*.scss')
    .pipe(sass().on('error', sass.logError))
    .pipe(gulp.dest('./design/okay_shop/css'));
});

Запустим задачу в ком.строке командой gulp.

Результат: в папке design/okay_shop/CSS - появились файлы style.css, responsive.css и libs.css, но теперь это файлы, скомпилированые с SASS. Открываем style.css и видим наши новые правила:

Обновляем браузер - пункты меню изменились

Sourcemaps - карта стилей.
Открываем панель разработчиков и посмотрим на наш код.
Нам указывают строку 1 в файле style.css


Но мы пишем код в scss на строке 5, кошмар, а что же будет дальше?

Для решения проблемы ставим плагин gulp-sourcemaps
https://www.npmjs.com/package/gulp-sourcemaps

В консоли:
npm install gulp-sourcemaps --save-dev

В gulpfile.js добавляем вверху в секцию со всеми require еще одну переменную

sourcemaps = require('gulp-sourcemaps');

В этом плагине есть некоторые особенности.
Активировать его .pipe(sourcemaps.init()) надо перед пайпингом sass (или другим фильтром, например js, если карта для js), затем идет .pipe(sass(), а затем после всех фильтров sourcemaps.write('.')

.pipe(sourcemaps.init())
.pipe(sass().on('error', sass.logError))
.pipe(sourcemaps.write('.'))

gulpVV_6_1
Еще раз запустим задачу: пишем в коммандной строке gulp и жмем Enter.
Обновляем страницу и смотрим код - теперь указана строка в style.scss и писать код стало намного проще и удобнее.



Watch отслеживает изменения.
Но осталось еще одно неудобство, которое сильно раздражает. Каждый раз, когда мы меняем sass, приходиться перезапускать gulp.
Нам поможет замечательный метод watch().

Создадим еще одну задачу, назвем ее sass, поставим ее перед нашей задачей default и перенесем в нее все, что сейчас стоит внутри задачи default

gulp.task('sass', function () {
    return gulp.src('./src/sass/**/*.scss')
    .pipe(sourcemaps.init())
    .pipe(sass().on('error', sass.logError))
    .pipe(sourcemaps.write('.'))
    .pipe(gulp.dest('./design/okay_shop/css'));
});

У нас теперь две задачи: sass и default.
Чтобы запустить задачу sass, в ком строке теперь надо обязательно указать название задачи (как мы помним, если указывать просто gulp, запускается задача по умолчанию - default).
Давайте запустим:

набираем gulp sass в коммандной строке и жмем Enter.

Видим, что все прошло успешно, никаких ошибок нам не выдало.
Можно даже изменить что-то в sass, например цвет указать $color: #00f;
Перезапустим gulp sass.
Обновляем браузер - все работает.

Но я хочу запускать задачу sass как раньше, набрав просто gulp, без указания названия задачи.
Для этого в задачу default добавим массив с названием задачи sass.

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

gulpVV_6.2

Давайте для наглядности еще раз поменяем цвет:
$color: #0f0 и запустим gulp.
Обновляем браузер.
Отлично, все работает.

Добавим еще одну задачу, и назовем ее watch. Название задачи здесь значения не имеет, всю магию делает функция gulp.watch.
Копируем внутрь функции путь, который мы указывали sass и через запятую добавляем массив sass

gulp.task('watch', function () {
    gulp.watch('./src/sass/**/*.scss' , ['sass'])
});


Теперь watch будет смотреть, произошли ли какие-нибудь изменения в указанных файлах, и если да, то перезапускает задачу sass.
gulpVV_6.3_1

Запустим в коммандной строке gulp watch. Он запустится, но потом зависнет и будет чего-то ждать.

Поменяем в sass цвет еще раз, например опять на красный #f00 и обновим страницу. Все работает. Watch отследила изменения и перезапустила sass.
Чтобы остановить watch используйте сочетание клавиш Ctrl + C.

Но посмотрите, у нас в коде появилось дублирование, мы уже 2 раза записали адресс к файлам sass ./src/sass/**/*.scss.
Создадим в самом начале нашего gulpfile.js новую переменную и назовем ее config:

var config = {
    srcDir: './src',
    sassPattern: 'sass/**/*.scss'
};

В корне проекта у нас есть папка src, где мы храним все наши исходники, для нее мы создали переменную srcDir,
а для всех sass файлов мы указали sassPattern.

Теперь исползуем переменные config.srcDir+'/'+config.sassPattern в нашем коде.
Ну и чтобы все запускалось одной коммандой, добавим в default после массива sass массив watch

Весь наш код

var config = {
    srcDir: './src',
    sassPattern: 'sass/**/*.scss'
};

var gulp = require('gulp'),
    sass = require('gulp-sass'),
    sourcemaps = require('gulp-sourcemaps');

gulp.task('sass', function () {
    return gulp.src(config.srcDir+'/'+config.sassPattern)
    .pipe(sourcemaps.init())
    .pipe(sass().on('error', sass.logError))
    .pipe(sourcemaps.write('.'))
    .pipe(gulp.dest('./design/okay_shop/css'));
});

gulp.task('watch', function () {
    gulp.watch(config.srcDir+'/'+config.sassPattern, ['sass'])
});

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

Запустим gulp, чтобы удостовериться, что все прошло без ошибок.

Объединение CSS-файлов.
До сих пор мы работали только с одинм scss-файлом - style.scss. Но ведь у нас несколько файлов со стилями. Кроме того, для продакшен мы хотим объединить все стили в один файл.

Воспользуемся плагином gulp-concat https://github.com/contra/gulp-concat
Использовать его можно также и для js-файлов.

Установим его в наш проект. Ой, у нас работает watch, зажимаем Ctrl + C, вводим y и нажимаем Enter.

Вот теперь можно устанавливать:
npm install --save-dev gulp-concat

Пока NPM устанавливает файл, зайдем в gulpfile.gs и подключим плагин в секции require:

concat = require('gulp-concat');

Функция gulp.src()загружает потоки многих файлов, а наша новая функция concat()объединяет эти потоки в один файл. Вот такая она минималистка.
Давайте сразу после пайпа sass поставим пайп concat и укажем имя объединенного файла стилей, пусть это будет main.css:

.pipe(concat('main.css'))

gulpVV_9_2

Теперь удалим все файлы из папки css, вернее удалим пока только три, с которыми мы экспериментируем. Это style.css, responsive.css и libs.css. Ох как мне мешают сейчас файлы стилей для плагина соц.сетей. Но что поделать, не обращаем на них внимания. Надеюсь, к следующей версии мы что-нибудь придумаем с соц.сетями.

В index.tpl в секции head удалим пути к этим файлам и укажем название нового файла стилей main.css.

Перезапускаем gulp
Теперь у нас один файл стилей, в котором собраны стили с файлов style, responsive и libs. И карта для файла main.css.

Но возникла другая проблема  - плагин объединяет файлы по алфавиту, и получилось, что стили из responsive теперь оказались выше, чем стили из style. А это нарушает каскад и ломает верстку.
Чтобы решить эту проблему, в пути к источнику scss-файлов укажем названия файлов в массиве в нужном порядке, например:
gulp.src([config.srcDir+'/sass/libs.scss', config.srcDir+'/sass/style.scss', config.srcDir+'/sass/responsive.scss'])

Перезапустим gulp. Теперь все нормально.

Минификация CSS.

Установим плагин gulp-clean-css.
https://github.com/scniro/gulp-clean-css.

npm install gulp-clean-css --save-dev

Добавим переменнную в gulpfile.js

cleanCSS = require('gulp-clean-css')

И добавляем в задачу sass после пайпа concat строку

.pipe(cleanCSS())

Итоговый gulpfile.js:

var config = {
    srcDir: './src',
    sassPattern: 'sass/**/*.scss'
};

var gulp = require('gulp'),
    sass = require('gulp-sass'),
    sourcemaps = require('gulp-sourcemaps'),
    concat = require('gulp-concat'),
    cleanCSS = require('gulp-clean-css');

gulp.task('sass', function () {
    return gulp.src([config.srcDir+'/sass/libs.scss', config.srcDir+'/sass/style.scss', config.srcDir+'/sass/responsive.scss'])
    .pipe(sourcemaps.init())
    .pipe(sass().on('error', sass.logError))
    .pipe(concat('main.css'))
    .pipe(cleanCSS())
    .pipe(sourcemaps.write('.'))
    .pipe(gulp.dest('./design/okay_shop/css'));
});

gulp.task('watch', function () {
    gulp.watch(config.srcDir+'/'+config.sassPattern, ['sass'])
});

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

 Перезапускаем gulp - теперь наш файл main.css в одну строку, но благодаря sourcemaps, в инспекторе мы знаем нужный файл и нужную строку для правки кода.

 Удачи! Надеюсь, я не сильно вас запутала.

Использование Gulp. Часть 1 - Установка. Использование Gulp. Часть 3 - разные сборки для development и production.

Комментарии

Оставить комментарий