GeekBrains
300*600
↑↑

↓↓
Флаг России Флаг Англии
🏠 | 💻 IT |

Gulp

Введение

Gulp — это таск-менеджер для автоматического выполнения часто используемых задач (например, минификации, тестирования, объединения файлов), написанный на языке программирования JavaScript.

Программное обеспечение использует командную строку для запуска задач, определённых в файле Gulpfile.

Создан как ответвление от проекта Grunt, чтоб взять из него лучшие практики. Распространяется через менеджер пакетов NPM под MIT лицензией.

Если Вы будете копировать код с этой страницы - имейте в виду, что я ставлю кое-где лишние проблелы - исключительно для того, чтобы текст лучше помещался на экран. Смело удаляйте их.

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

Как скопировать папку с помощью Gulp
Как отправить файлы по ftp с помощью Gulp
Gulp series
Обработка только изменённых файлов с помощью gulp.watch().on('change')

Установка

Рассмотрим установку с помощью npm. Подразумевается, что nmp Вы уже установили.

О том как установить npm читайте в моей статье Установка npm

О том как установить более старую версию Gulp - Установка архивной версии Gulp

$ npm install gulp-cli --global

C:\Users\ao\AppData\
Roaming\npm\gulp ->

C:\Users\ao\AppData\Roaming\npm\
node_modules
\gulp-cli\bin\gulp.js

+ gulp-cli@2.2.0

updated 7 packages in 7.386s

Проверить версию gulp

gulp -v

CLI version: 2.2.0 Local version: Unknown

Про установку не последней, а какой-то определённой версии Gulp читайте здесь

Теперь нужно перейти в директорию, в которой Вы планируете работать. Я буду делать сайт www.HeiHei.ru поэтому перехожу в директорию

$ cd /c/Users/ao/Desktop/Sites/heihei

Затем переходим непосредственно к установке gulp в текущий проект

$ npm install gulp --save-dev

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

Подробнее docs.npmjs.com

Посмотрим, как изменился наш файл pacakge.json

vi package.json

{ "name": "heihei", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "author": "", "license": "ISC", "dependencies": { "jquery": "^3.4.1", "normalize.css": "^8.0.1" }, "devDependencies": { "gulp": "^4.0.2" }, "repository": { "type": "git", "url": "git+https://github.com/ao/heiheiru.git" }, "bugs": { "url": "https://github.com/ao/heiheiru/issues" }, "homepage": "https://github.com/ao/heiheiru#readme" }

Появился раздел devDependencies, в который в будущем я добавлю ещё довольно много пакетов.

Если теперь посмотреть содержимое папки node_modules можно увидеть, что установка Gulp добавила не одну папку, как, например, сделал бы jquery а несколько десятков.

Старые версии npm создавали всегда одну папку и размещали все зависимости туда.

Новые версии npm сохраняют зависимости в родительскую папку node_modules.

Установка более старой версии

Иногда бывает нужно установить не текущую, а более ранню версию Gulp.

Особенно это касается версии 3.9.1 , которая сильно отличается от 4 и выше.

Сделать это можно добавив нужную версию после @

npm install gulp@3.9.1 --save-dev

npm install gulp-cli@1.2.1 --save-dev

Список версий Gulp находится здесь, Gulp-cli - здесь. Нужно открыть вкладку Versions

Если Вы хотите сперва удалить Вашу версию Gulp а уже потом установить другую - сделать это можно командой uninstall

npm uninstall gulp

Gulpfile.js

После установки Gulp нужно в корневой директории проекта (в моём случае - heiheiru) создать файл gulpfile.js в который мы будем записывать инструкции для Gulp.

Первым делом запишем туда

const gulp = require('gulp');

Начиная с верси 4.0 можно пользоваться новым синтаксисом JavaScript (ES2015+)

import gulp from 'gulp'

Но для этого нужно устанавливать babel и следить чтобы не было ошибок. Я видел на форумах жалобы, сам пока не пробовал.

Подробности www.npmjs.com

После того как файл gulpfile.js создан можно запустить Gulp

gulp

Результатом будет похожее сообщение

[11:22:35] Using gulpfile ~\Desktop\Sites\heihei\gulpfile.js

