Gulp не является. Gulp для самых маленьких - подробное руководство

Gulp не является. Gulp для самых маленьких - подробное руководство

Npm init

От вас потребуется:

  • Указать название проекта
  • Версию проекта
  • Описание проекта
  • Точку входа
  • Команду
  • Git репазиторий
  • Ключевые слова
  • Имя автора
  • Лицензия

Npm i –g gulp

  • Название задачи

Gulp test

Задача работает.

Gulp serve

Npm i gulp-sass --save-dev

  1. Компилирование sass в css
  2. Добавление префиксов
  3. Сохранение файла в src/css

Создание задачи в gulp

Вывод.

https://gulpjs.com/plugins/

Открываем терминал и переходим в папку с проектом. Первое, что нам необходимо сделать это инициализировать npm для этого выполняем команду:

Npm init

От вас потребуется:

  • Указать название проекта
  • Версию проекта
  • Описание проекта
  • Точку входа
  • Команду
  • Git репазиторий
  • Ключевые слова
  • Имя автора
  • Лицензия

Все можно оставить по умолчанию (если вы не хотите выкладывать проект в общий доступ)

Затем подтверждаем введенную информацию.

Отлично. NPM инициализировали. Теперь в корне появился файл packages.json – файл конфигурации менеджера пакетов.

Теперь мы можем установить gulp. Вначале надо установить его глобально, а затем для проекта. Для глобальной установки выполните следующую команду:

Npm i –g gulp

Теперь установим gulp для проекта:

Npm install --save-dev gulp

Все gulp для проекта установлен.

Давайте проверим. Создадим файл gulpfile.js и создадим в нем одну задачу test, которая будет выводить в консоль «Я работаю».

Var gulp = require("gulp"); gulp.task("test", function() { console.log("Я работаю"); });

Первое мы подключаем gulp, и второе мы вызываем функцию task у gulp, которая принимает два параметра:

  • Название задачи
  • Анонимная функция в которой описывается наша задача

Теперь в консоли выполните следующую команду

Gulp test

Задача работает.

Теперь давайте установим и подключим пакеты, которые помогают при верстке.

Browsersync, пакет который позволяет при изменении файлов обновлять страницу автоматически

Для установки в консоли выполняем следующую команду:

Npm i browser-sync --save-dev

Теперь давайте создадим задачу, которая будет запускать browser-sync и отслеживать изменения файлов.

Gulp.task("serve", ["sass"], function() { browserSync.init({ server: "src/" }); gulp.watch("src/css/*.css")on("change", browserSync.reload); gulp.watch("src/*.html").on("change", browserSync.reload); });

Задача называется serve. И browser-sync будет обновлять страницу браузера автоматически, если изменились файлы с расширением css (которые расположены в папке src/css) и с расширением html (которые расположены в папке src).

Для запуска данной задачи выполняем команду

Gulp serve

Для верстки я использую sass. Поэтому для компиляции из sass в css я использую пакет gulp-sass.

Установка и настройка gulp-sass

Для установки gulp-sass в консоли выполняем команду:

Npm i gulp-sass --save-dev

Теперь создадим задачу sass, которая будет компилировать sass в css. И изменим задачу serve, чтобы наш browser-sync отслеживал вместо css файлы sass.

Var gulp = require("gulp"); var browserSync = require("browser-sync").create(); var sass = require("gulp-sass"); gulp.task("serve", ["sass"], function() { browserSync.init({ server: "src/" }); gulp.watch("src/sass/*.sass", ["sass"]); gulp.watch("src/*.html").on("change", browserSync.reload); }); gulp.task("sass", function() { return gulp.src("src/sass/*.sass") .pipe(sass().on("error", sass.logError)) .pipe(gulp.dest("src/css")) .pipe(browserSync.stream()); });

Теперь при запуске задачи serve, будет запускаться задача sass.

Установка и настройка gulp-autoprefixer

Для установки gulp-autoprefixer выполним команду:

Npm i gulp-autoprefixer --save-dev

И добавим в задачу sass добавление префикса.

Var gulp = require("gulp"); var browserSync = require("browser-sync").create(); var sass = require("gulp-sass"); var autoprefixer = require("gulp-autoprefixer"); gulp.task("serve", ["sass"], function() { browserSync.init({ server: "src/" }); gulp.watch("src/sass/*.sass", ["sass"]); gulp.watch("src/*.html").on("change", browserSync.reload); }); gulp.task("sass", function() { return gulp.src("src/sass/*.sass") .pipe(sass().on("error", sass.logError)) .pipe(autoprefixer({ browsers: ["last 2 versions"], cascade: false })) .pipe(gulp.dest("src/css")) .pipe(browserSync.stream()); });

Теперь при запуске задачи sass у на с будет:

  1. Компилирование sass в css
  2. Добавление префиксов
  3. Сохранение файла в src/css

Следующий пакет объединяет все css файлы в один.

Установка и настройка contactCss

Для установки contactCss используем следующую команду:

Npm i gulp-concat-css --save-dev

И добавим выполнение данного пакета в задачу sass. (Будем все файлы css объединять в style.css)

Var gulp = require("gulp"); var browserSync = require("browser-sync").create(); var sass = require("gulp-sass"); var autoprefixer = require("gulp-autoprefixer"); var concatCss = require("gulp-concat-css"); gulp.task("serve", ["sass"], function() { browserSync.init({ server: "src/" }); gulp.watch("src/sass/*.sass", ["sass"]); gulp.watch("src/*.html").on("change", browserSync.reload); }); gulp.task("sass", function() { return gulp.src("src/sass/*.sass") .pipe(sass().on("error", sass.logError)) .pipe(autoprefixer({ browsers: ["last 2 versions"], cascade: false })) .pipe(concatCss("style.css")) .pipe(gulp.dest("src/css")) .pipe(browserSync.stream()); });

Отлично. Теперь добавим пакет, который переименовывает файлы. (Он нам понадобится, кода мы будем минимизировать css, и js файлы)

Установка и настройка gulp-rename

Для установки gulp-rename выполним следующую команду:

Npm i gulp-rename --save-dev

Пока данный пакет не будем добавлять ни в какие задачи.

Установка и настройка пакета для минимизации CSS файлов – clean-css

Для установки clean-css выполним следующую команду:

Npm i gulp-clean-css --save-dev

Теперь давайте создадим задачу mincss, которая будет добавлять к имени файла суффикс «.min», минимизировать css файл и сохранять в app/css

Var gulp = require("gulp"); var browserSync = require("browser-sync").create(); var sass = require("gulp-sass"); var autoprefixer = require("gulp-autoprefixer"); var concatCss = require("gulp-concat-css"); var cleanCSS = require("gulp-clean-css"); var rename = require("gulp-rename"); gulp.task("serve", ["sass"], function() { browserSync.init({ server: "src/" }); gulp.watch("src/sass/*.sass", ["sass"]); gulp.watch("src/*.html").on("change", browserSync.reload); }); gulp.task("sass", function() { return gulp.src("src/sass/*.sass") .pipe(sass().on("error", sass.logError)) .pipe(autoprefixer({ browsers: ["last 2 versions"], cascade: false })) .pipe(concatCss("style.css")) .pipe(gulp.dest("src/css")) .pipe(browserSync.stream()); }); gulp.task("mincss", function() { return gulp.src("src/css/*.css") .pipe(rename({suffix: ".min"})) .pipe(cleanCSS()) .pipe(gulp.dest("app/css")); })

Отлично, давайте установим gulp пакет, который будет минимизировать js файлы.

Установка и настройка пакета gulp для минимизации js файлов —gulp-uglify

Для установки gulp-uglify выполним следующую команду:

Npm i gulp-uglify --save-dev

Теперь создадим задачу, которая будет добавлять к файлу суффикс «.min», минимизировать файл js и сохранять в app/js

Var gulp = require("gulp"); var browserSync = require("browser-sync").create(); var sass = require("gulp-sass"); var autoprefixer = require("gulp-autoprefixer"); var concatCss = require("gulp-concat-css"); var cleanCSS = require("gulp-clean-css"); var rename = require("gulp-rename"); var uglify = require("gulp-uglify"); gulp.task("serve", ["sass"], function() { browserSync.init({ server: "src/" }); gulp.watch("src/sass/*.sass", ["sass"]); gulp.watch("src/*.html").on("change", browserSync.reload); }); gulp.task("sass", function() { return gulp.src("src/sass/*.sass") .pipe(sass().on("error", sass.logError)) .pipe(autoprefixer({ browsers: ["last 2 versions"], cascade: false })) .pipe(concatCss("style.css")) .pipe(gulp.dest("src/css")) .pipe(browserSync.stream()); }); gulp.task("mincss", function() { return gulp.src("src/css/*.css") .pipe(rename({suffix: ".min"})) .pipe(cleanCSS()) .pipe(gulp.dest("app/css")); }) gulp.task("minjs", function() { return gulp.src("src/js/*.js") .pipe(rename({suffix: ".min"})) .pipe(uglify()) .pipe(gulp.dest("app/js")); })

