Сжатие изображение, JS и CSS файлов, в целях оптимизации загрузки веб-страниц и многоe многое другое. Чтобы упросить этот процесс, мы предлагаем вам воспользоваться сборкой проектов Gulp 4, которую постоянно совершенствует Андрей Горохов. Ниже будут представлены ссылки на скачивание, а пока пройдемся по основным моментам: описанию и установке.
Gulp - это сборщик проектов, инструмент для автоматизации задач, которые описаны выше. Он поможет вам ускорить вашу работу и грамотно подготовить проект к релизу.
Скачать сборку можно с репозитория Github или через командную строку Git . В дальнейшем вы сможете настроить её под свои задачи.
Если вы всё сделали правильно, у вас должен открыться браузер с локальным сервером. Режим сборки предполагает оптимизацию проекта: сжатие изображений, минифицирование CSS и JS-файлов для загрузки на сервер.
Если у тебя возникли проблемы с установкой, то посмотри этот ролик:
Пример структуры папки с БЭМ-блоком:
Blocks ├── modules │ ├──header │ │ ├── header.html │ │ ├── header.js │ │ ├── header.scss
Чтобы вручную не создавать соответствующие папку и файлы, достаточно в консоли прописать команду bem create my-block — для создания папки БЭМ-блока, где my-block — имя БЭМ-блока
Import $ from " jquery" ;
⚠️ Если в вашем проекте используется несколько библиотек, которые необходимо подключать на нескольких страницах, во избежании ошибок нужно:
Entry: { main: " ./src/js/index.js" , pageA: " ./src/js/import/pages/pageA.js" , pageB: " ./src/js/import/pages/pageB.js" }
CSS-сетка smart-grid
В сборщик включена CSS-сетка smart-grid от Дмитрия Лаврика . Она позволяет избавиться от лишних классов в разметке за счёт использования примесей в SCSS и ускоряет адаптивную вёрстку. Конфигурация уже настроена в соответствии с сеткой Bootstrap . Пример использования:
Items { @include row-flex (); @include md (justify-content , center ); .item { @include col (); @include size (3 ); @include size-md (5 ); @include size-xs (10 ); } }
В последнее время Gulp набирает большую популярность, и понятно почему. Он быстрее, красивее и проще чем Grunt . Мне приходилось часто с ним работать, но я всегда брал готовые решения и не до конца понимал как же он все это делает. На этих выходных я решил разобрать и закрыть эту небольшую проблему. Об этом и поговорим сегодня.
Gulp - это инструмент сборки front-a. Он позволяет автоматизировать повторяющиеся задачи (сборка и минификация CSS- и JS-файлов, запуск тестов, перезагрузка браузера и другие). Тем самым Gulp ускоряет и оптимизирует процесс веб-разработки.
Установить Gulp достаточно легко. Если у вас что-то не получится, пишите в комментариях или загуглите вашу проблему. Итак для установки нужно сделать 3 шага:
Первый шаг - устанавливаем глобально Gulp. Открываем терминал и пишем:
npm install --global gulp
После этого вам нужно установить Gulp как devDependencies для вашего проекта. Убедитесь в том, что у вас есть файл package.json . Если его нет, то создайте его написав в консоль npm init . Теперь можно установить Gulp как devDependencies:
npm install --save-dev gulp
И наконец, вам нужно создать gulpfile.js в корне вашего проекта, который будет содержать ваши задачи (tasks). В качестве промежуточного шага, мы установим плагин gulp-util . Чтобы показать как устанавливаются плагины:
npm install --save-dev gulp-util
Теперь настало время написать нашу первую задачку. Открываем только что созданный файл gulpfile.js и пишем в него следующее:
/* File: gulpfile.js */ // собираем все наши плагины var gulp = require (" gulp " ), gutil = require (" gulp-util " ); // создаем задачку, которая будет выполняться по умолчанию gulp . task (" default " , function () { return gutil . log (" Gulp is running! " ) });
И теперь нам остается запустить gulp в терминале и мы увидим нечто похожее на это:
> gulp [ 12:32:08] Using gulpfile ~/Projects/gulp-scotch-io/gulpfile.js [ 12:32:08] Starting "default" ... [ 12:32:08] Gulp is running! [ 12:32:08] Finished "default" after 1 ms
Сам по себе Gulp очень скуден на возможности. Но все, что вам нужно вынесено в отдельные плагины. Они совместно с Gulp творят чудеса.
Api у gulp очень маленькое, и содержит всего 4 функции высшего порядка:
gulp.task определяет наши задачи. В качестве аргументов принимает название, зависимости (массив) и функцию (основные действия). Зависимостей может и не быть:
gulp . task (" mytask " , function () { //сделать что-то }); gulp . task (" dependenttask " , [ " mytask " ], function () { //сделать что-то после того, как "mytask" будет выполнен });
gulp.src указывает на файлы, которые мы хотим использовать. Он использует.pipe доступа к файлам через плагины.
gulp.dest указывает на папку, в которую мы хотим сохранить измененные файлы.
gulp.src и gulp.dest используется для простой копии файлов:
gulp . task (" copyHtml " , function () { // скопировать все html файлы из source/ в public/ gulp . src (" source/*.html " ). pipe (gulp . dest (" public " )); });
В gulp встроена система реагирования на изменения файлов (gulp.watch). Вы можете использовать эту задачу для запуска других необходимых вам задач при изменении файлов.
В этой статье мы подробно разберем процесс сборки фронтенд проекта, который прижился в моей повседневной работе и очень облегчил рутину.
Статья не претендует на истину в последней инстанции, так как сегодня существует большое количество различных сборщиков и подходов к сборке, и каждый выбирает по вкусу. Я лишь поделюсь своими мыслями по этой теме и покажу свой workflow.
Мы будем использовать сборщик Gulp . Соответственно у вас в системе должен быть установлен Node js. Установку ноды под конкретную платформу мы рассматривать не будем, т.к. это гуглится за пару минут.
И для начала отвечу на вопрос - почему Gulp?
Из более или менее сносных альтернатив мы имеем Grunt и Brunch .
Когда я только начал приобщаться к сборщикам - на рынке уже были и Grunt и Gulp. Первый появился раньше и по этому имеет более большое коммьюнити и разнообразие плагинов. По данным с npm :
Grunt - 11171 пакет
Gulp - 4371 пакет
Но Grunt мне показался через чур многословным. И после прочтения нескольких статей-сравнений - я предпочел Gulp за его простоту и наглядность.
Brunch - это сравнительно молодой проект, со всеми вытекающими из этого плюсами и минусами. Я с интересом наблюдаю за ним, но в работе пока не использовал.
Создадим папку под наш проект, например «habr». Откроем ее в консоли и выполним команду
Npm init
Можно просто нажать Enter на все вопросы установщика, т.к. сейчас это не принципиально.
В итоге в папке с проектом у нас сгенерируется файл package.json, примерно такого содержания
{ "name": "habr", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo "Error: no test specified" && exit 1" }, "author": "", "license": "ISC" }
Немного видоизменим его под наши нужды:
{ "name": "habr", "version": "1.0.0", "description": "", "author": "", "license": "ISC", "devDependencies": { "gulp": "^3.8.1" } }
в блоке devDependencies мы указали что нам нужен gulp и тут же будем прописывать все наши плагины.
Со стилями я поступаю так же как и с js, но только вместо rigger"a - использую встроенный в SCSS импорт.
Наш main.scss будет выглядеть так:
/* * Third Party */ @import "CSS:../../bower_components/normalize.css/normalize.css"; /* * Custom */ @import "partials/app";
Таким способом получается легко управлять порядком подключения стилей.
Проверим наш таск, запустив
Gulp style:build
Таск по картинкам будет выглядеть так:
Gulp.task("image:build", function () { gulp.src(path.src.img) //Выберем наши картинки.pipe(imagemin({ //Сожмем их progressive: true, svgoPlugins: [{removeViewBox: false}], use: , interlaced: true })) .pipe(gulp.dest(path.build.img)) //И бросим в build .pipe(connect.reload()); });
Я использую дефолтные настройки imagemin, за исключением interlaced. Подробнее об API этого плагина можно прочесть .
Теперь, если мы положим какую-нибудь картинку в src/img и запустим команду
Gulp image:build
то увидим в build нашу оптимизированную картинку. Так же gulp любезно напишет в консоли сколько места он сэкономил для пользователей нашего сайта:)
Со шрифтами мне обычно не нужно проводить никаких манипуляций, но что бы не рушить парадигму «Работаем в src/ и собираем в build/» - я просто копирую файлы из src/fonts и вставляю в build/fonts. Вот таск
Gulp.task("fonts:build", function() { gulp.src(path.src.fonts) .pipe(gulp.dest(path.build.fonts)) });
Теперь давайте определим таск с именем «build», который будет запускать все что мы с вами тут накодили
Gulp.task("build", [ "html:build", "js:build", "style:build", "fonts:build", "image:build" ]);
Чтобы не лазить все время в консоль давайте попросим gulp каждый раз при изменении какого то файла запускать нужную задачу. Для этого напишет такой таск:
Gulp.task("watch", function(){ watch(, function(event, cb) { gulp.start("html:build"); }); watch(, function(event, cb) { gulp.start("style:build"); }); watch(, function(event, cb) { gulp.start("js:build"); }); watch(, function(event, cb) { gulp.start("image:build"); }); watch(, function(event, cb) { gulp.start("fonts:build"); }); });
С понимаем не должно возникнуть проблем. Мы просто идем по нашим путям определенным в переменной path, и в функции вызывающейся при изменении файла - просим запустить нужный нам таск.
Попробуйте запустить в консоли
Gulp watch
и поменяйте разные файлы.
Ну не круто ли?)
Что бы насладиться чудом livereload - нам необходимо создать себе локальный веб-сервер. Для этого напишем следующий таск:
Gulp.task("webserver", function() { connect.server({ host: server.host, port: server.port, livereload: true }); });
Тут даже нечего комментировать. Мы просто запустим сервер с livereload на хосте и порте, которые мы определили в объекте server.
Если вы добавите какую-нибудь картинку, потом запустите задачу image:build и потом картинку удалите - она останется в папке build. Так что было бы удобно - периодически подчищать ее. Создадим для этого простой таск
Gulp.task("clean", function (cb) { rimraf(path.clean, cb); });
Теперь при запуске команды
Gulp clean
просто будет удаляться папка build.
Этот таск не несет в себе критической функциональности, но он очень мне нравится:)
Gulp.task("openbrowser", function() { opn("http://" + server.host + ":" + server.port + "/build"); });
Когда нам будет нужно, мы запустим его - и у нас в браузере автоматически откроется вкладка с нашим проектом.
Классно же:)
Последним делом - мы определим дефолтный таск, который будет запускать всю нашу сборку.
Gulp.task("default", ["build", "webserver", "watch", "openbrowser"]);
Окончательно ваш gulpfile.js будет выглядеть примерно вот так .
Теперь выполним в консоли
И вуаля:) Заготовка для вашего проекта готова и ждет вас.
Эта статья задумывалась как способ еще раз освежить в памяти тонкости сборки frontend проектов, и для легкости передачи этого опыта новым разработчикам. Вам не обязательно использовать на своих проектах именно такой вариант сборки. Есть yeoman.io , на котором вы найдете генераторы почти под любые нужды.
Я написал этот сборщик по 2ум причинам.
- Мне нравится использовать rigger в своем html коде
- Почти во всех сборках что я встречал - используется временная папка (обычно.tmp/), для записи промежуточных результатов сборки. Мне не нравится такой подход и я хотел избавится от временных папок.
- И я хотел что бы все это было у меня из коробки:)
Мою рабочую версию сборщика вы можете скачать на моем github .
Надеюсь статья оказалась полезной для вас:)
P.S. обо всех ошибках, недочетах и косяках - пожалуйста пишите в личку
Данный мануал содержит описание полезных и наиболее часто используемых front-end инструментов. Вы сможете узнать процесс установки инструментов и основные моменты работы с ними.
В процессе разработки проекта часто приходится добавлять сторонние библиотеки и плагины. В результате разработчику необходимо осуществлять поиск нужной зависимости, скачивать, распаковывать архив и копировать файлы в проект. Пакетные менеджеры помогут автоматизировать данную рутинную работу.
Пакетный менеджер – программное обеспечение, позволяющее управлять процессом установки, удаления, настройки и обновления различных компонентов.
Добавление сторонних библиотек с использованием пакетного менеджера заменяется парой команд в терминале.
Одним из пакетных менеджеров используемых во frontend-проектах является NPM.
npm (Node.js Package Manager) - менеджер пакетов, входящий в состав Node.js. Используется для скачивания пакетов из облачного сервера npm, либо для загрузки пакетов на этот сервер.
Для установки npm необходимо скачать и установить NodeJS (npm будет автоматически установлен): https://nodejs.org/en/.
Пакетом называется один или несколько JavaScript-файлов, представляющих собой какую-то библиотеку или инструмент. Для установки пакета с помощью npm необходимо выполнить следующую команду:
Npm install <название пакета>
Для глобальной установки пакета используется ключ -g. После установки пакет вместе с исходниками находится в директории node_modules/.
Чтобы проверить текущую версию npm, необходимо выполнить команду:
Файл package.json содержит в себе информацию о вашем приложении: название, версия, зависимости и тому подобное. Любая директория, в которой есть этот файл, интерпретируется как Node.js-пакет.
Для создания файла package.json необходимо выполнить команду:
Npm init
После этого необходимо будет заполнить некоторую информацию о проекте.
В данном файле будут храниться наименования и версии всех пакетов необходимых в проекте. С помощью команды npm install можно подгрузить все пакеты, которые находятся в package.json .
Для установки некоторого пакета и автоматическим сохранением в файле package.json используется команда:
Npm install<название пакета> --save-dev
В системе должны быть установлены NodeJS и npm.
Шаг 1: Для глобальной установки GulpJS с помощью пакетного менеджера npm необходимо выполнить команду:
Npm install gulp -g
Шаг 2: Необходимо установить его для приложения:
Npm install --save-dev gulp
Подгрузка дополнительных плагинов, которые могут быть использованы при сборке проекта, также осуществляется c помощью npm следующей командой:
Npm install <название плагина> --save-dev
Все установленные плагины находятся в директории node_modules/ .
Шаг 1: Сперва нужно подключить gulp к проекту. Для этого в файле gulpfile.js прописываем строчку:
Var gulp = require("gulp");
Функция require() позволяет подключать плагины из папки node_modules/.
Шаг 2: С помощью переменной gulp можно создавать таски для сборки проекта:
Gulp.task("exampleTask", function() {});
Метод task
принимает два параметра: название и функцию с телом таски.
Данную инструкцию уже можно выполнить. Для этого в консоли прописываем:
Gulp exampleTask
Ниже представлен более сложный пример инструкции:
Gulp.task("exampleTask", function () { return gulp.src("source-files") .pipe(plugin()) .pipe(gulp.dest("folder")); });
Разберем команды использованные в данном примере:
Функция gulp.src принимает в качестве параметра маску файлов. Примеры масок:
Использование потоков является одним из важнейших преимуществ GulpJS.
Потоки позволяют передать некоторые данные последовательно от одной функции к другой, каждая из которых выполняет некоторые действия с этими данными.
Функция gulp.src() создает поток объектов, представляющих файлы, которые переданы ей в качестве параметра. Далее с помощью функций pipe выстраивается конвейер, по которому передается поток объектов. Данной функции в качестве параметра передается плагин, который каким-либо способом обрабатывает поток объектов.
Ниже представлен пример использования потоков. В данном примере использованы сторонние плагины gulp-jshint и gulp-concat, которые необходимо установить и подключить в gulpfile.js.
Функция gulp.src берет файлы по маске js/*.js . Запускает JSHint и выводит результат. Затем производит конкатенацию файлов и в конце сохраняет полученный файл после конкатенации в директории dist/ .
Gulp.task("example", function () { return gulp.src("js/*.js") .pipe(jshint()) .pipe(concat("index.js")) .pipe(gulp.dest("dist")); });
Рассмотрим пример использования сторонних плагинов. Для этого создадим инструкцию конкатенации файлов js:
Шаг 1: Сперва необходимо подключить плагин командой require:
Var concat = require("gulp-concat");
Шаг 2: Затем нужно создать таск для конкатенации файлов с расширением js находящихся в директории js/ . В конце получившийся файл помещается в директорию dist/js:
Gulp.task("concat", function () { return gulp.src("js/*.js") .pipe(concat("index.js")) .pipe(gulp.dest("dist/js")); });
Gulp concat
Также можно определить таск, который будет вызывать выполнение других тасков.
Gulp.task("build", ["html", "css"]);
Кроме этого существует метод watch для наблюдения изменений в файлах:
Gulp.watch("маска файлов для наблюдения", ["название таски, которая выполнится при изменении файлов"]);
В gulpfile.js можно создать дефолтный таск:
Gulp.task("default", ["task1", "task2"]);
Данный таск запускается из консоли командой:
С полным списком Gulp-плагинов вы можете ознакомиться по ссылке:
http://gulpjs.com/plugins/
Для подключения Jasmine к своему проекту необходимо скачать библиотеку и подключить следующие файлы на главную HTML-страницу:
Jasmine можно подключить в сборку проекта на GulpJS:
Шаг 1: Вначале необходимо установить плагин gulp-jasmine:
Npm install gulp-jasmine --save-dev
Шаг 2: Затем нужно подключить плагин в файле сборки и создать таску запуска тестов:
Var jasmine = require("gulp-jasmine"); gulp.task("jasmine", function() { gulp.src("файлы тестов") .pipe(jasmine()); });
(в конце статьи подробнее описана работа с этим инструментом)
Для подключения Jasmine в KarmaJS необходимо:
Шаг 1: Установить KarmaJS:
Npm install -g karma-cli
Шаг 2: Установить плагины необходимые для запуска тестов написанных на Jasmine в браузерах Chrome и PhantomJS:
Npm install karma-jasmine karma-chrome-launcher karma-phantomjs-launcher
Шаг 3: Установить сам Jasmine:
Npm install -g jasmine
Шаг 4: В файле конфигурации karma подключить плагины и прописать путь к тестам.
Функции describe и it принимают два параметра: первый – название, второй – функция с кодом.
Во избежание копирования какой-либо логики, используемой в тестах, используются функции beforeEach/afterEach . Они запускаются соответственно перед/после каждого теста.
Для тестирования асинхронных вызовов используются функции runs и waitsFor .
Возможность отслеживания вызова функций производится с помощью spyOn . Данная функция принимает два параметра: первый – объект, для которого осуществляется вызов функции, второй – имя функции, которую необходимо отслеживать.
If(“проверка вызова функции”, function () { spyOn(exampleObject, "exampleFunction"); exampleObject.exampleFunction(); expect(exampleObject.exampleFunction).toHaveBeenCalled(); });
При тестировании с использованием spyOn можно отслеживать количество вызовов, их параметры и каждый вызов в отдельности.
Для создания функции без реализации можно воспользоваться createSpy . Функция createSpy принимает имя функции для идентификации.
If(“проверка вызова функции”, function () { var example = createSpy("EXAMPLE"); example(“param1”, “param2”); expect(example.identify).toHaveBeenCalledWith(“param1”, “param2”); expect(example.calls.length).toEqual(1); });
Создание объекта заглушки осуществляется с помощью createSpyObj . В качестве параметров createSpyObj принимает имя объекта и массив строк, являющийся списком методов объекта заглушки.
Генерация документации производится из комментариев исходного кода.
Ни для кого не секрет, что современный front-end разработчик обязан иметь в своем вооружении один из инструментов сборки проектов такие как Gulp или Grunt . До какого-то времени Grunt занимал монополию в этом вопросе, но отделившаяся от Grunt группа разработчиков решила создать свой легковесный и быстрый таск-менеджер Gulp.
В этой статье мы с нуля подготовим стартовый пакет для использования его в будущих проектах.
До недавнего времени я сам задавался вопросом, зачем мне нужно тратить время на настройку конфига таск-менеджера, если я и так неплохо справляюсь с версткой макетов, пока не начал использовать CSS пре-процессоры.
CSS пре-процессоры - реально удобны и ускоряют написание стилей, но компилирование кода написанного на пре-процессоре в обычный CSS, не совсем тривиальная задача которая решается одной кнопкой. Тут то нам на помощь и приходит таск-менеджер. Преобразование кода происходит не то чтобы нажатием кнопки, все происходит в режиме онлайн без вашего участия (конечно если правильно все настроить).
Само собой задачи таск-менеджера выходят далеко за пределы процессов связанных с преобразованием кода пре-процессора в чистый CSS. Сборщик проектов так же занимается минификацией, конкатенацией, проверкой кода на ошибки, сборкой изображение в спрайты, оптимизацией изображений под веб и т.д. Вы просто создаете в своем проекте множество логически-разделенных файлов, которые потом удобно собираются в один каталог уже обработанные и готовые для работе в браузере. Но об этом чуть позже, а сейчас начнем с подготовки.
Если вы знаете как установить node.js на свою систему и пользуетесь ей, можете смело переходить к следующему заголовку.
Хотелось бы сразу предупредить, что все описанные действия актуальны для Mac OS X , но в целом применимы и для других Unix систем. Разработка через таск-менеджер и командную строку в Windows несколько более затруднительная и тут она описана не будет. Однако, если вы все же пользуетесь Windows и не готовы от него отказываться, то могу предложить вариант использования виртуальной машины с установленной Ubuntu , я использую этот вариант на своей домашней системе, что в целом довольно удобно.
Итак первым делом нам предстоит скачать и установить пакет node.js в свою систему для работы с нодой через консоль. Переходим на официальный сайт node.js и скачиваем свежую stable версию для вашей системы. После установки в вашей командной строке должна быть доступна команда node . Чтобы проверить что ваша node работает, введем в командной строке команду
в ответ должна появиться версия установленной node.js. Если все хорошо, идем дальше.
В наших проектах мы будем использовать унифицированный вариант структуры:
Develop - корневой каталог разработки └─start - каталог проекта ├─build - билд собраный таск-менеджером ├─resource - все файлы исходники для разработки (.psd и пр.) ├─src - каталог разработки │├─css - каталог разработки стилей ││├─images - все статичные изображения ││├─sprites - изображение собираемые в спрайт ││├─partial - пользовательские файлы стилей │││├─mixins.styl - пользовательские миксины │││└─styles.styl - пользовательские стили ││├─vendor - прочие внешние файлы стилей ││└─styles.styl - основной файл стилей │├─fonts - каталог шрифтов │├─img - каталог динамических изображений │├─js - каталог разработки JavaScript ││├─_*.js - побочные файлы js ││├─_main.js - основной пользовательский js ││└─main.js - основной файл js │├─.htaccess - конфиг для сервера │├─*.html - файлы разметки страницы │├─pages.html - файл со ссылками на все страницы шаблона │├─index.html - индексовый файл разметки страницы │└─include - каталог подключаемых файлов разметки │ └─*.html - подключаемые файлы разметки (header.html и пр.) ├─package.json - конфиг пакетного менеджера npm ├─gulpfile.js - конфиг Gulp ├─stylus.template.mustache - маска для чтения спрайтов ├─TODO - todo лист └─.gitignore - конфиг для Git
В консоли с помощью команды cd перейдем в корневой каталог разработки, создадим каталог нашего проекта mkdir start и перейдем в него.
Установим нашу структуру для проекта через консоль:
mkdir build resource src src/css src/css/images src/css/sprites src/css/partial src/css/vendor src/js src/template src/template/include src/img src/fonts
Создадим начальные файлы в структуре проекта:
touch gulpfile.js stylus.template.mustache .gitignore src/.htaccess src/TODO src/css/styles.styl src/css/partial/styles.styl src/css/partial/mixins.styl src/js/main.js src/js/_main.js src/template/pages.html src/template/index.html src/template/include/header.html src/template/include/footer.html
все всплывающие вопросы можно прощелкать через Enter, node установит им значения по-умолчанию, либо заполнить предлагаемые поля.
Говорим гиту какие каталоги игнорировать и не заливать в репозиторий:
/node_modules/ /build/ /resource/
Каталог node_modules появится позже после установки плагинов и будет содержать в себе все node-плагины проекта.
Устанавливаем для сервера дополнительное gzip сжатие и кэширование:
AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css text/javascript application/javascript
Подключим пользовательские файлы стилей в основной файл стилей:
@import "partial/styles"
Обратите внимание, что для подключение.styl файлов, расширение не указывается, согласно семантике кода пре-процессора Stylus. Для подключения стилей в другом расширении, например.css, указание последнего обязательно.
Эта страница содержит в себе todo лист разработки. Более подробно о работе с данным файлом вы можете почитать на странице плагина PlainTasks для Sublime Text.
На этом установка структуры завершена.
Node.js по-умолчанию включает в себя пакетный менеджер npm , в репозиториях которого собрано множество плагинов, с которыми нам и предстоит работать.
Для начала нужно установить Gulp глобально (с ключем -g) на нашу систему
npm install gulp -g
Делать это нужно один раз , в дальнейшем глобальная установка не требуется.
Теперь нужно установить Gulp локально в каталог проекта
npm install gulp --save-dev
Ключ --save-dev говорит о том, что информация о плагине (имя в репозитории и его версия) будет добавлена в конфиг package.json и запомнит его для данного проекта. Поскольку мы не храним в гите тяжеловесную папку с плагинами node_modules , сохраненная в конфиге информация об установленных плагинах позволит всего одной командой npm i развернуть в проекте все нужные плагины.
Для каждой команды существуют сокращения, поэтому команду выше мы можем записать в более коротком формате
В дальнейшем мы так же будем пользоваться сокращенным форматом команд.
В наших проектах мы пользуемся пре-процессором Stylus который отлично работает и компилируется на ноде.
Устанавливаем:
npm i gulp-stylus -D
Автопрефиксер - автоматически подставляет префиксы -ms- -o- -moz- -webkit- в нужные свойства:
npm i gulp-autoprefixer -D
Минификация CSS - плагин минифицирует выходной CSS файл избавляя его от лишних пробелов и табуляций:
npm i gulp-minify-css -D
Объединение картинок в спрайты - вам больше не нужно тратить часы драгоценного времени на объединение всех изображений в спрайты, а потом высчитывать их координаты, все это за вас автоматически сделает этот плагин:
npm i gulp.spritesmith -D
Добавим в ранее созданный файл stylus.template.mustache маску вычисления позиций в спрайтах:
{{#items}}
${{name}} = {{px.x}} {{px.y}} {{px.offset_x}} {{px.offset_y}} {{px.width}} {{px.height}} {{px.total_width}} {{px.total_height}} "{{{escaped_image}}}";
{{/items}}
Добавим специальные миксины в mixins.styl:
SpriteWidth($sprite) width $sprite spriteHeight($sprite) height $sprite spritePosition($sprite) background-position $sprite $sprite spriteImage($sprite) background-image url($sprite) sprite($sprite) if !match("hover", selector()) && !match("active", selector()) spriteImage($sprite) spritePosition($sprite) spriteWidth($sprite) spriteHeight($sprite)
Подключим миксины и генерируемый файл с координатами в основной файл стилей src/css/styles.styl:
@import "partial/sprite" @import "partial/mixins"
Обратите внимание что файлы спрайтов должны подключаться до пользовательских стилей @import "partial/styles"
Оптимизация изображений под веб - плагин автоматически вырежет всю лишнюю информацию из ваших изображений и ужмет их до оптимального размера, что позволит в некоторых случаях добиться сокращения объема изображений до 90%:
npm i gulp-imagemin -D
Минификация JS - плагин максимально минифицирует ваш JS код сокращая время его загрузки:
npm i gulp-uglify -D
Отслеживание ошибок JS - плагин досканально проверит ваш JS код на выявление всех несоответствий и выведет их в консоль:
npm i jshint gulp-jshint -D
Подключаемые файлы - плагин позволяет хранить статичные части сайта, такие как header , footer , aside и т.д., в отдельных файлах и подключать их в любой части другого файла. Больше нет надобности, в случае мелких изменений в шапке, менять десятки, а то и сотни html страниц шаблона:
npm i gulp-rigger -D
Плагин так же совместим с JS.
Подключим пользовательский JS в основной файл JS src/js/main.js констуркцией:
//= _main.js
Подключим в index.html файлы header.html и footer.html
//= include/header.html //= include/footer.html
LiveReload - плагин избавляет вас от надобности каждый раз перезагружать страницу в браузере чтобы увидеть изменения, теперь это происходит автоматически при сохранении измененного файла:
npm i gulp-connect -D
Предохраняем Gulp от вылета - иногда случается так, что Gulp может вылететь из режима наблюдения в случае возникновения критических ошибок (в основном из-за JS). Данный плагин, по возможности, старается оставить процессы Gulp работоспособными:
npm i gulp-plumber -D
Переименование файлов - самая обычная работа с именами файлов. Плагин позволяет полностью переименовывать файлы, изменять расширение, добавлять префиксы и постфиксы, например чтобы привести файл вида style.styl в style.min.css:
npm i gulp-rename -D
Клинер - иногда возникает потребность в полном очищении каталога build , тут нам на помощь приходит плагин:
Sourcemap - для того чтобы после минификации ваши файлы оставались читаемы через отладку браузером, нужно добавлять sourcemap в минифицируемые файлы:
npm i gulp-sourcemaps -D
Расширенные возможности watch - плагин делает watch умным, теперь он не перезаписывает все файлы в билд при изменении всего одного файла, перезаписывается конкретный измененный файл, что экономит время и ресурсы:
npm i gulp-watch -D
После всех установленных плагинов, проверим наш package.json . Он должен иметь примерно следующий вид:
{ "name": "start", "version": "1.0.0", "description": "Start pack for Front-end develop", "author": "Ivan Ivanov", "license": "MIT", "dependencies": {}, "devDependencies": { "gulp": "latest", "gulp-autoprefixer": "latest", "gulp-connect": "latest", "gulp-imagemin": "latest", "jshint": "latest", "jshint-stylish": "latest", "gulp-jshint": "latest", "gulp-minify-css": "latest", "gulp-plumber": "latest", "gulp-rename": "latest", "gulp-rigger": "latest", "gulp-sourcemaps": "latest", "gulp-stylus": "latest", "gulp-uglify": "latest", "gulp-watch": "latest", "gulp.spritesmith": "latest", "rimraf": "latest" } }
Вместо latest в вашем случае будут прописаны конкретные версии установленных плагинов. Т.к. мы формируем наш стартовый пакет, который будет использоваться в множестве проектов, рекомендуется также заменить значения версий на latest , чтобы всегда устанавливать актуальные версии плагинов в проект.
В папке проекта также должен появиться каталог node_modules в котором хранятся все файлы плагинов ноды. Все нужные плагины установлены, можно переходить к настройки конфига Gulp.
gulpfile.js - это основной файл конфигурации нашего таск-менеджера, именно в нем мы будем хранить все настройки и команды.
Вся работа Gulp сводится к task (англ. задача). Задача - это отдельная самостоятельная функция с именем. Каждая задача может быть вызвана отдельно.
Во первых в начало файла подключим режим совместимости только по современным стандартам:
"use strict";
Подробнее про эту директиву можно .
Плагины инициализируются следующей конструкцией:
var initPlugin = require("plugin-name");
В соответствии с этой конструкцией инициализируем все наши плагины:
Var gulp = require("gulp"), //основной плагин gulp stylus = require("gulp-stylus"), //препроцессор stylus prefixer = require("gulp-autoprefixer"), //расставление автопрефиксов cssmin = require("gulp-minify-css"), //минификация css uglify = require("gulp-uglify"), //минификация js jshint = require("gulp-jshint"), //отслеживание ошибкок в js rigger = require("gulp-rigger"), //работа с инклюдами в html и js imagemin = require("gulp-imagemin"), //минимизация изображений spritesmith = require("gulp.spritesmith"), //объединение картинок в спрайты rimraf = require("rimraf"), //очистка sourcemaps = require("gulp-sourcemaps"), //sourcemaps rename = require("gulp-rename"), //переименвоание файлов plumber = require("gulp-plumber"), //предохранитель для остановки гальпа watch = require("gulp-watch"), //расширение возможностей watch connect = require("gulp-connect"); //livereload
Для удобства сразу определим все пути и маски:
Var path = { build: { //Тут мы укажем куда складывать готовые после сборки файлы html: "build/", js: "build/js/", css: "build/css/", img: "build/css/images/", fonts: "build/fonts/", htaccess: "build/", contentImg: "build/img/", sprites: "src/css/images/", spritesCss: "src/css/partial/" }, src: { //Пути откуда брать исходники html: "src/template/*.html", //Синтаксис src/template/*.html говорит gulp что мы хотим взять все файлы с расширением.html js: "src/js/[^_]*.js",//В стилях и скриптах нам понадобятся только main файлы jshint: "src/js/*.js", css: "src/css/styles.styl", cssVendor: "src/css/vendor/*.*", //Если мы хотим файлы библиотек отдельно хранить то раскоментить строчку img: "src/css/images/**/*.*", //Синтаксис img/**/*.* означает - взять все файлы всех расширений из папки и из вложенных каталогов fonts: "src/fonts/**/*.*", contentImg: "src/img/**/*.*", sprites: "src/css/sprites/*.png", htaccess: "src/.htaccess" }, watch: { //Тут мы укажем, за изменением каких файлов мы хотим наблюдать html: "src/template/**/*.html", js: "src/js/**/*.js", css: "src/css/**/*.*", img: "src/css/images/**/*.*", contentImg: "src/img/**/*.*", fonts: "src/fonts/**/*.*", htaccess: "src/.htaccess", sprites: "src/css/sprites/*.png" }, clean: "./build", //директории которые могут очищаться outputDir: "./build" //исходная корневая директория для запуска минисервера };
Обратите внимание, что мы можем использовать маски имен:
Теперь, когда все константы прописаны, можно приступить к написанию тасков. Все задачи имеют следующую конструкцию:
Gulp.task("taskName", function(){ //some functions });
Первым делом мы настроим работу локального сервера и LiveReload:
// Локальный сервер для разработки gulp.task("connect", function(){ connect.server({ //настриваем конфиги сервера root: , //корневая директория запуска сервера port: 9999, //какой порт будем использовать livereload: true //инициализируем работу LiveReload }); });
Скорее всего вам часто придется работать одновременно сразу в нескольких проектов. Сервер позволяет одновременно запускать множество серверов, достаточно для разных проектов прописать свой порт.
Все изображения для объединения в спрайты складываются в директорию src/css/sprites/ и после прогона через Gulp становятся единым спрайтовым изображением. В спрайты не стоит складывать логотипы и бэкграунды без четких размеров.
// билдим спрайты gulp.task("sprites:build", function () { var spriteData = gulp.src(path.src.sprites) //выберем откуда брать изображения для объединения в спрайт.pipe(spritesmith({ imgName: "sprite.png", //имя спрайтового изображения cssName: "sprite.styl", //имя стиля где храним позиции изображений в спрайте imgPath: "images/sprite.png", //путь где лежит спрайт cssFormat: "stylus", //формат в котором обрабатываем позиции cssTemplate: "stylus.template.mustache", //файл маски cssVarMap: function(sprite) { sprite.name = "s-" + sprite.name //имя каждого спрайта будет состоять из имени файла и конструкции "s-" в начале имени } })); spriteData.img.pipe(gulp.dest(path.build.sprites)); // путь, куда сохраняем картинку spriteData.css.pipe(gulp.dest(path.build.spritesCss)); // путь, куда сохраняем стили });
Для вывода спрайта достаточно воспользоваться миксином. Например, для файла lorem.png выборка из спрайта будет выглядеть следующим образом:
Lorem sprite($s-lorem)
Теперь объект с классом.lorem примет размеры изображения и само изображение в качестве фона.
Статичные изображения - это изображения используемые в шаблоне верстки.
// билдим статичные изображения gulp.task("image:build", function () { gulp.src(path.src.img) //Выберем наши картинки.pipe(imagemin({ //Сожмем их progressive: true, //сжатие.jpg svgoPlugins: [{removeViewBox: false}], //сжатие.svg interlaced: true, //сжатие.gif optimizationLevel: 3 //степень сжатия от 0 до 7 })) .pipe(gulp.dest(path.build.img)) //выгрузим в build .pipe(connect.reload()) //перезагрузим сервер });
Динамичные изображения - это контентные изображения, которые будут меняться на сайте и на уровне шаблона подключаются лишь для демонстрации. Например, это могут быть изображения для новостей и пр.
// билдим динамичные изображения gulp.task("imagescontent:build", function() { gulp.src(path.src.contentImg) .pipe(imagemin({ //Сожмем их progressive: true, //сжатие.jpg svgoPlugins: [{removeViewBox: false}], //сжатие.svg interlaced: true, //сжатие.gif optimizationLevel: 3 //степень сжатия от 0 до 7 })) .pipe(gulp.dest(path.build.contentImg)) //выгрузим в build .pipe(connect.reload()) //перезагрузим сервер });
Отдельный таск для внешних стилей:
// билдинг вендорного css gulp.task("cssVendor:build", function () { gulp.src(path.src.cssVendor) // Берем папку vendor .pipe(sourcemaps.init()) //инициализируем soucemap .pipe(cssmin()) //Сожмем.pipe(sourcemaps.write()) //пропишем sourcemap .pipe(gulp.dest(path.build.css)) //выгрузим в build .pipe(connect.reload()) //перезагрузим сервер });
Также добавим таск для билда общего CSS:
// билдим css целиком gulp.task("css:build", [ "cssOwn:build", // "cssVendor:build" ]);
В случае если требуется обработать внешние стили отдельно от домашних и выгрузить их отдельными файлами нужно раскомментировать строчку "cssVendor:build"
Для того чтобы нам не приходилось билдить каждую часть отдельно, пропишем таск для общего билда:
// билдим все gulp.task("build", [ "html:build", "jshint:build", "js:build", "sprites:build", "css:build", "fonts:build", "htaccess:build", "image:build", "imagescontent:build" ]);
Иногда требуется полностью очистить каталог build . Здесь нам на помощь придет следующий таск:
// чистим папку билда gulp.task("clean", function (cb) { rimraf(path.clean, cb); });
Одной из самых важных и полезных функций Gulp является функция watch , которая позволяет отслеживать в реальном времени все изменения с производимыми файлами и в зависимости от этого выполнять конкретные действия:
// watch gulp.task("watch", function(){ //билдим html в случае изменения watch(, function(event, cb) { gulp.start("html:build"); }); //билдим спрайты в случае изменения watch(, function(event, cb) { gulp.start("sprites:build"); }); //билдим контекстные изрображения в случае изменения watch(, function(event, cb) { gulp.start("imagescontent:build"); }); //билдим css в случае изменения watch(, function(event, cb) { gulp.start("css:build"); }); //проверяем js в случае изменения watch(, ["jshint"]); //билдим js в случае изменения watch(, function(event, cb) { gulp.start("js:build"); }); //билдим статичные изображения в случае изменения watch(, function(event, cb) { gulp.start("image:build"); }); //билдим шрифты в случае изменения watch(, function(event, cb) { gulp.start("fonts:build"); }); //билдим htaccess в случае изменения watch(, function(event, cb) { gulp.start("htaccess:build"); }); });
Действия по-умолчанию - это то какие задачи будет выполнять таск-менеджер при вводе команды gulp в консоль:
// действия по умолчанию gulp.task("default", ["build", "watch", "connect"]);
В нашем случае по-умончанию мы сбилдим наш проект, включим режим watch и запустим сервер.
Все команды гальпа для командной строки состоят из двух частей это непосредственно сама команда gulp и через пробел имя таска. Вот список команд применимых для нашего конфига:
На данном этапе настройка gulpfile.js закончена.
Для начала зайдем через консоль в папке где мы ведем разработку, например cd develop/example и скопируем все из директории стартового пакета в наш проект cp -a ~/develop/start/. ~/develop/example/
Такой способ копирования наиболее удобен, т.к. точно скопирует все, в том числе и скрытые файлы.gitignore и пр.
Используя данное руководство мы подготовили стартовый пакет для использования Gulp в своих проектах для Front-end разработки.
Так же данный пакет доступен на GitHub
Данная статья не является заключительной и будет обновляться в зависимости от изменений и улучшений.