[11:22:35] Task never defined: default

[11:22:35] To list available tasks, try running: gulp --tasks

Gulp жалуется на то, что не определно задание по умолчанию - default task

Нужно его определить

vi gulpfile.js

const gulp = require('gulp'); gulp.task('default', function() { console.log("Gulp is running!"); });

gulp

default запустится но теперь Gulp пожалуется на непонятное закрытие.

[11:31:44] Using gulpfile ~\Desktop\Sites\heihei\gulpfile.js
[11:31:44] Starting 'default'...
Gulp is running!
[11:31:44] The following tasks did not complete: default
[11:31:44] Did you forget to signal async completion?

Эту ошибку можно устранить несколькими способами. Подробности здесь. Я пользуюсь следующим:

const gulp = require('gulp'); gulp.task('default', function(cb) { console.log("Gulp is running!"); cb() });

gulp

Организация файлов

Чтобы не создавать каши из файлов и папок организуем всё правильно с самого начала.

Корневая папка носит называние проекта. В моё случае heihei или heiheiru

В этой папке мы инициализируем GIT и npm.

npm создаст папку node_modules и файлы package.json , package-lock.json.

Для GIT мы сами рано или поздно создадим файл gitignore

Так как мы будем пользоваться Gulp появится и файл gulpfile.js

С ростом числа заданий, которые будет выполнять Gulp нам станет неудобно хранить их все в одном файле. В gulpfile.js мы будем только импортировать другие .js файлы по принципу - на каждое задание один файл.

Чтобы хранить эти файлы нам будет нужна папка, назовём её gulp и создадим в корневой. Внутри неё создадим подпапку tasks

Всё, что относится непосредственно к сайту положим в папку heiheiru/app

index.html положим в корень app а .css файлы, картинки и скрипты мы положим в папки heiheiru/app/assets/styles heiheiru/app/assets/images , heiheiru/app/assets/scripts

Так будет выглядить дерево папок в редакоторе Sublime

Как организовать папки для веб разработки

Примеры использования Gulp

Простой пример - как рекурсивно скопировать папку с помощью Gulp и добавить логи разобран в статье - Как скопировать папку с помощью Gulp

Более сложный пример - Как отправлять файлы по ftp с помощью Gulp

Обработка файлов стилей

При разработке удобно пользоваться метаязыками, например, SASS.

Установим его с помощью npm

npm install gulp-sass --save-dev

Теперь можно объявить переменную sass и пользоваться этим препроцессором

const gulp = require('gulp'); const sass = require('gulp-sass'); const browserSync = require( 'browser-sync' ).create(); gulp.task('default', function(done) { console.log("Gulp is running!"); done(); }); // compile scss into css function style() { // 1. указываем расположение .scss файлов return gulp.src('./scss/**/*.scss') // 2. пропускаем их через sass compiller .pipe(sass()) // 3. указываем CSS файл, в который запишется результат? .pipe(gulp.dest( './css/style.css' ) ) } exports.style = style;

const и let - были введены в JavaScript начиная с ES6 и для современного JavaScript являются более предпочтительным вариантом чем var

gulp-watch

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

Начнём с простого - делаем функцию, которая при каждом изменении файла index.html в папке app будет выводить предупреждение.

Как это выглядит в Gulp 4

// Подтягиваем gulp // gulp-watch можно не подтягивать // - он влючен в Gulp начиная с 4-й версии const gulp = require('gulp'); // пишем функцию, выводящую в лог предупреждение function html() { console.log("Кто-то отредактировал index.html!"); } // Пишем функцию, // которая следит за файлом index.html // можно назвать её просто watch, но в образовательных // целях я назову её watchFiles // зачем - будет видно чуть ниже - в exports function watchFiles() { gulp.watch( "./app/assets/index.html", html); } // Чтобы обращаться к нашим функция извне, // например, из GitBash запишем exports // Слева запишем названия видимые извне, // а справа имена наших функций exports.html = html; exports.watch = watchFiles; // - он влючен в Gulp начиная с 4-й версии const gulp = require('gulp'); // пишем функцию, выводящую в лог предупреждение function html() { console.log("Кто-то отредактировал index.html!"); } // пишем функцию, которая следит за файлом index.html // можно назвать её просто watch, но в образовательных // целях я назову её watchFiles // зачем - будет видно чуть ниже - в exports function watchFiles() { gulp.watch( "./app/assets/index.html", html); } // Чтобы обращаться к нашим функция извне, // например, из GitBash запишем exports // Слева запишем названия видимые извне, // а справа имена наших функций exports.html = html; exports.watch = watchFiles;

