Gulp
Введение
Gulp — это таск-менеджер для автоматического выполнения часто используемых задач
(например, минификации, тестирования, объединения файлов), написанный на
языке программирования
JavaScript
.
Программное обеспечение использует
командную строку для запуска задач, определённых в файле
Gulpfile.
Создан как ответвление от проекта Grunt, чтоб взять из него лучшие практики.
Распространяется через менеджер пакетов
NPM
под MIT лицензией.
Если Вы будете копировать код с этой страницы - имейте в виду, что я ставлю кое-где лишние
проблелы - исключительно для того, чтобы текст лучше помещался на экран. Смело удаляйте их.
Это основная статья об использовании Gulp.
В данный момент Вы можете помимо этой прочитать также статьи:
Установка
Рассмотрим установку с помощью
npm. Подразумевается, что
nodejs
Вы уже установили.
О том как установить 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
Посмотрим, как изменился наш файл package.json
Подробнее о том, зачем этот файл нужне читайте в статье
npm
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
Как объединить .css файлы в один и уменьшить их с помощью Gulp
Более сложный пример -
Как отправлять файлы по ftp с помощью Gulp
Самый сложный пример -
Отправить только измененённые файлы с помощью 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
РЕКЛАМА от Яндекса. Может быть недоступна в вашем регионе
Конец рекламы. Если там пусто считайте это рекламой моей телеги