Мы создали основные задачи. Но две последние должны выполняться при выкладывании проекта в продакшен. И выполняться должны вместе. Давайте создадим задачу, которая будет выполнять задачу mincss, а потом minjs

Создание задачи в gulp

Создадим задачу min, которая будет запускать задачи mincss и minjs

Var gulp = require("gulp"); var browserSync = require("browser-sync").create(); var sass = require("gulp-sass"); var autoprefixer = require("gulp-autoprefixer"); var concatCss = require("gulp-concat-css"); var cleanCSS = require("gulp-clean-css"); var rename = require("gulp-rename"); var uglify = require("gulp-uglify"); gulp.task("serve", ["sass"], function() { browserSync.init({ server: "src/" }); gulp.watch("src/sass/*.sass", ["sass"]); gulp.watch("src/*.html").on("change", browserSync.reload); }); gulp.task("sass", function() { return gulp.src("src/sass/*.sass") .pipe(sass().on("error", sass.logError)) .pipe(autoprefixer({ browsers: ["last 2 versions"], cascade: false })) .pipe(concatCss("style.css")) .pipe(gulp.dest("src/css")) .pipe(browserSync.stream()); }); gulp.task("mincss", function() { return gulp.src("src/css/*.css") .pipe(rename({suffix: ".min"})) .pipe(cleanCSS()) .pipe(gulp.dest("app/css")); }) gulp.task("minjs", function() { return gulp.src("src/js/*.js") .pipe(rename({suffix: ".min"})) .pipe(uglify()) .pipe(gulp.dest("app/js")); }) gulp.task("min",["mincss", "minjs"]);

Все. Давайте еще зададим задачу по умолчанию.

Задание задачи по умолчанию gulp

gulp.task("default", ["serve"]);

Вывод.

Мы с вами рассмотрели для чего нужен gulp, как его установить. Установили дополнительные пакеты, которые необходимы для верстки и задали задачи.

Вы можете самостоятельно находить необходимые пакеты на сайте https://gulpjs.com/plugins/ и устанавливать их. А затем создавать задачи для оптимизации процесса разработки.

Всем привет, друзья! Сегодня мы подробно рассмотрим, что такое Gulp и как с его помощью можно автоматизировать работу Front-end разработчика. В результате урока мы соберем серьезное и внушительное рабочее Front-end окружение для веб-разработки с использованием Gulp.

Видео урок:

Класснуть

Запинить

  • Урок по обновлению Gulp до 4 версии: Ознакомиться с уроком Gulp 4
https://github.com/agragregra/gulp-lesson

Gulp - это инструмент, который помогает автоматизировать рутинные задачи веб-разработки. Gulp предназначен для решения таких задач, как:

  • Создание веб-сервера и автоматическая перезагрузка страницы в браузере при сохранении кода, слежение за изменениями в файлах проекта;
  • Использование различных JavaScript, CSS и HTML препроцессоров (CoffeeScript, Less, Sass, Stylus, Jade и т.д.);
  • Минификация CSS и JS кода, а также, оптимизация и конкатенация отдельных файлов проекта в один;
  • Автоматическое создание вендорных префиксов (приставок к названию CSS свойства, которые добавляют производители браузеров для нестандартных свойств) для CSS.
  • Управление файлами и папками в рамках проекта - создание, удаление, переименование;
  • Запуск и контроль выполнения внешних команд операционной системы;
  • Работа с изображениями - сжатие, создание спрайтов, ресайз (png, jpg, svg и др.);
  • Деплой (отправка на внешний сервер) проекта по FTP, SFTP, Git и т.д.
  • Подключение и использование в проекте безгранично большого количества Node.js и Gulp утилит, программ и плагинов.
  • Создание различных карт проекта и автоматизация другого ручного труда.

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

Любой проект, использующий Gulp имеет в корне файл gulpfile.js , который содержит набор инструкций по управлению проектом. Сразу хочется сказать, что написание инструкций для Gulp не является программированием, хотя пишутся на языке JavaScript. Не стоит пугаться больших gulpfile.js, в основном все инструкции однотипные и имеют общие черты. К тому времени, как вы прочтете данное руководство, у вас не должно остаться вопросов по Gulp, так как система сборки элементарная. Но если у вас останутся вопросы - обязательно пишите в комментариях.

Установка Gulp

Внимание! Если вы пользователь последней версии Windows, рекомендую использовать терминал Bash для веб-разработки. Скачивать инсталлятор с сайта Nodejs.org в этом случае не нужно. Воспользуйтесь этим руководством: .
Если у вас возникли проблемы при прохождении урока с использованием Gulp 4, рекомендую откатиться на 3 версию, пройти полностью урок и только после этого обновить package.json до 4 версии. Для лучшего понимания. Откатить версию можно в файле package.json. Вместо "gulp": "^4.x.x", напишите версию "^3.9.1", удалите папку "node_modules" и установите пакеты заново "npm i ".

Для работы с Gulp у вас должен быть установлен Node.js. Установка Node.js для различных платформ довольно простая - скачиваете инсталлер Node для своей операционной системы и устанавливаете. Я рекомендую устанавливать последнюю версию Stable. Для пользователей Linux и последней версии Windows я подготовил отдельное руководство по установке: Использование подсистемы Linux для веб-разработки в Windows 10 .

После того, как Node установлен, можно приступать к установке Gulp. Откройте терминал (правая кнопка мыши в папке с зажатым Shift > Откройте здесь оболочку Linux) и выполните следующую команду:

Npm i gulp -g

Для пользователей Mac и Linux и Ubuntu bash в Windows, глобальную установку с ключом -g необходимо выполнять с правами суперпользователя, sudo , например:
sudo npm i gulp -g .

Из данной команды мы видим, что запускается менеджер пакетов npm (Node Package Manager), который командой install устанавливает Gulp в систему. Ключ -g говорит о том, что пакет установится в систему глобально, то-есть в систему, а не в папку проекта. Без ключа -g пакет устанавливаются в ту папку, в которой выполняются текущие команды, поэтому будьте внимательны.

Создание проекта Gulp

Давайте создадим папку проекта для примера, с которой будем работать, пусть это будет, например, папка myproject .

Очень важно! Не создавайте русскоязычные папки проектов и следите за тем, чтобы путь до папки проекта не содержал кириллических символов, то-есть не был написан на русском языке. В противном случае, у вас могут возникнуть проблемы при работе различных утилит Gulp. Папка вашего пользователя также не должна быть русскоязычной. Всё только латинскими буквами.

Теперь откроем терминал в папке проекта. Для пользователей Windows достаточно зажать Shift и открыть контекстное меню. В нем появится пункт "Откройте здесь оболочку Linux". Оболочка Linux должна быть предварительно установлена, см урок: Использование подсистемы Linux для веб-разработки в Windows .

Npm init

Следуя инструкциям, заполним метаинформацию о нашем проекте:

В результате такой несложной первоначальной настройки нашего нового Gulp проекта в папке myproject нарисуется новый файл package.json .


Файл package.json является файлом манифеста нашего проекта, который описывает помимо той информации, что мы внесли в терминале, еще и информацию об используемых пакетах в нашем проекте.

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

Давайте установим в наш проект Gulp:

Npm i gulp --save-dev

Что мы видим из данной строки: npm устанавливает пакет gulp в текущую папку myproject (потому, что нет ключа -g, устанавливающий пакет глобально в систему) и сохраняет название пакета с версией в файл package.json:


Кроме того, у нас появляется папка node_modules , которая теперь содержит установленный пакет gulp и необходимые зависимости. В данную папку автоматически будут сваливаться все модули и зависимости, которые мы будем устанавливать в проект. Папок с зависимостями может быть очень много, не смотря на то, что мы установили не так уж и много пакетов. Это связано с тем, что в дополнение к основным пакетам устанавливаются программы, необходимые для корректной работы основного пакета. Ни чего чистить и удалять из папки node_modules не нужно. Кроме того, у вас может появиться дополнительный файл package-lock.json . В этом нет ничего страшного, это служебный файл, на который можно просто не обращать внимания.

Структура каталогов в проектах

Работая с различными плагинами, программами и скриптами, будь то jQuery плагин, модуль для CMS, веб-проект или какое-то другое ПО, вы наверняка замечали, что у всех проектов есть схожая структура каталогов, например, большинство проектов имеет папку dist и app . Давайте создадим первоначальную структуру нашего учебного проекта. В результате мы должны создать следующую структуру в нашем проекте myproject (все файлы, которых не было, пока создаем пустыми):

  • myproject/
    • app/
      • css/
      • fonts/
      • img/
      • js/
      • sass/
      • index.html
    • dist/
    • node_modules/
    • gulpfile.js
    • package.json
Данная структура встречается довольно часто, практически во всех проектах, но это не аксиома и некоторые проекты могут иметь вообще другую структуру. Для данной статьи мы будем использовать именно такую структуру проекта.

Здесь мы видим папку app/ , в которой будут размещены все исходные материалы проекта - оригинальные CSS, Sass, js файлы библиотек, оригинальные изображения. В общем - это папка исходников нашего проекта.