Чтобы запустить мониторинг пишем

gulp watch

[20:12:19] Using gulpfile ~\Desktop\Sites\heihei\gulpfile.js
[20:12:19] Starting 'watch'...

Теперь вносим изменения в файл index.html и сохраняем

[20:14:28] Starting 'html'...
Кто-то отредактировал index.html!

Как это выглядело в Gulp 3

// Подтягиваем gulp и gulp-watch const gulp = require('gulp') watch = require('gulp-watch'); gulp.task('html', function() { console.log( "Кто-то отредактировал index.html!"); } gulp.task('watch', function() { watch( './app/assets/index.html', function() { gulp.start('html'); }); });

Создадим папку /app/assets/styles/ , в которой будут файлы .css для разработки

Напишем функцию, которая будет собирать все файлы .css из этой папки, обрабатывать их с помощью sass и соединять в один файл /app/temp/styles/style.css

Мы уже писали такую функцию выше, просто немного изменим её.

Добавим мониторинг файлов CSS gulp.watch( "./app/assets/styles/**/*.css", style);

function style() { console.log( "style is running!" ); // 1. return gulp.src( './app/assets/styles/*.css' ) // 2. pass that file through sass compiller .pipe(sass()) // 3. where do I save the compiled CSS? .pipe( gulp.dest( './app/temp/styles/style.css' ) ) } function watchFiles() { gulp.watch( "./app/assets/index.html", html ); gulp.watch( "./app/assets/styles/**/*.css", style ); }

Теперь как только мы отредактируем один из файлов стилей watch заметит это изменение, пропустит его через sass, соберет все файлы в один.

Зачем нужен SASS:

чтобы пользоваться css переменными. Создать переменную, которую потом вставлять в .css пропускать через sass compiler и когда вдруг везде нужно будет изменить значение этой переменной, например, на сайте изменится основной цвет, всё что нам нужно будет сделать - это поменять одну переменную в одном файле.

чтобы делать вложения в стилях (nested css)

чтобы использовать mixins

PostCSS

До этого Вы уже прочитали про препроцессор SASS, который наряду с LESS и Stylus является стандартом для многих проектов.

Я не пользуюсь ими, а предпочитаю более современный PostCSS, который имеет более модульную структуру, и соответственно более гибкий в настройке и быстрый

Какой бы пре или пост процессор Вы не выбрали, нужно освоить работу с ним, научиться выполнять простые задачи и переходить к более сложным задачам, таким как Обработка только изменённых файлов с помощью gulp.watch().on('change')

Подробнее про PostCSS Вы можете прочитать в статье PostCSS.

Советую разобраться с PostCSS и возвращаться в эту статью либо в одну из следующих, более продвинутых глав.

Я не стал размещать описание работы с PostCSS здесь, потому что его можно запускать не только с помощью Gulp

Видеоуроки Gulp

Видео много весят, поэтому я выделил для них отдельную страницу - Видеоуроки Gulp

Ошибки

SKIPPING OPTIONAL DEPENDENCY: fsevents

Ошибка при установке gulp. Вы выполняете

$ npm install gulp --save-dev

А на выходе

npm WARN saveError ENOENT: no such file or directory, open 'C:\Users\ao\Desktop\Sites\heihei\package.json'
npm notice created a lockfile as package-lock.json. You should commit this file.
npm WARN enoent ENOENT: no such file or directory, open 'C:\Users\ao\Desktop\Sites\heihei\package.json'
npm WARN heihei No description
npm WARN heihei No repository field.
npm WARN heihei No README data

npm WARN heihei No license field.
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@1.2.9 (node_modules\fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@1.2.9: wanted {"os":"darwin","arch":"any"} (current: {"os":"win32","arch":"x64"})

+ gulp@4.0.2
added 314 packages from 217 contributors and audited 6490 packages in 30.037s
found 0 vulnerabilities

Скорее всего Вы не инициализировали npm. Нужно выполнить

npm init

Ввести нужные данные (либо просто нажимать Enter), после чего создастся файл package.json и можно будет вернуться к установке gulp

Unhandled 'error' event

events.js:174 throw er; // Unhandled 'error' event
^
CssSyntaxError: postcss-simple-vars: C:\Users\ao\Desktop\Sites\travel-site\app\assets\styles\modules\_large-hero.css:5:2: Undefined variable $aMadeUpVariable2

Может быть вызвана, например, несуществующей переменной. Допустим Вы добавили цвет как переменную, но нигде её не задали.

Unexpected identifier

Если Вы запустили Gulp

gulp

И получили что-то похожее

SyntaxError: Unexpected identifier
      at Module._compile (internal/modules/cjs/loader.js:723:23)

      at Object.Module._extensions..js (internal/modules/cjs/loader.js:789:10)

      at Module.load (internal/modules/cjs/loader.js:653:32)

      at tryModuleLoad (internal/modules/cjs/loader.js:593:12)

      at Function.Module._load (internal/modules/cjs/loader.js:585:3)

      at Module.require (internal/modules/cjs/loader.js:692:17)

      at require (internal/modules/cjs/helpers.js:25:18)

      at execute (C:\Users\ao\AppData\Roaming\npm\
node_modules\gulp-cli\lib\versioned\^4.0.0\index.js:36:18)

      at Liftoff.handleArguments (C:\Users\ao\AppData\Roaming\npm\
node_modules\gulp-cli\index.js:201:24)

      at Liftoff.execute (C:\Users\ao\AppData\Roaming\npm\
node_modules\gulp-cli\node_modules\liftoff\index.js:201:12)

Скорее всего Вы пытаетесь использовать синтаксис ES2015+ и не установили babel или он работает но с ошибкой.

Здесь два выхода - разобраться и настроить либо перейти к старому синтаксису с require

Did you forget to signal async completion?

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

Эту ошибку можно устранить несколькими способами. Я пользуюсь самым простым - в таске использую не анонимную функцию а называю функцию, например cb (от слова callback), а в конце таска вызваю её без аргументов:

const gulp = require('gulp'); gulp.task('default', function(cb) { console.log("Gulp is running!"); cb(); });

5

npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@1.2.9 (node_modules\fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@1.2.9: wanted {"os":"darwin","arch":"any"} (current: {"os":"win32","arch":"x64"})

Это предупреждение о несовместимости пакета fsevents с Windows, как Вы можете убедиться здесь fsevents нужен для работы с iOS поэтому можно просто проигнорировать.

Error - Task function must be specified

Эту ошибку я разбираю в статье Gulp series

No PostCSS Config found in

Эту ошибку я разбираю в статье Postcss

Вы нашли то, что искали на сайте?

Или оцените по десятибальной шкале

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

Например: у нас есть статья про аэропорт Хельсинки и про аэропорт Риги но в выдаче по Риге всё равно статья про Хельсинки.

Если статья Вам помогла, нажимайте ДА. Так мы поймём, что переделывать её не нужно.

Занятно наблюдать в вебвизоре, как люди копируют текст, например вежливого отказа в трудоустройстве на английском но игнорируют кнопку ДА.

Сделаем поиск лучше!

Контакты и сотрудничество:
Рекомендую наш хостинг beget.ru
Пишите на info@urn.su если Вы:
1. Хотите написать статью для нашего сайта или перевести статью на свой родной язык.
2. Хотите разместить на сайте рекламу, подходящуюю по тематике.
3. Реклама на моём сайте имеет максимальный уровень цензуры. Если Вы увидели рекламный блок недопустимый для просмотра детьми школьного возраста, вызывающий шок или вводящий в заблуждение - пожалуйста свяжитесь с нами по электронной почте
4. Нашли на сайте ошибку, неточности, баг и т.д. ... .......
5. Статьи можно расшарить в соцсетях, нажав на иконку сети:
Braun RU
Росгосстрах [CPS] RU