Настройка gulp для front-end разработки в PhpStorm
Что такое Gulp
Gulp — это сборщик проектов, который сам по себе ничего кроме организации потоков не умеет. Зато у него есть тьма плагинов, которые умеют все, что надо для front-end. Лично мне надо чтобы мои SCSS собирались в css, а JS минифицировались. Для компиляции css в PhpStorm можно использовать стандартный scss процессор, написанный на ruby, который отлично с этим справляется, но я стал замечать, что при наличии больше 5 scss, каждый из которых по 500-700 строк, в PhpStorm сборка занимает значительные 3-5 секунд, что для меня является долгим. А в одной из статей было сказано, что gulp-sass умеет это делать быстрее. Зерно сомнения посеяно, шило все глубже внедряется в мозг. В общем, на очередном проекте было принято волевое решение попробовать этот ваш Gulp.
Что нужно для front-end
Как я уже писал, мне надо не много:
- Компилировать css из SCSS
- Сжимать css
- Добавлять css.map
- Сжимать JS
- Добавлять префикс .min к сжатым js файлам
В идеале, надо будет добавить еще сжатие картинок, но я делаю это пока вручную.
Готовим Gulp
Для начале немого поговорим о том, как я организую структуру проекта:
Про стили чуть ниже. Для картинок я создаю 2 папки, те, который имеют отношение непосредственно к дизайну images/, и картинки, которые на этапе прикрутки будут заменены складываем в demoimg/, несжатые скрипты лежат в js/src/, а сжатые в корне js/. Стили мне нравится хранить в одной папке вместе с исходниками, ниже показано как это выглядит.
Не забывайте правильно настроить .gitignore, я надеюсь, что использование Git вошло в привычку, пусть даже кроме вас никто не будет использовать ваши файлы, но git это в первую очередь инструмент контроля версий, а уж потом средство совместной разработки. Мой .gitignore выглядит так:
# Исключим из репозитория папки с картинками .idea/ # Исключение .map файлов *.map *.json # gulp gulpfile.js node_modules
Чтобы работать с Gulp он должен быть у вас установлен, а для этого в свою очередь нужен NodeJS и NPM.
И так, для компиляции SCSS нужен пакет gulp-sass, но этот пакет не умеет генерировать.map, поэтому для его генерации нужен другой пакет gulp-sourcemaps. Для css этого достаточно. Теперь к минификации js. Нужно так же 2 пакета gulp-uglify — сжимает js, а чтобы у файлов появился префикс .min нужен пакет gulp-rename. В архиве пакетов Gulp есть и более эффективные модули, который в одну операцию умеют сжимать и добавлять префикс, но мне не понравилось, что он склеивает все js файлы в один, я хочу чтобы файлы оставались разделены. Для начала из корня проекта инициализируем проект
npm init
Внимательно или не очень следим за всеми пунктами и по необходимости заполняем их. Самое главное главный файл назовите gulpfile.js, установщик об этом спросит. Установка требуемых пакетов совершается одним движением
npm install --save-dev gulp gulp-sass gulp-sourcemaps gulp-uglify gulp-rename
Ключ —save-dev говорит что эти пакеты нужно только для пространства разработки и в продакш идти не должны. В корне проекта появился некий package.json, где указаны все пакеты с которыми мы имеем дело. Нафиг он нужен? Кроме того, что он несет служебную нагрузку, в перспективе я буду его таскать из проекта в проект и установку всех нужный пакетов производить одной командой
npm install
Главное чтобы npm видел этот файл. Он его прочтет и скачает нужные модули.
Собственно, что теперь со всем этим добром делать? Для начала создадим gulpfile.js где напишем слудующее:
'use strict'; var gulp = require('gulp'), sass = require('gulp-sass'), sourcemaps = require('gulp-sourcemaps'), uglify = require('gulp-uglify'), rename = require('gulp-rename');
Это просто подключение нужных пакетов. Можно открыть документацию к кажому пакету и детально изучить возможности. У меня для компиляции css используется такой код:
gulp.task('sass', function () { return gulp.src('./css/**/*.scss') // Для генераии style.css.map .pipe(sourcemaps.init()) // Собственно компиляция .pipe(sass({outputStyle: 'expanded'}).on('error', sass.logError)) // Куда положить .map .pipe(sourcemaps.write('./')) // Путь компиляции .pipe(gulp.dest('./css')); });
Для сжатия js
gulp.task('compressed-js', function () { gulp.src('js/src/*.js') .pipe(uglify()) .pipe(rename({suffix: '.min'})) .pipe(gulp.dest('js')); });
Задания можно запускать из консоли, но использую PhpStorm как-то это странно. Правой клавишей по gelpfile.js и выбираем пункт Show Gulp Tasks, откроется панель, где показаны доступные задачи
Можно даблкликом запустить любую. Но стоп! С js допустим ладно, периодически ткнуть — ок, но раньше css умел автоматически компилироваться, а теперь как?
Для автоматической компиляции у Gulp есть, так называемые вотчеры (watch). В документации они описаны, они следят за изменением файлов, и при каждом изменении могу запустить ту или иную задачу. Наш код примет следующий вид:
'use strict'; var gulp = require('gulp'), sass = require('gulp-sass'), sourcemaps = require('gulp-sourcemaps'), uglify = require('gulp-uglify'), rename = require('gulp-rename'); // SCSS compiled gulp.task('sass', function () { return gulp.src('./css/**/*.scss') // Для генераии style.css.map .pipe(sourcemaps.init()) // Собственно компиляция .pipe(sass({outputStyle: 'expanded'}).on('error', sass.logError)) // Куда положить .map .pipe(sourcemaps.write('./')) // Путь компиляции .pipe(gulp.dest('./css')); }); gulp.task('sass:watch', function () { gulp.watch('./css/**/*.scss', ['sass']); }); // JS COMPRESSED gulp.task('compressed-js', function () { gulp.src('js/src/*.js') .pipe(uglify()) .pipe(rename({suffix: '.min'})) .pipe(gulp.dest('js')); }); gulp.task('compressed-js:watch', function () { gulp.watch('./js/src/*.js', ['compressed-js']); });
А панель задач Gulp имеет такой вид
Можно запустить любой вотчер и он будет висеть в процессах, пока его явно не убьешь.
Но я пошел еще дальше и создал общий вотчер, который включает в себя и компиляцию css, и сжатие js, это делается всего одной строкой:
// Смотрим на все gulp.task('watch', ['sass:watch', 'compressed-js:watch']);
Теперь запускаем один вотчер и при любом изменении js или scss происходят все нужные манипуляции с файлами. Но, на сколько я понял, при добавлении новых файлов вотчер надо перезапускать, по крайней мере у меня он не захотел пережимать js, который был добавлен после запуска.
Конечно, ни что не мешает каждый раз запускать задачу вручную, но IDE предоставляет возможность автоматического запуска задания. Для этого идем в настройки Tool→Startup Tasks
В этом окне слева выбираем добавить новую задачу, и ищем Gulp
И в открывшемся окне добавляем наши вотчеры, хоть каждый по отдельности, хоть один общий.
Вот как бы вот так. Главное, если не настроили автоматический запуск вотчеров, не забывать запускать задачу при старте работы над проектом, а то ничего не получится. Но рекомендую переложить на IDE проблему автозапуска. Пока серьезного выигрыша по времени я не увидел, т.к. не было тяжелых проектов, но то, что вижу на небольших файлах, впечатляет. К тому же изучение новых технологи (пусть даже для одного взятого меня она новая), это всегда хорошо для разработчика, чтобы хоть как-то поспевать за изменяющимся миром.