Установка Gulp
Установка Gulp досить проста. Для початку встановіть пакет Gulp глобально:
<code>npm install-g gulp
Потім встановіть його у свій проект:
<code> npm install--save-dev gulp
Використання Gulp
Давайте створимо завдання Gulp для мінімізації одного з наших файлів JavaScript. Створіть файл із ім'ям gulpfile.js. У ньому будуть визначатися ваші завдання, які запускаються за допомогою команди gulp. language="javascript">var gulp=require('gulp'), uglify=require('gulp-uglify'); gulp.task('minify', function () { gulp.src('js/app.js') .pipe(uglify()) .pipe(gulp.dest('build')) });
Встановіть gulp-uglify через npm, виконавши npm install--save-dev gulp-uglify, а потім запустіть завдання через gulp minify. Припустимо, у вас є файл з ім'ям app.js у папці js, новий app.js буде створено в папці build і міститиме стислу версію js/app.js.
Що насправді тут відбувається?
Ми робимо кілька речей у нашому файлі gulpfile.js. Спочатку ми завантажуємо модулі gulp і gulp-uglify:
<code data-language="javascript">var gulp=require('gulp'), uglify=require('gulp-uglify');
Тому визначаємо завдання з ім'ям minify, яке при запуску викликає функцію, задану як другий аргумент:
<code data-language="javascript">gulp.task(' minify', function () { });
Наприкінці, і це найскладніше, ми визначаємо, що наше завдання має робити:
<code data-language="javascript">gulp.src('js/app.js') .pipe(uglify()) .pipe(gulp.dest('build'))
Якщо ви не знайомі з потоками, а більшість фронтенд-розробників з ними не знайомі, то код вище нічого вам не скаже. , які модифікують дані, а потім передають їх наступній функції.
У наведеному вище прикладі функція gulp.src() отримує рядок, який відповідає файлу мул і набору файлів, і створює потік об'єктів, що представляють ці файли. Потім вони переходять (або перетікають) у функцію uglify(), яка приймає об'єкти файлів та повертає нові об'єкти файлів із мінімізованим вихідним кодом. Цей результат потім перетікає у функцію gulp.dest(), яка зберігає змінені файли.
Ось що відбувається у вигляді схеми:
Коли є лише одне завдання, функція нічого не робить. Тим не менш, розглянемо наступний код:
<code data-language="javascript">gulp.task('js', function() { return gulp.src('js/*.js') .pipe(jshint()) .pipe(jshint.reporter('default')) .pipe(uglify()) .pipe(concat('app.js')) .pipe(gulp.dest('build')) });
Щоб запустити це самостійно, встановіть gulp, gulp-jshint, gulp-uglify та gulp-concat.
Це завдання бере всі файли відповідні js/*.js (іншими словами всі файли JavaScript з папки js), запускає для них JSHint, виводить звіт, мінімізує кожен файл, а потім об'єднує їх, зберігаючи їх у build/app.js. У вигляді схеми:
Якщо ви знайомі з Grunt, то помітите, що це досить сильно відрізняється від того, як працює Grunt. Grunt не використовує потоки. Натомість він бере файли, запускає одну задачу для кожного файлу і зберігає нові файли, повторюючи весь процес для кожного завдання. В результаті безлічі звернень до файлової системи, Grunt працює повільніше, ніж Gulp.
Для кращого розуміння потоків прочитайте Stream Handbook.
gulp.src()
Функція gulp.src() бере один або кілька файлів або масив і повертає потік, який може бути переданий у плагіни.
Gulp використовує node-glob для отримання вказаних файлів. Найпростіше пояснити на прикладах:
- js/app.js
- js/*.js
- js/**/*.js
- !js/app. js
- *.+(js|css)
Відповідає певному файлу.
Відповідає всім файлам, що закінчуються на . js у папці js.
Відповідає всім файлам з розширенням .js у папці js та всіх вкладених папках.
Виключає js/app.js з відповідності, що корисно якщо ви бажаєте вибрати всі файли в папці за винятком певного файлу.
Відповідає всім файлам, Інші функції також доступні, але в Gulp вони зазвичай не застосовуються. Перегляньте документацію Minimatch заради подробиць.
Припустимо, у нас є папка з ім'ям js, містить JavaScript, деякі мінімізовані, а деякі ні. Ми хочемо створити задачу мінімізації ще не зменшених файлів. Щоб зробити це, ми вибираємо всі файли JavaScript у папці, за винятком усіх файлів, що закінчуються .min.js:
<code data-language="javascript">gulp.src(['js/* */ *.js', '!js/**/*.min.js'])
Визначення задач
Щоб визначити завдання використовуйте функцію gulp.task(). Для простої задачі ця функція приймає два параметри: ім'я задачі та функція для запуску.
<code data-language="javascript">gulp.task('greet', function() Доброго дня, мир!'); Завдання також може бути списком інших завдань. Припустимо, ми хочемо визначити завдання build, яке виконує три інші завдання: css, js та imgs. Ми можемо зробити це, вказавши замість функції масив із завданнями: gulp.task('build', ['css', 'js', 'imgs']);
Вони будуть запускатися асинхронно, так що ви не можете припускати, що коли завдання css завершиться, то запуститься завдання js — насправді це, швидше за все, не відбудеться. Щоб переконатися, що завдання завершило роботу перед запуском іншого завдання, ви можете вказати залежність шляхом об'єднання масиву задач з функцією. Наприклад, щоб визначити завдання css, яке перед запуском перевірить, що завдання greet завершено, ви можете зробити так:
<code data-language="javascript">gulp.task('css', ['greet '], function () { //Робимо щось із CSS });
Тепер, коли ви запустите завдання css, Gulp виконає завдання greet, почекає, поки воно закінчиться, а потім викличе вказану функцію.
Завдання за замовчуванням
Ви можете визначити завдання default, яке виконується, коли ви просто запускаєте gulp. Ви можете зробити це, визначивши завдання з ім'ям default.
<code data-language="javascript">gulp.task('default', function () { //Завдання за замовчуванням });
Плагіни
Разом з Gulp ви можете використовувати ряд плагінів — понад 600 насправді. Ви знайдете їх список на сторінці плагінів, або шляхом пошуку gulpplugin в npm. Деякі плагіни позначені «gulpfriendly»; це не плагіни, але вони призначені для роботи з Gulp. Зверніть увагу, що при пошуку безпосередньо в npm, ви не побачите плагіни з чорного списку (прокрутіть сторінку з плагінами вниз і побачите більше).
Більшість плагінів досить прості у використанні, мають хорошу документацію та запускаються аналогічним чином (через потік файлових об'єктів). Вони, як правило, модифікують файли (хоча деякі, начебто валідатори, ні) і повертають нові файли, які передаються в наступний плагін.
Давайте розширимо вже згадане завдання js:
<code data-language="javascript">var gulp=require('gulp'), jshint=require('gulp-jshint'), uglify=require('gulp-uglify'), concat=require('gulp-concat') ; gulp.task('js', function () { return gulp.src('js/*.js') .pipe(jshint()) .pipe(jshint.reporter('default')) .pipe(uglify()) .pipe(concat('app.js')) .pipe(gulp.dest('build')); });
Ми використовуємо три плагіни: gulp-jshint, gulp-uglify та gulp-concat. Ви можете побачити у файлах README для плагінів, що їх досить легко використати. Доступні деякі налаштування, але, як правило, все добре.
Ви, можливо, помітили, що плагін JSHint викликається двічі. Тому що перший рядок викликає JSHint для файлів, які лише приєднують властивість jshint до файлових об'єктів без виводу. Ви можете прочитати властивість jshint самостійно або передати його до jshint.reporter за замовчуванням або в іншій reporter, такий як jshint-stylish.
Два інші плагіна зрозуміліша: функція uglify() мінімізує код, а функція concat('app.js') поєднує всі файли в один з ім'ям app.js.
gulp-load-plugin
Модуль, який я знаходжу дуже корисним називається gulp-load-plugins, він автоматично завантажує будь-які плагіни Gulp з файлу package.json і приєднує їх до об'єкта. Основне застосування:
<code data-language="javascript">var gulpLoadPlugins=require('gulp-load-plugins'), plugins=gulpLoadPlugins();
Ви можете записати все в один рядок (var plugins=require('gulp-load-plugins')();), але я не великий шанувальник однорядкового виклику require.
Після запуску цього коду об'єкт plugins міститиме ваші плагіни з іменами в CamelCase-стилі (наприклад, gulp-ruby-sass буде завантажений як plugins.rubySass). Ви можете використати їх звичайним шляхом. Наприклад, наше завдання js скоротиться так:
<code data-language="javascript">var gulp=require('gulp'), gulpLoadPlugins=require('gulp-load-plugins'), plugins=gulpLoadPlugins(); gulp.task('js', function () { return gulp.src('js/*.js') .pipe(plugins.jshint()) .pipe(plugins.jshint.reporter('default')) .pipe (plugins.uglify()) .pipe(plugins.concat('app.js')) .pipe(gulp.dest('build')); });
До цього додається файл package.json, який містить щось подібне:
<code data-language="javascript">{ "devDependencies": { "gulp-concat": "~2.2.0", "gulp-uglify": "~0.2.1", "gulp-jshint": "~1.5.1", "gulp": "~3.5.6" } }
Цей приклад насправді не набагато коротший. Однак для об'ємних і складних Gulp-файлів, це скоротить блок із завантаженням файлів до одного або двох рядків. Плагіни не завантажуються, поки їх не викличемо, це означає, що вам не доведеться турбуватися про невикористані плагіни в package.json, що впливають на продуктивність (хоча їх, ймовірно, слід прибрати в будь-якому випадку). Іншими словами, якщо ви запустите завдання, яке вимагає лише два плагіни, воно не стане завантажувати всі плагіни, які необхідні для інших завдань. та виконувати завдання чи завдання при виявленні змін. Ця функція напрочуд корисна (для мене, напевно, одна з найкорисніших у Gulp). Ви можете зберегти Less-файл, а Gulp перетворить його на CSS і оновить браузер без будь-яких дій з вашого боку.
Для стеження за файлом або файлами використовуйте функцію gulp. watch(), яка приймає шаблон файлів або їх масив (такі як gulp.src()), або масив завдань для їх запуску або виконання функції зворотного виклику.
Припустимо, що у нас є завдання build, вона перетворює наші файли шаблонів в HTML і ми хочемо визначити завдання watch, яка відстежує зміну шаблонів і запускає завдання для перетворення їх на HTML. Ми можемо використовувати функцію watch таким чином:
<code data-language="javascript">gulp.task('watch', function() { gulp .watch('templates/*.tmpl.html', ['build']); });
Тепер при зміні файлу шаблону буде запущено завдання build, яке створить HTML.
Ви також можете вказати для watch функцію зворотного виклику замість масиву завдань. У цьому випадку функція отримує об'єкт event, який містить інформацію про подію, яка викликала функцію:
<code data-language="javascript">gulp.watch(' templates/*.tmpl.html', function (event) { console.log('Event type: ' + event.type); //додано, змінено або видалено console.log('Event path: ' + event.path) //шлях до файлу });
Іншою відмінною особливістю gulp.watch() є те, що вона повертає watcher. Використовуйте його для прослуховування додаткових подій або для додавання файлів у watch. Наприклад, щоб одночасно запустити список завдань і викликати функцію, ви можете додати слухача в подію change при поверненні watcher:
<code data-language="javascript">var watcher=gulp.watch('templates/*.tmpl.html', ['build']); watcher.on('change', function (event) { console.log('Event type: ' + event.type); //додано, змінено або видалено console.log('Event path: ' + event.path); //шлях до файлу });
На додаток до change ви можете прослуховувати ряд інших подій:
- end
- error
- ready
- nomatch
Спрацьовує, коли watcher завершується (це означає, що завдання та функції зворотного виклику не будуть викликатися більше при зміні файлів).
Спрацьовує, коли відбувається помилка.
Спрацьовує, коли файли були знайдені та готові до відстеження.
Спрацьовує, коли запиту не відповідає ні один файл.
Об'єкт watcher також містить деякі методи, які можна викликати:
- watcher.end ()
- watcher.files()
- watcher.add(glob)
- watcher.remove(filepath)
Зупиняє watcher (при цьому завдання або функції зворотних викликів не будуть викликатися більше).
Повертає список файлів за якими стежить watcher.
Додає файли до watcher, які відповідають вказаному шаблону glob (також приймає необов'язкову функцію зворотного виклику як другий аргумент).
Видаляє певний файл з watcher .