Папка dist/ будет содержать уже готовый продукт, оптимизированный, сжатый, причесанный. Это папка продакшена.

gulpfile.js

Теперь давайте откроем в редакторе кода gulpfile.js и напишем в него:

Var gulp = require("gulp");

Данной строчкой мы подключаем Gulp к нашему проекту, посредством функции require . Данная функция подключает пакеты из папки node_modules в наш проект, присваивая их переменной. В данном случае, мы создаем переменную gulp .

Gulp.task("mytask", function() { console.log("Привет, я таск!"); });

mytask - это название команды, которую вы будете вызывать в нужном вам месте gulpfile.js. Кроме того, можно в командной строке выполнить таск напрямую, написав:

Gulp mytask

gulpfile.js :


Результат выполнения команды gulp mytask :


Если вы используете Gulp 4 и у вас появляется ошибка о невозможности завершения таска, можно добавить async перед function() и выполнять код асинхронно: var gulp = require("gulp"); gulp.task("mytask", async function() { console.log("Привет, я таск!"); });

Это, конечно очень простой базовый пример создания таска. Как правило, таски несколько сложнее и включают некоторые дополнительные команды:

Gulp.task("mytask", function () { return gulp.src("source-files") // Выборка исходных файлов для обработки плагином.pipe(plugin()) // Вызов Gulp плагина для обработки файла.pipe(gulp.dest("folder")) // Вывод результирующего файла в папку назначения (dest - пункт назначения) })

  • gulp.src - выборка исходных файлов проекта для обработки плагином;
  • .pipe(plugin()) - вызов Gulp плагина для обработки файла;
  • .pipe(gulp.dest("folder")) - вывод результирующего файла в папку назначения (dest - пункт назначения).

Это база Gulp, теперь можно создавать инструкции. Для начала давайте создадим обработчик, который будет компилировать Sass файлы в CSS (CSS препроцессинг).

Gulp Sass

Давайте установим пакет gulp-sass в наш проект с сохранением версии и названия в package.json.

Обратите внимание, что любые Gulp пакеты, для любых задач, легко гуглятся и имеют вполне исчерпывающие инструкции по подключению на своих хоумпейджах и в документации.
npm i gulp-sass --save-dev

Var gulp = require("gulp"), sass = require("gulp-sass"); //Подключаем Sass пакет

Давайте создадим в папке app/sass файл main.sass , зададим в нем фон body - черный и напишем для него обработчик в gulpfile.js


gulpfile.js :

Var gulp = require("gulp"), // Подключаем Gulp sass = require("gulp-sass"); //Подключаем Sass пакет gulp.task("sass", function(){ // Создаем таск "sass" return gulp.src("app/sass/main.sass") // Берем источник.pipe(sass()) // Преобразуем Sass в CSS посредством gulp-sass .pipe(gulp.dest("app/css")) // Выгружаем результата в папку app/css });

После этого, логичным будет выполнить в терминале наш новый таск sass :

Gulp sass

В результате выполения данной команды в папке app/css появится файл main.css .


От таки чудеса, друзя. Как видим, все просто:-)

Выборка файлов для gulp.src

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

Выборка файлов в примере выше довольно простая, мы брали файл напрямую: gulp.src("app/sass/main.sass") . Но файлы также можно выбирать по шаблону. Шаблон выборки файлов называется glob - https://en.wikipedia.org/wiki/Glob_(programming) . Давайте познакомимся ближе со всеми возможностями выборки файлов для обработки.

Самые распространенные шаблоны выборки

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

Давайте внесем некоторые изменения в таск sass и сделаем его более универсальным:

Gulp.task("sass", function(){ return gulp.src("app/sass/**/*.sass") // Берем все sass файлы из папки sass и дочерних, если таковые будут.pipe(sass()) .pipe(gulp.dest("app/css")) });

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

Обратите внимание, что файлы sass, которые предназначены для импорта в другие файлы, как части одного общего, начинаются с нижнего подчеркивания _part-1.sass . Такие файлы не учавствуют в компиляции, как отдельные файлы, а добавляются через @import в основные файлы.

Наблюдение за изменениями в файлах (Gulp Watch)

Gulp поддерживает метод watch для проверки сохраняемых файлов и имеет следующий синтаксис:

Gulp.watch("watch-files", ["task1", "task2"]);

Если мы, например, хотим наблюдать за всеми изменениями в файлах sass нашего проекта, то можем использовать следующую конструкцию:

Gulp.watch("app/sass/**/*.sass", ["sass"]);

Что мы видим: Gulp наблюдает за всеми sass файлами и при сохранении выполняет таск sass, который автоматически компилирует их в css файлы.

Также, мы можем создать отдельный таск для наблюдения за всеми необходимыми файлами

Gulp.task("watch", function() { gulp.watch("app/sass/**/*.sass", ["sass"]); // Наблюдение за sass файлами // Наблюдение за другими типами файлов });

Для Gulp 4 код будет выглядеть так: gulp.task("watch", function() { gulp.watch("app/sass/**/*.sass", gulp.parallel("sass")); });

Если мы запустим в консоли gulp watch , то Gulp будет автоматически следить за всеми измененями в файлах sass при сохранении и компилировать их в css.

Было бы неплохо в дополнение к этой красоте сделать автоматическую перезагрузку страницы при изменениях в файлах. Для этой задачи нам подойдет Browser Sync .

Автоматическое обновление страниц с использованием Bbrowser Sync

Browser Sync - это отличное решение для LiveReload страниц при сохранении файлов. При чем релоад происходит не только в одном браузере, но и во всех браузерах сети, будь это мобильные устройства или другие компьютеры в одной Wi-Fi сети.

Мы уже умеем устанавливать дополнения для Gulp, поэтому давайте установим Browser Sync в наш проект:

Npm i browser-sync --save-dev

И, конечно-же, подключим в файле gulpfile.js, как мы это делали ранее с пакетом gulp-sass.

Var gulp = require("gulp"), // Подключаем Gulp sass = require("gulp-sass"), //Подключаем Sass пакет, browserSync = require("browser-sync"); // Подключаем Browser Sync

Создаем таск для Browser Sync:

Gulp.task("browser-sync", function() { // Создаем таск browser-sync browserSync({ // Выполняем browser Sync server: { // Определяем параметры сервера baseDir: "app" // Директория для сервера - app }, notify: false // Отключаем уведомления }); });

Отлично! Наш сервер для работы и автоматического релоада готов. Теперь давайте последим за изменениями в Sass. Если файл Sass обновляется, автоматически инжектим в HTML измененный CSS файл:

Gulp.task("sass", function(){ // Создаем таск Sass return gulp.src("app/sass/**/*.sass") // Берем источник.pipe(sass()) // Преобразуем Sass в CSS посредством gulp-sass .pipe(gulp.dest("app/css")) // Выгружаем результата в папку app/css .pipe(browserSync.reload({stream: true})) // Обновляем CSS на странице при изменении });

Все, что нам осталось сделать - это запустить таск browser-sync перед тем, как запустится gulp watch . Немного модифицируем таск watch , добавив выполнение browser-sync и sass до запуска watch :

Gulp.task("watch", ["sass", "browser-sync"], function() { gulp.watch("app/sass/**/*.sass", ["sass"]); // Наблюдение за sass файлами // Наблюдение за другими типами файлов });

Обратите внимание, что мы выполняем таски ["sass", "browser-sync"] до запуска watch , так как их выполнение необходимо нам для корректного отображения изменений на момент запуска сервера.
Для Gulp 4 логичнее было бы написать так и выполнять всю конструкцию в дефолтном таске: gulp.task("watch", function() { gulp.watch("app/sass/**/*.sass", gulp.parallel("sass")); }); gulp.task("default", gulp.parallel("sass", "browser-sync", "watch"));

Расположим таск watch после всех других тасков и в результате получим такой gulpfile.js для Gulp 3:

Var gulp = require("gulp"), // Подключаем Gulp sass = require("gulp-sass"), //Подключаем Sass пакет, browserSync = require("browser-sync"); // Подключаем Browser Sync gulp.task("sass", function(){ // Создаем таск Sass return gulp.src("app/sass/**/*.sass") // Берем источник.pipe(sass()) // Преобразуем Sass в CSS посредством gulp-sass .pipe(gulp.dest("app/css")) // Выгружаем результата в папку app/css .pipe(browserSync.reload({stream: true})) // Обновляем CSS на странице при изменении }); gulp.task("browser-sync", function() { // Создаем таск browser-sync browserSync({ // Выполняем browserSync server: { // Определяем параметры сервера baseDir: "app" // Директория для сервера - app }, notify: false // Отключаем уведомления }); }); gulp.task("watch", ["sass", "browser-sync"], function() { gulp.watch("app/sass/**/*.sass", ["sass"]); // Наблюдение за sass файлами // Наблюдение за другими типами файлов });

Такой код получится для Gulp 4:

Var gulp = require("gulp"), // Подключаем Gulp sass = require("gulp-sass"), //Подключаем Sass пакет, browserSync = require("browser-sync"); // Подключаем Browser Sync gulp.task("sass", function(){ // Создаем таск Sass return gulp.src("app/sass/**/*.sass") // Берем источник.pipe(sass()) // Преобразуем Sass в CSS посредством gulp-sass .pipe(gulp.dest("app/css")) // Выгружаем результата в папку app/css .pipe(browserSync.reload({stream: true})) // Обновляем CSS на странице при изменении }); gulp.task("browser-sync", function() { // Создаем таск browser-sync browserSync({ // Выполняем browserSync server: { // Определяем параметры сервера baseDir: "app" // Директория для сервера - app }, notify: false // Отключаем уведомления }); }); gulp.task("watch", function() { gulp.watch("app/sass/**/*.sass", gulp.parallel("sass")); // Наблюдение за sass файлами }); gulp.task("default", gulp.parallel("sass", "browser-sync", "watch"));

Для того, чтобы следить за изменениями в браузере, сделаем соответствующую разметку в файле index.html директории app с подключением файла стилей main.css :

Document

Выполним в терминале команду "gulp". Результат завораживает:


Давайте разберемся, что у нас происходит в консоли (картина может разниться, в зависимости от версии ПО):


После того, как мы нарадуемся результату, встает весьма ожидаемый вопрос - а как, собтвенно, обновлять страницу при сохранении HTML и JS?

И эта задача нам по плечу. Создайте в папке app/js файл common.js . Это основной пользовательский JS файл в нашем проекте. Модифицируем код:

Код для Gulp 3:

Gulp.task("watch", ["sass", "browser-sync"], function() { gulp.watch("app/sass/**/*.sass", ["sass"]); // Наблюдение за sass файлами в папке sass gulp.watch("app/*.html", browserSync.reload); // Наблюдение за HTML файлами в корне проекта gulp.watch(["app/js/common.js", "app/libs/**/*.js"], browserSync.reload); // Наблюдение за главным JS файлом и за библиотеками });

Код для Gulp 4 (здесь лучше добавить дополнительный таск для обработки HTML и JS):

Gulp.task("scripts", function() { return gulp.src(["app/js/common.js", "app/libs/**/*.js"]) .pipe(browserSync.reload({ stream: true })) }); gulp.task("code", function() { return gulp.src("app/*.html") .pipe(browserSync.reload({ stream: true })) }); gulp.task("watch", function() { gulp.watch("app/sass/**/*.sass", gulp.parallel("sass")); // Наблюдение за sass файлами gulp.watch("app/*.html", gulp.parallel("code")); // Наблюдение за HTML файлами в корне проекта gulp.watch(["app/js/common.js", "app/libs/**/*.js"], gulp.parallel("scripts")); // Наблюдение за главным JS файлом и за библиотеками }); gulp.task("default", gulp.parallel("sass", "browser-sync", "watch"));

Здесь мы используем функцию browserSync.reload, которую нам любезно предоставил пакет Browser Sync. Обратите внимание на выборку файлов для слежения.

В принципе, мы уже имеем довольно продвинутое рабочее окружение. Но двигаемся дальше, это не все, на что способен Gulp.

Оптимизация JavaScript

Давайте рассмотрим, как можно оптимизировать JS файлы проекта. Чаще всего, в оптимизации нуждаются библиотеки и сторонние jQuery и JavaScript плагины. Давайте создадим в папке app паку libs , которая будет содержать необходимые проекту библиотеки. Все библиотеки будем размещать в отдельных папках. Для установки новых библиотек я советую использовать Bower .

Установим Bower:

Npm i -g bower

Обратите внимание, что для работы Bower необходим установленный Git . Если в ОС Windows вы используте оболочку Ubuntu bash, то установку Git выполнять не нужно.

Теперь в папке проекта создадим файл .bowerrc , в который напишем:

{ "directory" : "app/libs/" }

Если вы пользователь ОС Windows, у вас не получится просто взять и создать файл, начинающийся с точки. В этом случае можно просто поставить точку в конце файла и нажать Enter: .bowerrc.

Данной настройкой мы указываем путь по умолчанию для установки плагинов с помощью Bower.

Установим jQuery и Magnific Popup, для примера:

Bower i jquery magnific-popup

Обратите внимание, что все (ну, или почти все) плагины имеют папку dist, об этом мы говорили ранее. В этой папке располагаются готовые файлы продакшена, которые мы и будем использовать в нашем проекте.

Давайте создадим таск scripts , который будет собирать все JS файлы библиотек в один и минифицировать файл. Для этого установим 2 пакета: gulp-concat и gulp-uglifyjs .

Npm i --save-dev gulp-concat gulp-uglifyjs

Подключим новые библиотеки в gulpfile.js:

Var gulp = require("gulp"), // Подключаем Gulp sass = require("gulp-sass"), //Подключаем Sass пакет, browserSync = require("browser-sync"), // Подключаем Browser Sync concat = require("gulp-concat"), // Подключаем gulp-concat (для конкатенации файлов) uglify = require("gulp-uglifyjs"); // Подключаем gulp-uglifyjs (для сжатия JS)

Создаем задачу для сборки и сжатия всех библиотек (перед watch):

Gulp.task("scripts", function() { return gulp.src([ // Берем все необходимые библиотеки "app/libs/jquery/dist/jquery.min.js", // Берем jQuery "app/libs/magnific-popup/dist/jquery.magnific-popup.min.js" // Берем Magnific Popup ]) .pipe(concat("libs.min.js")) // Собираем их в кучу в новом файле libs.min.js .pipe(uglify()) // Сжимаем JS файл.pipe(gulp.dest("app/js")); // Выгружаем в папку app/js });

Давайте проверим, как работает наш новый таск scripts , выполнив в терминале:


Выполнение таска scripts можно запустить перед выполнением watch. Gulp 3:


Для Gulp 4 код будет выглядеть следующим образом - добавим в параллельное выполнение таска scripts (некоторую структуру уже задали ранее): gulp.task("watch", function() { gulp.watch("app/sass/**/*.sass", gulp.parallel("sass")); // Наблюдение за sass файлами gulp.watch("app/*.html", gulp.parallel("code")); // Наблюдение за HTML файлами в корне проекта gulp.watch(["app/js/common.js", "app/libs/**/*.js"], gulp.parallel("scripts")); // Наблюдение за главным JS файлом и за библиотеками }); gulp.task("default", gulp.parallel("sass", "scripts", "browser-sync", "watch"));

Далее можно подключить к проекту все необходимые CSS файлы библиотек. В нашем случае, только одна библиотека нуждается в подключении - это Magnific Popup. Сделаем это через @import в Sass фале sass/libs.sass :

@import "app/libs/magnific-popup/dist/magnific-popup.css" // Импортируем библиотеку Magnific Popup

Внимание! В новых версиях gulp-sass для импорта CSS файлов в Sass необходимо указывать расширение.css и импортировать CSS файлы в SASS файлы с нижним подчёркиванием в начале названия. Например, для того, чтобы импортировать файл library-name.css, необходимо создать вспомогатальный SASS файл, например, _libs.sass, импортировать в него нужный CSS - @import "app/libs/library-name.css" и добавить вспомогательный _libs.sass в главный main.sass без указания нижнего подчёркивания и расширения, например, так: @import "libs"

На выходе, в папке app/css мы получаем дополнительно к main.css файл libs.css, который содержит стили всех библиотек. Файл main.css нет особого смысла минифицировать, так как он содержит кастомные (пользовательские) стили. А вот файл libs.css мы с удовольствием минифицируем.

Внимание! Если в файле libs.css не появляется кода библиотек, а вы по-прежнему видите в нём конструкции @import, создайте отдельный файл _libs.sass для библиотек, который начинался бы с нижнего подчёркивания . Затем импортируйте этот файл в главный, тем самым объеденив и библиотеки и пользовательские стили в один файл.

Для минификации CSS установим пакеты gulp-cssnano и gulp-rename :

Npm i gulp-cssnano gulp-rename --save-dev

И подключим их в нашем gulpfile.js:

Var gulp = require("gulp"), // Подключаем Gulp sass = require("gulp-sass"), //Подключаем Sass пакет, browserSync = require("browser-sync"), // Подключаем Browser Sync concat = require("gulp-concat"), // Подключаем gulp-concat (для конкатенации файлов) uglify = require("gulp-uglifyjs"), // Подключаем gulp-uglifyjs (для сжатия JS) cssnano = require("gulp-cssnano"), // Подключаем пакет для минификации CSS rename = require("gulp-rename"); // Подключаем библиотеку для переименования файлов

И создадим соответствующий таск css-libs . Сразу добавим данный таск в watch для того, чтобы библиотеки собирались в процессе запуска проекта. Таск sass лучше вызвать до запуска css-libs, чтобы нам было что минифицировать:

Gulp.task("css-libs", ["sass"], function() { return gulp.src("app/sass/libs.sass") // Выбираем файл для минификации.pipe(sass()) // Преобразуем Sass в CSS посредством gulp-sass .pipe(cssnano()) // Сжимаем.pipe(rename({suffix: ".min"})) // Добавляем суффикс.min .pipe(gulp.dest("app/css")); // Выгружаем в папку app/css }); gulp.task("watch", ["browser-sync", "css-libs", "scripts"], function() { gulp.watch("app/sass/**/*.sass", ["sass"]); // Наблюдение за sass файлами в папке sass gulp.watch("app/*.html", browserSync.reload); // Наблюдение за HTML файлами в корне проекта gulp.watch(["app/js/common.js", "app/libs/**/*.js"], browserSync.reload); // Наблюдение за главным JS файлом и за библиотеками });

Код для Gulp 4:

Gulp.task("css-libs", function() { return gulp.src("app/sass/libs.sass") // Выбираем файл для минификации.pipe(sass()) // Преобразуем Sass в CSS посредством gulp-sass .pipe(cssnano()) // Сжимаем.pipe(rename({suffix: ".min"})) // Добавляем суффикс.min .pipe(gulp.dest("app/css")); // Выгружаем в папку app/css }); gulp.task("watch", function() { gulp.watch("app/sass/**/*.sass", gulp.parallel("sass")); // Наблюдение за sass файлами gulp.watch("app/*.html", gulp.parallel("code")); // Наблюдение за HTML файлами в корне проекта gulp.watch(["app/js/common.js", "app/libs/**/*.js"], gulp.parallel("scripts")); // Наблюдение за главным JS файлом и за библиотеками }); gulp.task("default", gulp.parallel("css-libs", "sass", "scripts", "browser-sync", "watch"));

Подготовка к продакшену

Результирующий код для Gulp 4 будет представлен в конце статьи.

Для продакшена (сборки в папку dist) мы создадим отдельный таск build в конце gulpfile.js. В данной инструкции мы осуществим сборку Sass, JS и выгрузку того, что у нас готово в папку dist.

Gulp.task("build", ["sass", "scripts"], function() { var buildCss = gulp.src([ // Переносим CSS стили в продакшен "app/css/main.css", "app/css/libs.min.css" ]) .pipe(gulp.dest("dist/css")) var buildFonts = gulp.src("app/fonts/**/*") // Переносим шрифты в продакшен.pipe(gulp.dest("dist/fonts")) var buildJs = gulp.src("app/js/**/*") // Переносим скрипты в продакшен.pipe(gulp.dest("dist/js")) var buildHtml = gulp.src("app/*.html") // Переносим HTML в продакшен.pipe(gulp.dest("dist")); });

Здесь, присваивая переменным какие-либо действия, мы их выполняем. Таким образом можно выполнять мультизадачные таски. Можно и не присваивать, но мы сделаем так, ибо красивше.

Все прекрасно, но всегда есть одно "Но". Перед тем, как собирать проект нам желательно бы очистить папку dist, чтобы не оставалось лишних потрохов от предыдущих итераций с нашим проектом.

Установим и подключим пакет del:

Npm i del --save-dev var gulp = require("gulp"), // Подключаем Gulp sass = require("gulp-sass"), //Подключаем Sass пакет, browserSync = require("browser-sync"), // Подключаем Browser Sync concat = require("gulp-concat"), // Подключаем gulp-concat (для конкатенации файлов) uglify = require("gulp-uglifyjs"), // Подключаем gulp-uglifyjs (для сжатия JS) cssnano = require("gulp-cssnano"), // Подключаем пакет для минификации CSS rename = require("gulp-rename"), // Подключаем библиотеку для переименования файлов del = require("del"); // Подключаем библиотеку для удаления файлов и папок

Создаем таск очистки clean и добавляем его выполнение перед выполнение build:

Gulp.task("clean", function() { return del.sync("dist"); // Удаляем папку dist перед сборкой }); gulp.task("build", ["clean", "sass", "scripts"], function() { var buildCss = gulp.src([ // Переносим библиотеки в продакшен "app/css/main.css", "app/css/libs.min.css" ]) .pipe(gulp.dest("dist/css")) var buildFonts = gulp.src("app/fonts/**/*") // Переносим шрифты в продакшен.pipe(gulp.dest("dist/fonts")) var buildJs = gulp.src("app/js/**/*") // Переносим скрипты в продакшен.pipe(gulp.dest("dist/js")) var buildHtml = gulp.src("app/*.html") // Переносим HTML в продакшен.pipe(gulp.dest("dist")); });

Для Gulp 4 попробуйте составить таски самостоятельно, как мы это делали в предыдущих прмерах.

Оптимизация изображений

Как вы могли заметить, в нашем проекте на продакшене не хватает изображений. Давайте исправим это недоразумение и добавим обработку изображений в наш проект. Данный раздел выполнен с использованием Gulp 3. Код для Gulp 4 можно адаптировать самостоятельно, как мы это делали ранее.

В папке app/img есть 3 изображения, которые нам необходимо перенести в папку продакшена, оптимизируя.


Для оптимизации изображений установим 2 пакета (gulp-imagemin , imagemin-pngquant ) и подключим их:

Npm i gulp-imagemin imagemin-pngquant --save-dev var gulp = require("gulp"), // Подключаем Gulp sass = require("gulp-sass"), //Подключаем Sass пакет, browserSync = require("browser-sync"), // Подключаем Browser Sync concat = require("gulp-concat"), // Подключаем gulp-concat (для конкатенации файлов) uglify = require("gulp-uglifyjs"), // Подключаем gulp-uglifyjs (для сжатия JS) cssnano = require("gulp-cssnano"), // Подключаем пакет для минификации CSS rename = require("gulp-rename"), // Подключаем библиотеку для переименования файлов del = require("del"), // Подключаем библиотеку для удаления файлов и папок imagemin = require("gulp-imagemin"), // Подключаем библиотеку для работы с изображениями pngquant = require("imagemin-pngquant"); // Подключаем библиотеку для работы с png

Gulp.task("img", function() { return gulp.src("app/img/**/*") // Берем все изображения из app .pipe(imagemin({ // Сжимаем их с наилучшими настройками interlaced: true, progressive: true, svgoPlugins: [{removeViewBox: false}], use: })) .pipe(gulp.dest("dist/img")); // Выгружаем на продакшен }); gulp.task("build", ["clean", "img", "sass", "scripts"], function() { var buildCss = gulp.src([ // Переносим библиотеки в продакшен "app/css/main.css", "app/css/libs.min.css" ]) .pipe(gulp.dest("dist/css")) var buildFonts = gulp.src("app/fonts/**/*") // Переносим шрифты в продакшен.pipe(gulp.dest("dist/fonts")) var buildJs = gulp.src("app/js/**/*") // Переносим скрипты в продакшен.pipe(gulp.dest("dist/js")) var buildHtml = gulp.src("app/*.html") // Переносим HTML в продакшен.pipe(gulp.dest("dist")); });

Все прекрасно. До тех пор, пока количество изображений в проекте не превышает 3 шт. Большое количество картинок будет обрабатываться значительно дольше, поэтому к обработке изображений было бы неплохо добавить кеш, чтобы картинки кешировались, экономя наше время.

Установи м подключим gulp-cache :

Npm i gulp-cache --save-dev var gulp = require("gulp"), // Подключаем Gulp sass = require("gulp-sass"), //Подключаем Sass пакет, browserSync = require("browser-sync"), // Подключаем Browser Sync concat = require("gulp-concat"), // Подключаем gulp-concat (для конкатенации файлов) uglify = require("gulp-uglifyjs"), // Подключаем gulp-uglifyjs (для сжатия JS) cssnano = require("gulp-cssnano"), // Подключаем пакет для минификации CSS rename = require("gulp-rename"), // Подключаем библиотеку для переименования файлов del = require("del"), // Подключаем библиотеку для удаления файлов и папок imagemin = require("gulp-imagemin"), // Подключаем библиотеку для работы с изображениями pngquant = require("imagemin-pngquant"), // Подключаем библиотеку для работы с png cache = require("gulp-cache"); // Подключаем библиотеку кеширования

Модифицируем таск img :

Gulp.task("img", function() { return gulp.src("app/img/**/*") // Берем все изображения из app .pipe(cache(imagemin({ // Сжимаем их с наилучшими настройками с учетом кеширования interlaced: true, progressive: true, svgoPlugins: [{removeViewBox: false}], use: }))) .pipe(gulp.dest("dist/img")); // Выгружаем на продакшен });

Автоматическое создание префиксов CSS с помощью Gulp

Вендорные префиксы необходимы для обеспечения максимальной совместимости со всеми современными браузерами. Было бы логично сделать автоматическое добавление префиксов, чтобы написав в CSS или Sass:

Display: flex

Мы получили на выходе:

Display: -webkit-flex; display: -moz-flex; display: -ms-flex; display: -o-flex; display: flex;

Установим пакет gulp-autoprefixer и подключим его в gulpfile.js:

Npm i --save-dev gulp-autoprefixer var gulp = require("gulp"), // Подключаем Gulp sass = require("gulp-sass"), //Подключаем Sass пакет, browserSync = require("browser-sync"), // Подключаем Browser Sync concat = require("gulp-concat"), // Подключаем gulp-concat (для конкатенации файлов) uglify = require("gulp-uglifyjs"), // Подключаем gulp-uglifyjs (для сжатия JS) cssnano = require("gulp-cssnano"), // Подключаем пакет для минификации CSS rename = require("gulp-rename"), // Подключаем библиотеку для переименования файлов del = require("del"), // Подключаем библиотеку для удаления файлов и папок imagemin = require("gulp-imagemin"), // Подключаем библиотеку для работы с изображениями pngquant = require("imagemin-pngquant"), // Подключаем библиотеку для работы с png cache = require("gulp-cache"), // Подключаем библиотеку кеширования autoprefixer = require("gulp-autoprefixer");// Подключаем библиотеку для автоматического добавления префиксов

И модифицируем наш таск sass :

Gulp.task("sass", function(){ // Создаем таск Sass return gulp.src("app/sass/**/*.sass") // Берем источник.pipe(sass()) // Преобразуем Sass в CSS посредством gulp-sass .pipe(autoprefixer(["last 15 versions", "> 1%", "ie 8", "ie 7"], { cascade: true })) // Создаем префиксы.pipe(gulp.dest("app/css")) // Выгружаем результата в папку app/css .pipe(browserSync.reload({stream: true})) // Обновляем CSS на странице при изменении });

Дефолтный таск Gulp

Внимание! Дефолтный таск для Gulp 4 отличается от приведённого в этой главе. Полный код для Gulp 4 можно будет посмотреть в конце статьи.

Итак, мы имеем 2 главных таска - gulp watch - для работы над проектом в режиме "онлайн" и gulp build - для сборки проекта на продакшен без лишних файлов, папок и со сжатыми картинками. Так как чаще всего нам нужен будет таск watch , можно повесить его на дефолтный таск, чтобы не писать в консоли постоянно gulp watch, а писать просто gulp .

Gulp.task("default", ["watch"]);

Также, необходимо создать автономный таск для очистки кеша Gulp, чтобы его можно было вызывать простой командой gulp clear :

Gulp.task("clear", function () { return cache.clearAll(); })

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

В результате, у нас должен получиться такой gulpfile.js . Gulp 3:

Var gulp = require("gulp"), // Подключаем Gulp sass = require("gulp-sass"), //Подключаем Sass пакет, browserSync = require("browser-sync"), // Подключаем Browser Sync concat = require("gulp-concat"), // Подключаем gulp-concat (для конкатенации файлов) uglify = require("gulp-uglifyjs"), // Подключаем gulp-uglifyjs (для сжатия JS) cssnano = require("gulp-cssnano"), // Подключаем пакет для минификации CSS rename = require("gulp-rename"), // Подключаем библиотеку для переименования файлов del = require("del"), // Подключаем библиотеку для удаления файлов и папок imagemin = require("gulp-imagemin"), // Подключаем библиотеку для работы с изображениями pngquant = require("imagemin-pngquant"), // Подключаем библиотеку для работы с png cache = require("gulp-cache"), // Подключаем библиотеку кеширования autoprefixer = require("gulp-autoprefixer");// Подключаем библиотеку для автоматического добавления префиксов gulp.task("sass", function(){ // Создаем таск Sass return gulp.src("app/sass/**/*.sass") // Берем источник.pipe(sass()) // Преобразуем Sass в CSS посредством gulp-sass .pipe(autoprefixer(["last 15 versions", "> 1%", "ie 8", "ie 7"], { cascade: true })) // Создаем префиксы.pipe(gulp.dest("app/css")) // Выгружаем результата в папку app/css .pipe(browserSync.reload({stream: true})) // Обновляем CSS на странице при изменении }); gulp.task("browser-sync", function() { // Создаем таск browser-sync browserSync({ // Выполняем browserSync server: { // Определяем параметры сервера baseDir: "app" // Директория для сервера - app }, notify: false // Отключаем уведомления }); }); gulp.task("scripts", function() { return gulp.src([ // Берем все необходимые библиотеки "app/libs/jquery/dist/jquery.min.js", // Берем jQuery "app/libs/magnific-popup/dist/jquery.magnific-popup.min.js" // Берем Magnific Popup ]) .pipe(concat("libs.min.js")) // Собираем их в кучу в новом файле libs.min.js .pipe(uglify()) // Сжимаем JS файл.pipe(gulp.dest("app/js")); // Выгружаем в папку app/js }); gulp.task("css-libs", ["sass"], function() { return gulp.src("app/css/libs.sass") // Выбираем файл для минификации.pipe(sass()) // Преобразуем Sass в CSS посредством gulp-sass .pipe(cssnano()) // Сжимаем.pipe(rename({suffix: ".min"})) // Добавляем суффикс.min .pipe(gulp.dest("app/css")); // Выгружаем в папку app/css }); gulp.task("clean", function() { return del.sync("dist"); // Удаляем папку dist перед сборкой }); gulp.task("img", function() { return gulp.src("app/img/**/*") // Берем все изображения из app .pipe(cache(imagemin({ // С кешированием // .pipe(imagemin({ // Сжимаем изображения без кеширования interlaced: true, progressive: true, svgoPlugins: [{removeViewBox: false}], use: }))/**/) .pipe(gulp.dest("dist/img")); // Выгружаем на продакшен }); gulp.task("build", ["clean", "img", "sass", "scripts"], function() { var buildCss = gulp.src([ // Переносим библиотеки в продакшен "app/css/main.css", "app/css/libs.min.css" ]) .pipe(gulp.dest("dist/css")) var buildFonts = gulp.src("app/fonts/**/*") // Переносим шрифты в продакшен.pipe(gulp.dest("dist/fonts")) var buildJs = gulp.src("app/js/**/*") // Переносим скрипты в продакшен.pipe(gulp.dest("dist/js")) var buildHtml = gulp.src("app/*.html") // Переносим HTML в продакшен.pipe(gulp.dest("dist")); }); gulp.task("clear", function (callback) { return cache.clearAll(); }); gulp.task("watch", ["browser-sync", "css-libs", "scripts"], function() { gulp.watch("app/sass/**/*.sass", ["sass"]); // Наблюдение за sass файлами в папке sass gulp.watch("app/*.html", browserSync.reload); // Наблюдение за HTML файлами в корне проекта gulp.watch(["app/js/common.js", "app/libs/**/*.js"], browserSync.reload); // Наблюдение за JS файлами в папке js }); gulp.task("default", ["watch"]);

Результирующий код для Gulp 4:

Var gulp = require("gulp"), // Подключаем Gulp sass = require("gulp-sass"), //Подключаем Sass пакет, browserSync = require("browser-sync"), // Подключаем Browser Sync concat = require("gulp-concat"), // Подключаем gulp-concat (для конкатенации файлов) uglify = require("gulp-uglifyjs"), // Подключаем gulp-uglifyjs (для сжатия JS) cssnano = require("gulp-cssnano"), // Подключаем пакет для минификации CSS rename = require("gulp-rename"), // Подключаем библиотеку для переименования файлов del = require("del"), // Подключаем библиотеку для удаления файлов и папок imagemin = require("gulp-imagemin"), // Подключаем библиотеку для работы с изображениями pngquant = require("imagemin-pngquant"), // Подключаем библиотеку для работы с png cache = require("gulp-cache"), // Подключаем библиотеку кеширования autoprefixer = require("gulp-autoprefixer");// Подключаем библиотеку для автоматического добавления префиксов gulp.task("sass", function() { // Создаем таск Sass return gulp.src("app/sass/**/*.sass") // Берем источник.pipe(sass()) // Преобразуем Sass в CSS посредством gulp-sass .pipe(autoprefixer(["last 15 versions", "> 1%", "ie 8", "ie 7"], { cascade: true })) // Создаем префиксы.pipe(gulp.dest("app/css")) // Выгружаем результата в папку app/css .pipe(browserSync.reload({stream: true})) // Обновляем CSS на странице при изменении }); gulp.task("browser-sync", function() { // Создаем таск browser-sync browserSync({ // Выполняем browserSync server: { // Определяем параметры сервера baseDir: "app" // Директория для сервера - app }, notify: false // Отключаем уведомления }); }); gulp.task("scripts", function() { return gulp.src([ // Берем все необходимые библиотеки "app/libs/jquery/dist/jquery.min.js", // Берем jQuery "app/libs/magnific-popup/dist/jquery.magnific-popup.min.js" // Берем Magnific Popup ]) .pipe(concat("libs.min.js")) // Собираем их в кучу в новом файле libs.min.js .pipe(uglify()) // Сжимаем JS файл.pipe(gulp.dest("app/js")); // Выгружаем в папку app/js }); gulp.task("code", function() { return gulp.src("app/*.html") .pipe(browserSync.reload({ stream: true })) }); gulp.task("css-libs", function() { return gulp.src("app/css/libs.sass") // Выбираем файл для минификации.pipe(sass()) // Преобразуем Sass в CSS посредством gulp-sass .pipe(cssnano()) // Сжимаем.pipe(rename({suffix: ".min"})) // Добавляем суффикс.min .pipe(gulp.dest("app/css")); // Выгружаем в папку app/css }); gulp.task("clean", async function() { return del.sync("dist"); // Удаляем папку dist перед сборкой }); gulp.task("img", function() { return gulp.src("app/img/**/*") // Берем все изображения из app .pipe(cache(imagemin({ // С кешированием // .pipe(imagemin({ // Сжимаем изображения без кеширования interlaced: true, progressive: true, svgoPlugins: [{removeViewBox: false}], use: }))/**/) .pipe(gulp.dest("dist/img")); // Выгружаем на продакшен }); gulp.task("prebuild", async function() { var buildCss = gulp.src([ // Переносим библиотеки в продакшен "app/css/main.css", "app/css/libs.min.css" ]) .pipe(gulp.dest("dist/css")) var buildFonts = gulp.src("app/fonts/**/*") // Переносим шрифты в продакшен.pipe(gulp.dest("dist/fonts")) var buildJs = gulp.src("app/js/**/*") // Переносим скрипты в продакшен.pipe(gulp.dest("dist/js")) var buildHtml = gulp.src("app/*.html") // Переносим HTML в продакшен.pipe(gulp.dest("dist")); }); gulp.task("clear", function (callback) { return cache.clearAll(); }) gulp.task("watch", function() { gulp.watch("app/sass/**/*.sass", gulp.parallel("sass")); // Наблюдение за sass файлами gulp.watch("app/*.html", gulp.parallel("code")); // Наблюдение за HTML файлами в корне проекта gulp.watch(["app/js/common.js", "app/libs/**/*.js"], gulp.parallel("scripts")); // Наблюдение за главным JS файлом и за библиотеками }); gulp.task("default", gulp.parallel("css-libs", "sass", "scripts", "browser-sync", "watch")); gulp.task("build", gulp.parallel("prebuild", "clean", "img", "sass", "scripts"));

Проект-пример из данного урока вы можете посмотреть на GitHub и скачать: https://github.com/agragregra/gulp-lesson

Чтобы установить все пакеты и зависимости для скачанного примера, выполните команду npm i в папке проекта.

Помните - к любому плагину для Gulp есть хорошая документация по подключению и использованию на npmjs.com или на страничке GitHub.

13 декабря 2017 в 17:40

Понимаем и работаем с gulp

  • JavaScript

Всем привет. Если вы связаны хоть как-то с JS, вы наверняка слышали о таком приложении как gulp . А возможно даже и использовали. По своему опыту могу сказать, что «въехать» в то, как с ним работать бывает сложно, хотя ключ к пониманию лежит на поверхности. Поэтому и публикую этот материал, надеясь, что он станет полезным.

Так же, на основе данного материала был снят видеоролик, так что можете выбирать, в каком виде потреблять.


Если сравнить gulp с другими популярными системами сборки, то это как сравнивать готовый квадрокоптер по типу “купил и полетел”, и набор для самостоятельной сборки дрона. Да, взлетите вы только на следующий день, но зато у ваших руках больше гибкости и контроля, особенно если у вас нестандартная задача.

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

Зайдем издалека. В экосистеме nodejs, существует такое понятие, как потоки , или stream. Из-за сложности перевода, потоками так же называются нити или threads многопоточной программы. В нашем же случае, поток - это объект, представляющий потоковые данные, и является совершенно иным понятием.

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

Const fs = require("fs"); const input = fs.createReadStream("myfile"); input.on("data", (chunk) => { console.log(chunk); }); input.on("end", () => { console.log("file is read"); });
Потоками в nodejs может быть практически все, начиная от файлов или строк заканчивая сокетами. Например, в известном фреймворке Express, HTTP запрос и ответ являются ни чем иным, как потоками. Потоки могут быть только на чтение, только на запись или и то и другое.

Есть у потоков одна полезная функция: их можно складывать между собой у цепочку, которая называется pipe. Таким образом, мы можем объединить несколько потоков между собой, и управлять им как одним целым. Выход одного потока идет на вход следующему и так до конца. Как можно догадаться из перевода слова pipe, это очень похоже на трубопровод.

Это позволяет определить нужный поток данных (опять сложность перевода. Здесь имеется в виду flow, или течение) прямо здесь и сейчас не дожидаясь, когда данные станут доступны.

Например, вот так вот мы можем определить, что мы хотим отдать как результат, а “как” отдавать уже занимается сам движок.

Const fs = require("fs"); const express = require("express"); var app = express(); app.get("/", function (req, res) { fs.createReadStream("myfile") .pipe(res); }); app.listen(3000);
Обратите внимание, что обработчик запроса завершается до того, как файл даже откроется - остальное берет на себя движок ноды.

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

Если вы когда-нибудь слышали о vinyl - это как раз и есть реализация потоков, которые используют в gulp. Если мы возьмем стандартную задачу для галпа, и посмотрим что там внутри, то обнаружим, что на каждый вызов события data к нам приходит объект file, который и содержит всю необходимую информацию: имя файла, путь к файлу, рабочая директория и конечно же, его содержимое.

Const gulp = require("gulp"); gulp.task("default", function() { gulp.src("./*.js") .on("data", function(file) { console.log("data callback"); console.log(file.inspect()); /* It outputs: * data callback * > * data callback * > */ }) .pipe(gulp.dest("dist/")); });
Содержимое может быть представлено в двух форматах: в виде уже прочитанного буфера, или же в виде родного нодовского потока. Каждая ступень галповского пайпа берет на вход такие вот файлы, делает некую трансформацию и передает на выход следующей цепочке. Последняя цепочка обычно просто сохраняет их на диск.

Pipe(gulp.dest("dist/"));
Осознание факта того, что потоки в gulp другие ведет к просветлению и пониманию, поскольку это объясняет большинство проблем и ошибок.

Рассмотрим реальный пример. Вы хотите использовать browserify для склейки ваших JS файлов. Вы идете, и находите плагин gulp-browserify . Но видите приписку, которая говорит, что плагин deprecated, т.е. Устарел.

Как хорошо воспитанный программист вы отметаете этот вариант, и идете искать, а какое же решение не устарело. Находите официальные рецепты от gulp, и видите , что browserify работает с галпом напрямую. Ну как напрямую, через прослойку , которая как раз и переводит родной нодовский поток в виниловский поток, который понимает gulp. Без него ничего бы не заработало, поскольку это разные потоки.

Если вы хотите написать свою трансформацию, то можете использовать данный шаблон .
Как видим, здесь все просто: на каждый файл будет вызываться наш обработчик, который и выполнит модификации. Мы можем делать все что захотим: изменить содержимое файла, переименовать файл, удалить файл или добавить еще пару новых файлов в поток.

Как мы помним, содержимое файла в виниловском потоке может быть представлено в виде буфера или в виде потока данных. Однако не обязательно поддерживать и то другое. Всегда можно использовать пакет

13 января 2014 в 13:42

GulpJS - фантастически быстрый сборщик проектов

  • Разработка веб-сайтов ,
  • JavaScript ,
  • Node.JS

В этой статье будет больше практики, мы соберем среду разработки фронтенда используя Jade и Stylus, запустим локальный сервер и подключим Livereload. Проект я выложил на Github , экспериментируйте.

Установка Gulp
У вас должен быть установлен Node.JS и npm.
Создадим директорию проекта, создадим структуру каталогов и установим Gulp и необходимые плагины.
Струтура проекта:
|--/assets // Компоненты |--|--/template |--|--/stylus |--|--/js |--|--/img |--/build // Каталог релиза |--/public // Каталог разработки |--package.json |--gulpfile.js
Установка:
$ mkdir assets public build assets/js assets/img assets/stylus assets/template $ touch gulpfile.js $ sudo npm install gulp -g $ npm init $ npm install gulp gulp-jade gulp-stylus gulp-livereload gulp-myth gulp-csso gulp-imagemin gulp-uglify gulp-concat connect --save-dev

В корне проекта есть файл конфигурации gulpfile.js его и будем редактировать.

Иницилизируем плагины:
var lr = require("tiny-lr"), // Минивебсервер для livereload gulp = require("gulp"), // Сообственно Gulp JS jade = require("gulp-jade"), // Плагин для Jade stylus = require("gulp-stylus"), // Плагин для Stylus livereload = require("gulp-livereload"), // Livereload для Gulp myth = require("gulp-myth"), // Плагин для Myth - http://www.myth.io/ csso = require("gulp-csso"), // Минификация CSS imagemin = require("gulp-imagemin"), // Минификация изображений uglify = require("gulp-uglify"), // Минификация JS concat = require("gulp-concat"), // Склейка файлов connect = require("connect"), // Webserver server = lr();
Задачи:
Теперь создадим первую задачу
// Собираем Stylus gulp.task("stylus", function() { gulp.src("./assets/stylus/screen.styl") .pipe(stylus({ use: ["nib"] })) // собираем stylus .on("error", console.log) // Если есть ошибки, выводим и продолжаем.pipe(myth()) // добавляем префиксы - http://www.myth.io/ .pipe(gulp.dest("./public/css/")) // записываем css .pipe(livereload(server)); // даем команду на перезагрузку css });
В Gulp мы работаем с потоком, поэтому получаем данные из gulp.src и поточно обрабатываем их.

Так же создадим задачи по обработке Jade, изображений и JS

// Собираем html из Jade gulp.task("jade", function() { gulp.src(["./assets/template/*.jade", "!./assets/template/_*.jade"]) .pipe(jade({ pretty: true })) // Собираем Jade только в папке./assets/template/ исключая файлы с _* .on("error", console.log) // Если есть ошибки, выводим и продолжаем.pipe(gulp.dest("./public/")) // Записываем собранные файлы.pipe(livereload(server)); // даем команду на перезагрузку страницы }); // Собираем JS gulp.task("js", function() { gulp.src(["./assets/js/**/*.js", "!./assets/js/vendor/**/*.js"]) .pipe(concat("index.js")) // Собираем все JS, кроме тех которые находятся в./assets/js/vendor/** .pipe(gulp.dest("./public/js")) .pipe(livereload(server)); // даем команду на перезагрузку страницы }); // Копируем и минимизируем изображения gulp.task("images", function() { gulp.src("./assets/img/**/*") .pipe(imagemin()) .pipe(gulp.dest("./public/img")) });

Для комфортной разработки создадим локальный сервер
// Локальный сервер для разработки gulp.task("http-server", function() { connect() .use(require("connect-livereload")()) .use(connect.static("./public")) .listen("9000"); console.log("Server listening on http://localhost:9000"); });
Необходимые нам выше задачи предназначены для разработки и конечно хочется отслеживать изменения файлов и иметь на сервере Livereload
Для этого создадим задачу "watch".

// Запуск сервера разработки gulp watch gulp.task("watch", function() { // Предварительная сборка проекта gulp.run("stylus"); gulp.run("jade"); gulp.run("images"); gulp.run("js"); // Подключаем Livereload server.listen(35729, function(err) { if (err) return console.log(err); gulp.watch("assets/stylus/**/*.styl", function() { gulp.run("stylus"); }); gulp.watch("assets/template/**/*.jade", function() { gulp.run("jade"); }); gulp.watch("assets/img/**/*", function() { gulp.run("images"); }); gulp.watch("assets/js/**/*", function() { gulp.run("js"); }); }); gulp.run("http-server"); });

Теперь можно запустить наш проект и посмотреть, что получилось.
$ gulp watch

Сервер доступен по адресу localhost:9000 Мы создали среду для веб-разработке проектов с помощью Stylus и Jade с Livereload. Теперь нужно собрать оптимизированный проект. Для этого создадим задачу "build"

Хотите набрать побольше баллов в Google Page Speed? Не знаете что такое «сборка front-end»? Тогда вам сюда, будет интересно.

Что такое Node.JS?

Node.JS принято называть «северным JavaScript». Эта платформа позволяет писать программы, используя синтаксис JavaScript.

Есть реализации для Windows, Mac OS и Linux.

В комплект входит менеджер пакетов NPM , с помощью которого можно устанавливать пакеты.

Что такое Gulp?

Gulp — это пакет, написанный на Node.JS, который помогает веб-мастерам осуществлять сборку проектов на этапе верстки макетов.

Для установки Gulp необходимо воспользоваться командной строкой.

Npm install gulp

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

В этом примере с помощью Gulp мы сделаем следующее:

  • Автоматически оптимизируем изображения для веба;
  • Собираем один минифицированный файл стилей из предпроцессоров (SASS, SCSS);
  • Собираем один минифицированный файл со скриптами;

Как собирать front-end с помощью Gulp?

Чтобы понять, как все работает, разберем все по шагам.

Структуру можно посмотреть на скриншоте.

  • Папка assets — для исходников изображений, стилей и скриптов;
  • Папка public — результат сборки проекта будет находится именно в ней;
  • gulpfile.js — файл, в котором описана логика работы сборщика;
  • package.json — файл, в котором содержатся информация о программах и плагинах, использующихся для корректной работы Gulp.

package.json

Содержимое файла:

{ "name": "gulp_project", "version": "1.0.0", "description": "Example", "main": "gulpfile.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "author": "Dmitriy Ilichev", "license": "ISC", "devDependencies": { "gulp": "^3.9.0", "gulp-csso": "^1.0.0", "gulp-concat": "^2.6.0", "gulp-uglify": "^1.2.0", "gulp-imagemin": "^2.3.0", "gulp-sass": "^2.1.1" } }

Из этого файла понятно следующее:

  • Название проекта gulp_project, версия и описание;
  • Главный файлом является gulpfile.js;
  • Автор проекта, лицензия — все это не столь важно и попросту эти поля могут быть пустыми;
  • Интересным пунктом является devDependencies . В нем описаны зависимости.

Файл можно отредактировать в обычном текстовом редакторе. Его также можно создать для нового проекта командой npm int.

Исходя из этого, Node.JS понимает, что для работы нам понадобятся:

  • Gulp версии 3.9.0 и выше для сборки;
  • Gulp-csso версии 1.0.0 и выше — плагин для минификации стилей (css);
  • Gulp-concat версии 2.6.0 и выше — плагин для склейки нескольких файлов в один;
  • Gulp-uglify версии 1.2.0 и выше — плагин для минификации javascript;
  • Gulp-imagemin версии 2.3.0 и выше — плагин для оптимизации изображений;
  • Gulp-sass версии 2.1.1 и выше — плагин для получения css из sass (scss);

Отлично! После этого нужно все это установить. Делается это из командной строки. Находясь в папке с проектом нужно выполнить команду:

Npm install

Вся необходимая информация будет взята из package.json.

После всего этого волшебства появится служебная папка node_modules .

gulpfile.js

Содержимое файла:

/* * * Определяем переменные * */ var gulp = require("gulp"), // Сообственно Gulp JS uglify = require("gulp-uglify"), // Минификация JS concat = require("gulp-concat"), // Склейка файлов imagemin = require("gulp-imagemin"), // Минификация изображений csso = require("gulp-csso"), // Минификация CSS sass = require("gulp-sass"); // Конверстация SASS (SCSS) в CSS /* * * Создаем задачи (таски) * */ // Задача "sass". Запускается командой "gulp sass" gulp.task("sass", function () { gulp.src("./assets/styles/style.scss") // файл, который обрабатываем.pipe(sass().on("error", sass.logError)) // конвертируем sass в css .pipe(csso()) // минифицируем css, полученный на предыдущем шаге.pipe(gulp.dest("./public/css/")); // результат пишем по указанному адресу }); // Задача "js". Запускается командой "gulp js" gulp.task("js", function() { gulp.src([ "./assets/javascripts/jquery-2.1.4.min.js", "./assets/javascripts/bootstrap.min.js", "./assets/javascripts/script.js" ]) // файлы, которые обрабатываем.pipe(concat("min.js")) // склеиваем все JS .pipe(uglify()) // получившуюся "портянку" минифицируем.pipe(gulp.dest("./public/js/")) // результат пишем по указанному адресу }); // Задача "images". Запускается командой "gulp images" gulp.task("images", function() { gulp.src(".assets/images/**/*") // берем любые файлы в папке и ее подпапках.pipe(imagemin()) // оптимизируем изображения для веба.pipe(gulp.dest("./public/images/")) // результат пишем по указанному адресу }); // Задача "watch". Запускается командой "gulp watch" // Она следит за изменениями файлов и автоматически запускает другие задачи gulp.task("watch", function () { // При изменение файлов *.scss в папке "styles" и подпапках запускаем задачу sass gulp.watch("./assets/styles/**/*.scss", ["sass"]); // При изменение файлов *.js папке "javascripts" и подпапках запускаем задачу js gulp.watch("./assets/javascripts/**/*.js", ["js"]); // При изменение любых файлов в папке "images" и подпапках запускаем задачу images gulp.watch("./assets/images/**/*", ["images"]); });

Главная фишка — в задаче watch . Запустив ее один раз, можно спокойно работать с источниками, и проект будет автоматически собираться при каждом сохранении редактируемых файлов.

На выходе получим готовый к публикации в интернете шаблон.

Задачи можно запускать отдельно. В итоге, в архиве в конце статьи вас ждет следующее:

! Обратите внимание на то, что распаковав у себя этот архив, прежде всего необходимо будет выполнить команду npm install. Папка эта содержит довольно большое количество файлов, и каждый раз копировать/вставлять их — пустая трата времени.

В заключении

Есть огромное множество других полезных плагинов. Например, прекрасный шаблонизатор Jade, который в разы ускоряет написание html кода, кому-то может понадобится LESS и так далее.

Представленный пример — всего лишь платформа и шаблон, с которого быстро и без особых знаний можно начать пользоваться всеми этими прекрасными фишками.