Gulp команды. Gulp для ускорения разработки
Всем привет. Если вы связаны хоть как-то с JS, вы наверняка слышали о таком приложении как gulp . А возможно даже и использовали. По своему опыту могу сказать, что «въехать» в то, как с ним работать бывает сложно, хотя ключ к пониманию лежит на поверхности. Поэтому и публикую этот материал, надеясь, что он станет полезным.
Так же, на основе данного материала был снят видеоролик, так что можете выбирать, в каком виде потреблять.
Если сравнить gulp с другими популярными системами сборки, то это как сравнивать готовый квадрокоптер по типу “купил и полетел”, и набор для самостоятельной сборки дрона. Да, взлетите вы только на следующий день, но зато у ваших руках больше гибкости и контроля, особенно если у вас нестандартная задача.
На самом деле, после преодоления порога входа, gulp выглядит не так уж и сложно, и моментами даже понятно и логично. Но, без должной подготовки придти к такому состоянию может быть непросто. Давайте же нырнем в самое оно и рассмотрим, на каких принципах построен gulp.
Зайдем издалека. В экосистеме nodejs, существует такое понятие, как потоки , или stream. Из-за сложности перевода, потоками так же называются нити или threads многопоточной программы. В нашем же случае, поток - это объект, представляющий потоковые данные, и является совершенно иным понятием.
Так вот эти потоки предлагают удобный интерфейс для асинхронной работы с данными. Всем процессом чтения/записи занимается движок ноды, а мы имеет только соответствующие колбеки, когда появилась новая порция данных, когда произошла ошибка, когда поток закончился и т.п. Таким образом достигается эффективность ввода/вывода при минимальных затратах со стороны программиста.
Const fs = require("fs");
const input = fs.createReadStream("myfile");
input.on("data", (chunk) => {
console.log(chunk);
});
input.on("end", () => {
console.log("file is read");
});
Потоками в nodejs может быть практически все, начиная от файлов или строк заканчивая сокетами. Например, в известном фреймворке Express, HTTP запрос и ответ являются ни чем иным, как потоками. Потоки могут быть только на чтение, только на запись или и то и другое.
Есть у потоков одна полезная функция: их можно складывать между собой у цепочку, которая называется pipe. Таким образом, мы можем объединить несколько потоков между собой, и управлять им как одним целым. Выход одного потока идет на вход следующему и так до конца. Как можно догадаться из перевода слова pipe, это очень похоже на трубопровод.
Это позволяет определить нужный поток данных (опять сложность перевода. Здесь имеется в виду flow, или течение) прямо здесь и сейчас не дожидаясь, когда данные станут доступны.
Например, вот так вот мы можем определить, что мы хотим отдать как результат, а “как” отдавать уже занимается сам движок.
Const fs = require("fs");
const express = require("express");
var app = express();
app.get("/", function (req, res) {
fs.createReadStream("myfile")
.pipe(res);
});
app.listen(3000);
Обратите внимание, что обработчик запроса завершается до того, как файл даже откроется - остальное берет на себя движок ноды.
Gulp построен на аналогичном подходе. Это его преимущество, но это и его недостаток. Недостатком, как минимум, можно назвать из-за возникающей путаницы, поскольку gulp использует другие, похожие, но несовместимые потоки. Gulp плотно работает с файловой системой, поэтому он и использует потоки, которые представляют не столько поток данных, сколько отдельные виртуальные файлы, каждый со своим содержимым.
Если вы когда-нибудь слышали о vinyl - это как раз и есть реализация потоков, которые используют в gulp. Если мы возьмем стандартную задачу для галпа, и посмотрим что там внутри, то обнаружим, что на каждый вызов события data к нам приходит объект file, который и содержит всю необходимую информацию: имя файла, путь к файлу, рабочая директория и конечно же, его содержимое.
Const gulp = require("gulp");
gulp.task("default", function() {
gulp.src("./*.js")
.on("data", function(file) {
console.log("data callback");
console.log(file.inspect());
/* It outputs:
* data callback
*
Содержимое может быть представлено в двух форматах: в виде уже прочитанного буфера, или же в виде родного нодовского потока. Каждая ступень галповского пайпа берет на вход такие вот файлы, делает некую трансформацию и передает на выход следующей цепочке. Последняя цепочка обычно просто сохраняет их на диск.
Pipe(gulp.dest("dist/"));
Осознание факта того, что потоки в gulp другие ведет к просветлению и пониманию, поскольку это объясняет большинство проблем и ошибок.
Рассмотрим реальный пример. Вы хотите использовать browserify для склейки ваших JS файлов. Вы идете, и находите плагин gulp-browserify . Но видите приписку, которая говорит, что плагин deprecated, т.е. Устарел.
Как хорошо воспитанный программист вы отметаете этот вариант, и идете искать, а какое же решение не устарело. Находите официальные рецепты от gulp, и видите , что browserify работает с галпом напрямую. Ну как напрямую, через прослойку , которая как раз и переводит родной нодовский поток в виниловский поток, который понимает gulp. Без него ничего бы не заработало, поскольку это разные потоки.
Если вы хотите написать свою трансформацию, то можете использовать данный шаблон .
Как видим, здесь все просто: на каждый файл будет вызываться наш обработчик, который и выполнит модификации. Мы можем делать все что захотим: изменить содержимое файла, переименовать файл, удалить файл или добавить еще пару новых файлов в поток.
Как мы помним, содержимое файла в виниловском потоке может быть представлено в виде буфера или в виде потока данных. Однако не обязательно поддерживать и то другое. Всегда можно использовать пакет
Чтобы ускорить процесс фронтенд-разработки, мы автоматизируем выполнение некоторых задач с помощью сборщика Gulp.
Для этого нам понадобится пакетный менеджер NPM. Но, чтобы установить NPM, сначала надо установить Node.js.
Шаг 1. Установка Node
Заходим на официальный сайт https://nodejs.org и скачиваем рекомендованную версию.
Инсталлятор запускать с правами администратора.
После установки появятся 2 значка: Node.js и командная консоль Node.js coomand prompt. Нам они не пригодятся, так как мы не используем Node.js, а для запуска консоли есть более удобные варианты:
1. Использовать Командную консоль TotalCommander (Команды - Открыть командную консоль).
2. Зажать Shift и, кликнув правой кнопкой, открыть контекстное меню. В нем появится пункт "Открыть окно команд".
Запуск коммандной строки лучше производить, находясь в директории нужного вам проекта, в консоли сразу отобразится путь к нужной директории, это избавит от необходимости вводить путь вручную.
Для проверки версий node и npm наберите в командной строке
node -v и нажмите Enter
затем npm -v
Версии NPM обновляются обычно чаще, чем версии node, чтобы установить последнюю версию:
npm install npm@latest -g
Комманды npm, которые нам пригодятся
:
npm list
- список всех установленных пакетов
npm -g ls --depth=0
- список глобально установленнных пакетов
npm outdated
проверить, не устарели ли пакеты
npm update gulp
- обновление версий плагинов
npm init
- создать package.json
npm install package_name
- установить пакет (package_name - название нужного пакета)
npm install package_name --save-dev
- установить пакет и вносит запись о нем в package.json в секцию devDependencies
npm uninstall
package_name
- удаление пакета
npm install
- установить все пакеты, перечисленные в package.json
Перед запуском в продакшн npm shrinkwrap
- фиксируем версии пакетов,теперь npm install будет устанавливать именно их и вы будете уверены что все будет работать как надо
Сокращения
-v: --version
-g: --global
-S: --save
-D: --save-dev
-y: --yes
-n: --yes false
Шаг 2. Установка gulp
Сначала gulp надо установить глобально.
Запускаем командную консоль.
Иногда на некоторых ресурсах перед коммандой стоит значок доллара, например
$ npm install --global gulp-cli
Значок доллара не копировать, вставлять только саму комманду
npm install --global gulp-cli
Подсказка: чтобы вставлять скопированный текст в командную строку, открыть ком.строку, нажать ALT + SPACE -> Значения по умолчанию, поставить галочку Выделение мышью. Теперь можно выделить текст мышкой, скопировать, в ком. строке кликнуть правой кнопкой - текст вставится автоматически.
Шаг 3. Работа с gulp в конкретном проекте
3.1
Сначала создадим пакет зависимостей package.json
Файл package.json содержит информацию, которую мы внесем в терминале и список всех пакетов, которые мы используем в проекте.
При установке пакета с ключом --save-dev, пакет автоматически добавляется в package.json. Чтобы не устанавливать в каждом новом проекте все пакеты вручную, мы будем использовать уже готовый package.json с небходимыми нам модулями и зависимостями, расположив его в корне нашего проекта.
package.json генерируется с помощью команды npm init, которая выведет в консоль несколько вопросов для создания файла.
В пункте name по умолчанию отображается название вашего каталога с проектом.
Подсказка:
Вы можете сгенерировать это файл быстрее и проще, используя опцию --yes (автоматический ответ “да” на все вопросы):
npm init --yes
Полезно знать:
Вы можете установить значения по умолчанию, которые будут использоваться при каждом запуске npm init, а значит будут экономить вам время. После установки они сохраняются в.npmrc файлах.
Например:
npm config set init.author.name "Valentina Vladova"
npm config set init.author.email "[email protected]"
npm config set init.author.url "http://simpalmarket.com/"
npm set init-license MIT
npm set init-version 0.0.0
Затем запустить npm init, все указанные значения подтянутся в соответстующие переменные.
Когда npm init спросит про гит-репозиторий, пишите кратко user/repo — npm достаточно умён, чтобы раскрыть строчку в https://github.com/user/repo. npm также сгенерирует поля repository, bugs и homepage в нужном формате.
Итак, заходим в корневую папку проекта, вызываем командную консоль и набираем
npm init --yes
В корне проекта появится файл package.json с примерно таким содержанием
3.2
Установим gulp локально
В папке проекта в консоли вводим:
npm install --save-dev gulp
или сокращенно
npm i gulp --save-dev
В списке будут Warn - игнорируем.
Для проверки версии используем команду
gulp --version
В root-каталоге проекта появилась папка node_modules. В нее автоматически будут загружаться все модули и зависимости, которые мы будем устанавливать в проект. Папок с зависимостями может быть очень много, не смотря на то, даже если самих пакетов установлено не так уж и много. Это связано с тем, что в дополнение к основным пакетам устанавливаются программы, необходимые для корректной работы основного пакета. Ничего чистить и удалять из папки node_modules не нужно.
В файле package.json добавится запись
"devDependencies": {
"gulp": "^3.9.1"
}
Теперь можно устанавливать различные плагины для gulp.
http://gulpjs.com/plugins/
В поле поиска вводите название интересующего плагина.
Плагины можно устанавливать как по одному, например:
npm install --save-dev gulp-plumber
так и списком через пробел, например:
npm install gulp-sass gulp-plumber gulp-autoprefixer gulp-minify-css --save-dev
Плагины для установки и плагины для сборки лучше устанавливать отдельными командами
GulpJS - фантастически быстрый сборщик проектов
- Разработка веб-сайтов ,
- JavaScript ,
- Node.JS
В этой статье будет больше практики, мы соберем среду разработки фронтенда используя Jade и Stylus, запустим локальный сервер и подключим Livereload. Проект я выложил на Github , экспериментируйте.
Установка Gulp
У вас должен быть установлен Node.JS и npm.Создадим директорию проекта, создадим структуру каталогов и установим Gulp и необходимые плагины.
Струтура проекта:
|--/assets // Компоненты |--|--/template |--|--/stylus |--|--/js |--|--/img |--/build // Каталог релиза |--/public // Каталог разработки |--package.json |--gulpfile.jsУстановка:
$ mkdir assets public build assets/js assets/img assets/stylus assets/template $ touch gulpfile.js $ sudo npm install gulp -g $ npm init $ npm install gulp gulp-jade gulp-stylus gulp-livereload gulp-myth gulp-csso gulp-imagemin gulp-uglify gulp-concat connect --save-devВ корне проекта есть файл конфигурации gulpfile.js его и будем редактировать.
Иницилизируем плагины:
var lr = require("tiny-lr"), // Минивебсервер для livereload gulp = require("gulp"), // Сообственно Gulp JS jade = require("gulp-jade"), // Плагин для Jade stylus = require("gulp-stylus"), // Плагин для Stylus livereload = require("gulp-livereload"), // Livereload для Gulp myth = require("gulp-myth"), // Плагин для Myth - http://www.myth.io/ csso = require("gulp-csso"), // Минификация CSS imagemin = require("gulp-imagemin"), // Минификация изображений uglify = require("gulp-uglify"), // Минификация JS concat = require("gulp-concat"), // Склейка файлов connect = require("connect"), // Webserver server = lr();Задачи:
Теперь создадим первую задачу// Собираем Stylus gulp.task("stylus", function() { gulp.src("./assets/stylus/screen.styl") .pipe(stylus({ use: ["nib"] })) // собираем stylus .on("error", console.log) // Если есть ошибки, выводим и продолжаем.pipe(myth()) // добавляем префиксы - http://www.myth.io/ .pipe(gulp.dest("./public/css/")) // записываем css .pipe(livereload(server)); // даем команду на перезагрузку css });
В Gulp мы работаем с потоком, поэтому получаем данные из gulp.src и поточно обрабатываем их.
Так же создадим задачи по обработке Jade, изображений и JS
// Собираем html из Jade
gulp.task("jade", function() {
gulp.src(["./assets/template/*.jade", "!./assets/template/_*.jade"])
.pipe(jade({
pretty: true
})) // Собираем Jade только в папке./assets/template/ исключая файлы с _*
.on("error", console.log) // Если есть ошибки, выводим и продолжаем.pipe(gulp.dest("./public/")) // Записываем собранные файлы.pipe(livereload(server)); // даем команду на перезагрузку страницы
});
// Собираем JS
gulp.task("js", function() {
gulp.src(["./assets/js/**/*.js", "!./assets/js/vendor/**/*.js"])
.pipe(concat("index.js")) // Собираем все JS, кроме тех которые находятся в./assets/js/vendor/**
.pipe(gulp.dest("./public/js"))
.pipe(livereload(server)); // даем команду на перезагрузку страницы
});
// Копируем и минимизируем изображения
gulp.task("images", function() {
gulp.src("./assets/img/**/*")
.pipe(imagemin())
.pipe(gulp.dest("./public/img"))
});
Для комфортной разработки создадим локальный сервер
// Локальный сервер для разработки
gulp.task("http-server", function() {
connect()
.use(require("connect-livereload")())
.use(connect.static("./public"))
.listen("9000");
console.log("Server listening on http://localhost:9000");
});
Необходимые нам выше задачи предназначены для разработки и конечно хочется отслеживать изменения файлов и иметь на сервере Livereload
Для этого создадим задачу "watch".
// Запуск сервера разработки gulp watch gulp.task("watch", function() { // Предварительная сборка проекта gulp.run("stylus"); gulp.run("jade"); gulp.run("images"); gulp.run("js"); // Подключаем Livereload server.listen(35729, function(err) { if (err) return console.log(err); gulp.watch("assets/stylus/**/*.styl", function() { gulp.run("stylus"); }); gulp.watch("assets/template/**/*.jade", function() { gulp.run("jade"); }); gulp.watch("assets/img/**/*", function() { gulp.run("images"); }); gulp.watch("assets/js/**/*", function() { gulp.run("js"); }); }); gulp.run("http-server"); });
Теперь можно запустить наш проект и посмотреть, что получилось.
$ gulp watch
Сервер доступен по адресу localhost:9000 Мы создали среду для веб-разработке проектов с помощью Stylus и Jade с Livereload. Теперь нужно собрать оптимизированный проект. Для этого создадим задачу "build"
Всем привет! В этой статье мы создадим наш проект, инициализируем файл манифеста и установим Gulp локально.
Для начала следует сказать, что путь до папки(в том числе и имя пользователя компьютера) должен быть на английском языке, иначе у вас могут возникнуть ошибки при использовании Gulp . Я создал папку Projects , в которой буду создавать все свои проекты. Для примера я назову наш проект firstProject .
Итак, в прошлой статье мы установили Gulp глобально, теперь же нам нужно установить его локально. В первую очередь мы проведем инициализацию. Напишите в терминале следующую команду:
Cd путь_до_вашего_проекта (cd "user/projects/firstProject")
npm init
Благодаря этой команде мы создадим базовый файл манифества для нашего проекта. В принципе, там все понятно, поэтому пояснять не буду. Если вы не хотите заморачиваться со всеми этими настройками, то просто жмите все время enter , т.к. этот файлик нам понадобится для другого, начальные настройки не так важны.
Если вы все сделали правильно, то в вашей папке с проектом должен появиться файл package.json . Если вы откроете его, то увидите, что там хранится вся та информация, которую вы ввели(или не ввели) при инициализации. Помимо этого, файлик хранит информацию об используемых пакетах и это именно то, что нам нужно. Если вы постоянно используете, например, библиотеку JQuery , то вы можете записать ее в этот файл, и она будет автоматически скачиваться при запуске нового проекта.
Теперь установим Gulp локально в нашу папку.
Npm i gulp --save-dev
Флаг --save-dev нужен для того, чтобы пакет Gulp и его версия автоматически записались в файл package.json . Если вы откроете этот файл после успешной установки пакета, то увидите, что там появилось следующее:
"devDependencies": {
"gulp": "^3.9.1"
}
Думаю, понятно, что тут написано имя пакета и его версия. Стрелочка вверх обозначает, что этот пакет можно обновлять. Также у нас появилась папка node_modules , где теперь хранится Gulp и все его зависимости. Именно сюда будут устанавливаться новые модули.
Итак, на этом сегодня все. Мы рассмотрели, как установить Gulp локально в папку проекта и зачем нужен манифест package.json .
Хотите набрать побольше баллов в Google Page Speed? Не знаете что такое «сборка front-end»? Тогда вам сюда, будет интересно.
Что такое Node.JS?
Node.JS принято называть «северным JavaScript». Эта платформа позволяет писать программы, используя синтаксис JavaScript.
Есть реализации для Windows, Mac OS и Linux.
В комплект входит менеджер пакетов NPM , с помощью которого можно устанавливать пакеты.
Что такое Gulp?
Gulp — это пакет, написанный на Node.JS, который помогает веб-мастерам осуществлять сборку проектов на этапе верстки макетов.
Для установки Gulp необходимо воспользоваться командной строкой.
Npm install gulp
В конце данной статьи находится файл, который поможет собрать типовой проект.
В этом примере с помощью Gulp мы сделаем следующее:
- Автоматически оптимизируем изображения для веба;
- Собираем один минифицированный файл стилей из предпроцессоров (SASS, SCSS);
- Собираем один минифицированный файл со скриптами;
Как собирать front-end с помощью Gulp?
Чтобы понять, как все работает, разберем все по шагам.
Структуру можно посмотреть на скриншоте.
- Папка assets — для исходников изображений, стилей и скриптов;
- Папка public — результат сборки проекта будет находится именно в ней;
- gulpfile.js — файл, в котором описана логика работы сборщика;
- package.json — файл, в котором содержатся информация о программах и плагинах, использующихся для корректной работы Gulp.
package.json
Содержимое файла:
{ "name": "gulp_project", "version": "1.0.0", "description": "Example", "main": "gulpfile.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "author": "Dmitriy Ilichev", "license": "ISC", "devDependencies": { "gulp": "^3.9.0", "gulp-csso": "^1.0.0", "gulp-concat": "^2.6.0", "gulp-uglify": "^1.2.0", "gulp-imagemin": "^2.3.0", "gulp-sass": "^2.1.1" } }
Из этого файла понятно следующее:
- Название проекта gulp_project, версия и описание;
- Главный файлом является gulpfile.js;
- Автор проекта, лицензия — все это не столь важно и попросту эти поля могут быть пустыми;
- Интересным пунктом является devDependencies . В нем описаны зависимости.
Файл можно отредактировать в обычном текстовом редакторе. Его также можно создать для нового проекта командой npm int.
Исходя из этого, Node.JS понимает, что для работы нам понадобятся:
- Gulp версии 3.9.0 и выше для сборки;
- Gulp-csso версии 1.0.0 и выше — плагин для минификации стилей (css);
- Gulp-concat версии 2.6.0 и выше — плагин для склейки нескольких файлов в один;
- Gulp-uglify версии 1.2.0 и выше — плагин для минификации javascript;
- Gulp-imagemin версии 2.3.0 и выше — плагин для оптимизации изображений;
- Gulp-sass версии 2.1.1 и выше — плагин для получения css из sass (scss);
Отлично! После этого нужно все это установить. Делается это из командной строки. Находясь в папке с проектом нужно выполнить команду:
Npm install
Вся необходимая информация будет взята из package.json.
После всего этого волшебства появится служебная папка node_modules .
gulpfile.js
Содержимое файла:
/* * * Определяем переменные * */ var gulp = require("gulp"), // Сообственно Gulp JS uglify = require("gulp-uglify"), // Минификация JS concat = require("gulp-concat"), // Склейка файлов imagemin = require("gulp-imagemin"), // Минификация изображений csso = require("gulp-csso"), // Минификация CSS sass = require("gulp-sass"); // Конверстация SASS (SCSS) в CSS /* * * Создаем задачи (таски) * */ // Задача "sass". Запускается командой "gulp sass" gulp.task("sass", function () { gulp.src("./assets/styles/style.scss") // файл, который обрабатываем.pipe(sass().on("error", sass.logError)) // конвертируем sass в css .pipe(csso()) // минифицируем css, полученный на предыдущем шаге.pipe(gulp.dest("./public/css/")); // результат пишем по указанному адресу }); // Задача "js". Запускается командой "gulp js" gulp.task("js", function() { gulp.src([ "./assets/javascripts/jquery-2.1.4.min.js", "./assets/javascripts/bootstrap.min.js", "./assets/javascripts/script.js" ]) // файлы, которые обрабатываем.pipe(concat("min.js")) // склеиваем все JS .pipe(uglify()) // получившуюся "портянку" минифицируем.pipe(gulp.dest("./public/js/")) // результат пишем по указанному адресу }); // Задача "images". Запускается командой "gulp images" gulp.task("images", function() { gulp.src(".assets/images/**/*") // берем любые файлы в папке и ее подпапках.pipe(imagemin()) // оптимизируем изображения для веба.pipe(gulp.dest("./public/images/")) // результат пишем по указанному адресу }); // Задача "watch". Запускается командой "gulp watch" // Она следит за изменениями файлов и автоматически запускает другие задачи gulp.task("watch", function () { // При изменение файлов *.scss в папке "styles" и подпапках запускаем задачу sass gulp.watch("./assets/styles/**/*.scss", ["sass"]); // При изменение файлов *.js папке "javascripts" и подпапках запускаем задачу js gulp.watch("./assets/javascripts/**/*.js", ["js"]); // При изменение любых файлов в папке "images" и подпапках запускаем задачу images gulp.watch("./assets/images/**/*", ["images"]); });
Главная фишка — в задаче watch . Запустив ее один раз, можно спокойно работать с источниками, и проект будет автоматически собираться при каждом сохранении редактируемых файлов.
На выходе получим готовый к публикации в интернете шаблон.
Задачи можно запускать отдельно. В итоге, в архиве в конце статьи вас ждет следующее:
! Обратите внимание на то, что распаковав у себя этот архив, прежде всего необходимо будет выполнить команду npm install. Папка эта содержит довольно большое количество файлов, и каждый раз копировать/вставлять их — пустая трата времени.
В заключении
Есть огромное множество других полезных плагинов. Например, прекрасный шаблонизатор Jade, который в разы ускоряет написание html кода, кому-то может понадобится LESS и так далее.
Представленный пример — всего лишь платформа и шаблон, с которого быстро и без особых знаний можно начать пользоваться всеми этими прекрасными фишками.