Npm init
От вас потребуется:
Npm i –g gulp
Gulp test
Задача работает.
Gulp serve
Npm i gulp-sass --save-dev
https://gulpjs.com/plugins/
Открываем терминал и переходим в папку с проектом. Первое, что нам необходимо сделать это инициализировать npm для этого выполняем команду:
Npm init
От вас потребуется:
Все можно оставить по умолчанию (если вы не хотите выкладывать проект в общий доступ)
Затем подтверждаем введенную информацию.
Отлично. 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
Задача работает.
Теперь давайте установим и подключим пакеты, которые помогают при верстке.
Для установки в консоли выполняем следующую команду:
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 в консоли выполняем команду:
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 выполним команду:
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 у на с будет:
Следующий пакет объединяет все css файлы в один.
Для установки 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 выполним следующую команду:
Npm i gulp-rename --save-dev
Пока данный пакет не будем добавлять ни в какие задачи.
Для установки 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-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
Создадим задачу 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, как его установить. Установили дополнительные пакеты, которые необходимы для верстки и задали задачи.
Вы можете самостоятельно находить необходимые пакеты на сайте https://gulpjs.com/plugins/ и устанавливать их. А затем создавать задачи для оптимизации процесса разработки.
Всем привет, друзья! Сегодня мы подробно рассмотрим, что такое Gulp и как с его помощью можно автоматизировать работу Front-end разработчика. В результате урока мы соберем серьезное и внушительное рабочее Front-end окружение для веб-разработки с использованием Gulp.
Класснуть
Запинить
https://github.com/agragregra/gulp-lesson
Gulp - это инструмент, который помогает автоматизировать рутинные задачи веб-разработки. Gulp предназначен для решения таких задач, как:
Можно с уверенностью сказать, что Gulp и множество утилит, написанных для него, подходят для решения практически любой задачи при разработке проекта любой сложности - от небольшого сайта до крупного проекта.
Любой проект, использующий Gulp имеет в корне файл gulpfile.js , который содержит набор инструкций по управлению проектом. Сразу хочется сказать, что написание инструкций для Gulp не является программированием, хотя пишутся на языке JavaScript. Не стоит пугаться больших gulpfile.js, в основном все инструкции однотипные и имеют общие черты. К тому времени, как вы прочтете данное руководство, у вас не должно остаться вопросов по 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 пакет устанавливаются в ту папку, в которой выполняются текущие команды, поэтому будьте внимательны.
Давайте создадим папку проекта для примера, с которой будем работать, пусть это будет, например, папка 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 (все файлы, которых не было, пока создаем пустыми):
Данная структура встречается довольно часто, практически во всех проектах, но это не аксиома и некоторые проекты могут иметь вообще другую структуру. Для данной статьи мы будем использовать именно такую структуру проекта.
Здесь мы видим папку app/ , в которой будут размещены все исходные материалы проекта - оригинальные CSS, Sass, js файлы библиотек, оригинальные изображения. В общем - это папка исходников нашего проекта.
Папка dist/ будет содержать уже готовый продукт, оптимизированный, сжатый, причесанный. Это папка продакшена.
Теперь давайте откроем в редакторе кода 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, теперь можно создавать инструкции. Для начала давайте создадим обработчик, который будет компилировать Sass файлы в CSS (CSS препроцессинг).
Давайте установим пакет 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, теперь будем углубляться в каждую деталь того, что было изложено выше.
Выборка файлов в примере выше довольно простая, мы брали файл напрямую: gulp.src("app/sass/main.sass") . Но файлы также можно выбирать по шаблону. Шаблон выборки файлов называется glob - https://en.wikipedia.org/wiki/Glob_(programming) . Давайте познакомимся ближе со всеми возможностями выборки файлов для обработки.
Давайте внесем некоторые изменения в таск 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("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 .
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 :
Выполним в терминале команду "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.
Давайте рассмотрим, как можно оптимизировать 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 или 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 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Всем привет. Если вы связаны хоть как-то с JS, вы наверняка слышали о таком приложении как 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
*
Содержимое может быть представлено в двух форматах: в виде уже прочитанного буфера, или же в виде родного нодовского потока. Каждая ступень галповского пайпа берет на вход такие вот файлы, делает некую трансформацию и передает на выход следующей цепочке. Последняя цепочка обычно просто сохраняет их на диск.
Pipe(gulp.dest("dist/"));
Осознание факта того, что потоки в gulp другие ведет к просветлению и пониманию, поскольку это объясняет большинство проблем и ошибок.
Рассмотрим реальный пример. Вы хотите использовать browserify для склейки ваших JS файлов. Вы идете, и находите плагин gulp-browserify . Но видите приписку, которая говорит, что плагин deprecated, т.е. Устарел.
Как хорошо воспитанный программист вы отметаете этот вариант, и идете искать, а какое же решение не устарело. Находите официальные рецепты от gulp, и видите , что browserify работает с галпом напрямую. Ну как напрямую, через прослойку , которая как раз и переводит родной нодовский поток в виниловский поток, который понимает gulp. Без него ничего бы не заработало, поскольку это разные потоки.
Если вы хотите написать свою трансформацию, то можете использовать данный шаблон .
Как видим, здесь все просто: на каждый файл будет вызываться наш обработчик, который и выполнит модификации. Мы можем делать все что захотим: изменить содержимое файла, переименовать файл, удалить файл или добавить еще пару новых файлов в поток.
Как мы помним, содержимое файла в виниловском потоке может быть представлено в виде буфера или в виде потока данных. Однако не обязательно поддерживать и то другое. Всегда можно использовать пакет
13 января 2014 в 13:42В этой статье будет больше практики, мы соберем среду разработки фронтенда используя Jade и Stylus, запустим локальный сервер и подключим Livereload. Проект я выложил на Github , экспериментируйте.
В корне проекта есть файл конфигурации gulpfile.js его и будем редактировать.
Так же создадим задачи по обработке 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 принято называть «северным JavaScript». Эта платформа позволяет писать программы, используя синтаксис JavaScript.
Есть реализации для Windows, Mac OS и Linux.
В комплект входит менеджер пакетов NPM , с помощью которого можно устанавливать пакеты.
Gulp — это пакет, написанный на Node.JS, который помогает веб-мастерам осуществлять сборку проектов на этапе верстки макетов.
Для установки Gulp необходимо воспользоваться командной строкой.
Npm install gulp
В конце данной статьи находится файл, который поможет собрать типовой проект.
В этом примере с помощью Gulp мы сделаем следующее:
Чтобы понять, как все работает, разберем все по шагам.
Структуру можно посмотреть на скриншоте.
Содержимое файла:
{ "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" } }
Из этого файла понятно следующее:
Файл можно отредактировать в обычном текстовом редакторе. Его также можно создать для нового проекта командой npm int.
Исходя из этого, Node.JS понимает, что для работы нам понадобятся:
Отлично! После этого нужно все это установить. Делается это из командной строки. Находясь в папке с проектом нужно выполнить команду:
Npm install
Вся необходимая информация будет взята из package.json.
После всего этого волшебства появится служебная папка node_modules .
Содержимое файла:
/* * * Определяем переменные * */ 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 и так далее.
Представленный пример — всего лишь платформа и шаблон, с которого быстро и без особых знаний можно начать пользоваться всеми этими прекрасными фишками.