Level up для новичков: gulp и requirejs
Содержание:
- Migrating to version 5
- Установка Gulp
- gulp-watch
- Use latest JavaScript version in your gulpfile
- Что такое Gulp, чем он хорош и нужен ли он простому верстальщику?
- Gulp src, gulp dist, gulp pipe
- Sample gulpfile.js
- Установка Gulp
- Use last JavaScript version in your gulpfile
- Организация файлов
- Use latest JavaScript version in your gulpfile
- gulp.src()
- Release History
- Incremental Builds
- Автоматизация автоматизации
- What’s new in 4.0?!
- Определение задач
- Разворачивание готовой сборки одной командой
- Usage
- The gulp-minify example
- LICENSE
- Gulp composing tasks
- Sample gulpfile.js
- Шаг 7: Пожинаем плоды!
- Автоматизация
Migrating to version 5
version 5 requires Node 12 or later, and introduces some breaking changes. Additionally, changes in Node itself mean that we should no longer use Node fibers to speed up asynchronous rendering with Dart Sass.
Setting a Sass compiler
As of version 5, does not include a default Sass compiler, so you must install one (either or ) along with .
Then, you must explicitly set that compiler in your gulpfille. Instead of setting a prop on the instance, you pass the compiler into a function call when instantiating .
These changes look something like this:
- var sass = require('gulp-sass')); - var compiler = require('sass'); - sass.compiler = compiler; + var sass = require('gulp-sass')(require('sass'));
Установка Gulp
Установка Gulp 4 довольно простая. Так как Gulp написан на языке javascript, изначально необходимо установить Node.js на вашу систему. Просто заходите на сайт https://nodejs.org, скачиваете инсталятор последний версии и устанавливаете.
Далее создаем папку для проекта в любом удобном месте компьютера и вызываем окно терминала в этом каталоге. В командной строке запускаем инициализацию проекта:
Отвечаем на вопросы на каждом шаге. После каждого ввода нажимаем Enter и переходим к следующему шагу. В результате получим файл package.json, который содержит информацию о проекте и установленных плагинах. Далее установим gulp в наш проект:
После установке Gulp 4 название пакета и его версия сохранятся в файле package.json. Флаг —save-dev используется для сохранения пакета в package.json в раздел devDependencies, то есть в целях разработки. Если установить пакет с флагом —save, то пакет попадает в раздел dependencies (для запуска приложения).
Такой подход дает возможность сохранять все пакеты в файле package.json со всеми зависимостями, а при разворачивании нового проекта достаточно скопировать файл package.json и запустить команду:
Таким образом все пакеты и зависимости установятся автоматически. После установки gulp в каталоге проекта создалась папка node_modules. Все новые установленные пакеты и зависимости сохраняются в данную папку. Поэтому изменять содержимое этого каталога нельзя.
Далее в каталоге проекта создаем файл gulpfile.js. Это самый основной файл, без которого Gulp работать не может. По сути в него можно писать любой javascript код, но gulp — это менеджер управления задачами, и эти задачи описываются в этом файле в виде обычных функций. Что бы запускать эти задачи, функцию нужно экспортировать через оператор exports. Пример:
На примере выше мы создали задачу под название testTask, в которой выводим строчку test. После этого мы экспортируем эту задачу. Что бы Gulp знал, что задача выполнена, мы вызываем функцию обратного вызова done.
Что бы запустить Gulp, можно установить отдельную утилиту глобально на вашу систему:
После этого в консоли вводим команду gulp и через пробел название задачи:
Но есть и альтернативный вариант. Можно передать дополнительные параметры командам запуска в файле package.json для раздела scripts:
В этом случае запускается задача так:
gulp — это значение с раздела scripts файла package.json, а test — название задачи. В итоге в консоле выведется слово test:
gulp-watch
gulp-watch это название плагина для Gulp, который отслеживает изменение файлов. Начиная с четвёртой
версии Gulp gulp-watch включен в основной пакет и не требует отдельной установки.
Начнём с простого — делаем функцию, которая при каждом изменении файла index.html в
папке app будет выводить предупреждение.
Как это выглядит в Gulp 4
Чтобы запустить мониторинг пишем
gulp watch
Using gulpfile ~\Desktop\Sites\heihei\gulpfile.js
Starting ‘watch’…
Теперь вносим изменения в файл index.html и сохраняем
Starting ‘html’…
Кто-то отредактировал index.html!
Как это выглядело в Gulp 3
Создадим папку /app/assets/styles/ , в которой будут файлы .css для разработки
Напишем функцию, которая будет собирать все файлы .css из этой папки,
обрабатывать их с помощью sass и соединять в один файл /app/temp/styles/style.css
Мы уже писали такую функцию выше, просто немного изменим её.
Добавим мониторинг файлов CSS gulp.watch( «./app/assets/styles/**/*.css», style);
Теперь как только мы отредактируем один из файлов стилей watch заметит это изменение,
пропустит его через sass, соберет все файлы в один.
Зачем нужен SASS:
чтобы пользоваться css переменными. Создать переменную, которую потом
вставлять в .css пропускать через sass compiler и когда вдруг везде нужно будет
изменить значение этой переменной, например, на сайте изменится основной цвет, всё
что нам нужно будет сделать — это поменять одну переменную в одном файле.
чтобы делать вложения в стилях (nested css)
чтобы использовать mixins
Use latest JavaScript version in your gulpfile
Most new versions of node support most features that Babel provides, except the / syntax. When only that syntax is desired, rename to , install the module, and skip the Babel portion below.
Node already supports a lot of ES2015+ features, but to avoid compatibility problems we suggest to install Babel and rename your to .
npm install --save-dev @babel/register @babel/core @babel/preset-env
Then create a .babelrc file with the preset configuration.
{"presets""@babel/preset-env"}
And here’s the same sample from above written in ES2015+.
importgulpfrom'gulp';importlessfrom'gulp-less';importbabelfrom'gulp-babel';importconcatfrom'gulp-concat';importuglifyfrom'gulp-uglify';importrenamefrom'gulp-rename';importcleanCSSfrom'gulp-clean-css';importdelfrom'del';constpaths={ styles{ src'src/styles/**/*.less', dest'assets/styles/'}, scripts{ src'src/scripts/**/*.js', dest'assets/scripts/'}};exportconstclean=()=>del('assets');exportfunctionstyles(){returngulp.src(paths.styles.src).pipe(less()).pipe(cleanCSS()).pipe(rename({ basename'main', suffix'.min'})).pipe(gulp.dest(paths.styles.dest));}exportfunctionscripts(){returngulp.src(paths.scripts.src,{ sourcemapstrue}).pipe(babel()).pipe(uglify()).pipe(concat('main.min.js')).pipe(gulp.dest(paths.scripts.dest));}functionwatchFiles(){gulp.watch(paths.scripts.src, scripts);gulp.watch(paths.styles.src, styles);}export{watchFilesaswatch};constbuild=gulp.series(clean,gulp.parallel(styles, scripts));exportdefaultbuild;
Что такое Gulp, чем он хорош и нужен ли он простому верстальщику?
Так что же такое Gulp?
Gulp позволяет решать такие задачи, как:
- использование различных JS, CSS, HTML препроцессоров для ускорения верстки (CoffeeScript, SASS, LESS, Stylus, Pug (Jade) и др.);
- объединение файлов в один — js, css, html;
- минимизация кода файлов — js, css, html;
- создание локального веб-сервера и перезагрузка страницы браузера при сохранении файла проекта (live reaload);
- автоматическая простановка вендорных префиксов в CSS-файле для поддержки стилей устаревшими браузерами;
- работа с изображениями сайта — объединение в спрайты (в том числе и SVG-спрайты), оптимизация (уменьшение веса);
- копирование файлов проекта из одной папки в другую, создавая при это рез. копию;
- создание иконочных шрифтов;
- и многое другое…
Одним словом, круг задач, решаемых с помощью галп достаточно широк и грех всем этим не воспользоваться. Когда я впервые столкнулся с GruntJs мне казалось, что подобные сборки нужны только для крупных и поддерживаемых проектов. А я верстаю небольших макеты и мне это не нужно. Ох как же я ошибался. На самом деле данный инструмент нужен любому веб-разработчику, он здорово экономит время. Представьте, я раньше делал спрайты изображений вручную — это же натуральная рутина. А в Gulp, установив нужный плагин мне достаточно добавить нужное изображение в определенную папку и скрипт сделает все за меня, выдав уже готовый объединенный файл изображений.
Ну что сказать, все в жизни происходит когда-то впервые. Если сказать в целом, Gulp и множество плагинов для него превращает его в мощный инструмент решения задач как маленьких, так и крупных проектов. Теперь давайте разберем более подробнее как его установить и как с ним работать.
Gulp src, gulp dist, gulp pipe
Прежде чем приступать к практике, определимся еще с некоторыми базовыми понятиями. Ранее мы создали тестовый таск, который просто выводит значение в консоль. Но смысл gulp в том, чтобы выполнять рутинные задачи в процессе разработки. Другими словами — взять какой-то файл нашего проекта, выполнить определенные манипуляции с ним, и на выходе получить обновленный файл. Для того, чтобы указать входной файл, используется выражение gulp.src(‘source-file’), а исходящий — gulp.dest(‘dest-folder’). Давайте рассмотрим на примере:
Первой строчкой подключаем сам gulp в наш проект. Далее создаем таск, как мы делали это ранее. Указываем gulp что мы работаем с файлом test.js. После этого через метод pipe говорим gulp, что исходная папка называется output. Таким образом мы просто скопировали файл test.js в папку output.
Метод pipe — это основное API для gulp. Этот метод как бы объединяет все операции внутри таска. Через pipe можно выстроить неограниченную цепочку из операций для создания определенных сценариев.
Sample gulpfile.js
This file will give you a taste of what gulp does.
var gulp =require('gulp');var less =require('gulp-less');var babel =require('gulp-babel');var concat =require('gulp-concat');var uglify =require('gulp-uglify');var rename =require('gulp-rename');var cleanCSS =require('gulp-clean-css');var del =require('del');var paths ={ styles{ src'src/styles/**/*.less', dest'assets/styles/'}, scripts{ src'src/scripts/**/*.js', dest'assets/scripts/'}};functionclean(){returndel('assets');}functionstyles(){returngulp.src(paths.styles.src).pipe(less()).pipe(cleanCSS()).pipe(rename({ basename'main', suffix'.min'})).pipe(gulp.dest(paths.styles.dest));}functionscripts(){returngulp.src(paths.scripts.src,{ sourcemapstrue}).pipe(babel()).pipe(uglify()).pipe(concat('main.min.js')).pipe(gulp.dest(paths.scripts.dest));}functionwatch(){gulp.watch(paths.scripts.src, scripts);gulp.watch(paths.styles.src, styles);}var build =gulp.series(clean,gulp.parallel(styles, scripts));exports.clean= clean;exports.styles= styles;exports.scripts= scripts;exports.watch= watch;exports.build= build;exports.default= build;
Установка Gulp
Установку Gulp я буду показывать на примере ОС Windows 10 x64 последней сборки, так как я работаю именно в данной системе.
Первым делом нам необходимо установить node.js. Данный пакет превращает клиентский язык javaScript в серверный. Для тех, кто не знает язык javaScript интерпретирует браузер пользователя. Кстати, Gulp создан на языке javaScript и если вы знакомы с данным языком, то освоить его вам будет намного легче.
Для установки node.js необходимо скачать инсталлятор с официального сайта. Качаем последнюю стабильную версию. Пакет устанавливается как обычная программа и ничего сложного в этом нет.
После установки node.js можно проверить правильно ли все установилось. Открываем консольное окно (командная строка) — в ОС Windows это комбинация клавиш . Вводим команду:
Если все правильно установили в ответ вы увидите версию установленного пакета.
Все, можно приступать к установке Gulp.
Пишем команду для установки Gulp:
Давайте разберем, что значит данная запись:
- npm — говорит о том, что мы запускаем пакет менеджер, который установит Gulp;
- i — это сокращенная запись install, т.е. установить;
- gulp — имя устанавливаемого пакета;
- -g — данный флаг говорит о том, что мы устанавливаем Gulp глобально в систему. Без данного ключа gulp установится в ту папку, из которой запускается команда. Так что имейте это ввиду.
Установка не занимает много времени, примерно 1-2 мин. После завершения работы установщика галп можно проверить корректность установки, также, как и node.js:
Если все правильно, то выдаст версию установленного галп.
Use last JavaScript version in your gulpfile
Node already supports a lot of ES2015, to avoid compatibility problem we suggest to install Babel and rename your as .
npm install --save-dev babel-register babel-preset-es2015
Then create a .babelrc file with the preset configuration.
{"presets""es2015"}
And here’s the same sample from above written in ES2015.
importgulpfrom'gulp4';importlessfrom'gulp-less';importbabelfrom'gulp-babel';importconcatfrom'gulp-concat';importuglifyfrom'gulp-uglify';importrenamefrom'gulp-rename';importcleanCSSfrom'gulp-clean-css';importdelfrom'del';constpaths={ styles{ src'src/styles/**/*.less', dest'assets/styles/'}, scripts{ src'src/scripts/**/*.js', dest'assets/scripts/'}};constclean=()=>del('assets');export{clean};exportfunctionstyles(){returngulp.src(paths.styles.src).pipe(less()).pipe(cleanCSS()).pipe(rename({ basename'main', suffix'.min'})).pipe(gulp.dest(paths.styles.dest));}exportfunctionscripts(){returngulp.src(paths.scripts.src,{ sourcemapstrue}).pipe(babel()).pipe(uglify()).pipe(concat('main.min.js')).pipe(gulp.dest(paths.scripts.dest));}exportfunctionwatch(){gulp.watch(paths.scripts.src, scripts);gulp.watch(paths.styles.src, styles);}constbuild=gulp.series(clean,gulp.parallel(styles, scripts));export{build};exportdefaultbuild;
Организация файлов
Чтобы не создавать каши из файлов и папок организуем всё правильно с самого начала.
Корневая папка носит называние проекта. В моё случае 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
Use latest JavaScript version in your gulpfile
Node already supports a lot of ES2015, to avoid compatibility problem we suggest to install Babel and rename your as .
npm install --save-dev babel-register babel-preset-es2015
Then create a .babelrc file with the preset configuration.
{"presets""es2015"}
And here’s the same sample from above written in ES2015.
importgulpfrom'gulp';importlessfrom'gulp-less';importbabelfrom'gulp-babel';importconcatfrom'gulp-concat';importuglifyfrom'gulp-uglify';importrenamefrom'gulp-rename';importcleanCSSfrom'gulp-clean-css';importdelfrom'del';constpaths={ styles{ src'src/styles/**/*.less', dest'assets/styles/'}, scripts{ src'src/scripts/**/*.js', dest'assets/scripts/'}};exportconstclean=()=>del('assets');exportfunctionstyles(){returngulp.src(paths.styles.src).pipe(less()).pipe(cleanCSS()).pipe(rename({ basename'main', suffix'.min'})).pipe(gulp.dest(paths.styles.dest));}exportfunctionscripts(){returngulp.src(paths.scripts.src,{ sourcemapstrue}).pipe(babel()).pipe(uglify()).pipe(concat('main.min.js')).pipe(gulp.dest(paths.scripts.dest));}functionwatchFiles(){gulp.watch(paths.scripts.src, scripts);gulp.watch(paths.styles.src, styles);}export{watchFilesaswatch};constclean=gulp.series(clean,gulp.parallel(styles, scripts));gulp.task('clean', clean);exportdefaultbuild;
gulp.src()
Функция gulp.src() берёт один или несколько файлов или массив и возвращает поток, который может быть передан в плагины.
Gulp использует node-glob для получения указанных файлов. Проще всего объяснить на примерах:
- js/app.js
Соответствует определённому файлу.
- js/*.js
Соответствует всем файлам, заканчивающихся на .js в папке js.
- js/**/*.js
Соответствует всем файлам с расширением .js в папке js и всех вложенных папках.
- !js/app.js
Исключает js/app.js из соответствия, что полезно если вы желаете выбрать все файлы в папке за исключением определённого файла.
- *.+(js|css)
Соответствует всем файлам, заканчивающихся на .js или .css.
Другие функции также доступны, но в Gulp они обычно не применяются. Посмотрите документацию Minimatch ради подробностей.
Предположим, у нас есть папка с именем js, содержащая файлы JavaScript, некоторые минимизированы, а некоторые нет. Мы хотим создать задачу по минимизации ещё не уменьшенных файлов. Чтобы сделать это, мы выбираем все файлы JavaScript в папке, за исключением всех файлов, оканчивающиеся на .min.js:
Release History
- 1.5.0 — Update webpack to 1.9.x (@nmccready). Update other dependencies.
- 1.4.0 — Update webpack to 1.8.x (@Zolmeister).
- 1.3.2 — Fix another place with ? in name (@raphaelluchini).
- 1.3.1 — Fix for paths with ? in their name (@raphaelluchini).
- 1.3.0 — Updating to webpack >= 1.7.
- 1.2.0 — Updating to webpack >= 1.5, vinyl >= 0.4, memory-fs >= 0.2.
- 1.1.2 — Fixes to default stats for logging (@mdreizin).
- 1.1.1 — Add additional stats to default logging (@mdreizin).
- 1.1.0 — Exposes internal webpack if asked via
- 1.0.0 — Support named chunks pipe’d in for multiple entry points.
- 0.4.1 — Fixed regression for multiple entry point support.
- 0.4.0 — Display an error message if there are no input files (@3onyc). Add message on why task is not finishing, Add ability to track compilation progress, Add ability to configure stats output via options (@kompot). Bump webpack version (@koistya).
- 0.3.0 — Update deps (@kompot). Fixes to determining entry (@btipling and @abergs).
- 0.2.0 — Support for mode (@ampedandwired).
- 0.1.0 — Initial release
Incremental Builds
You can filter out unchanged files between runs of a task using
the function’s option and :
constpaths={... images{ src'src/images/**/*.{jpg,jpeg,png}', dest'build/img/'}}functionimages(){returngulp.src(paths.images.src,{sincegulp.lastRun(images)}).pipe(imagemin({optimizationLevel5})).pipe(gulp.dest(paths.images.dest));}functionwatch(){gulp.watch(paths.images.src, images);}
Task run times are saved in memory and are lost when gulp exits. It will only
save time during the task when running the task
for a second time.
If you want to compare modification time between files instead, we recommend these plugins:
functionimages(){var dest ='build/img';returngulp.src(paths.images).pipe(newer(dest)).pipe(imagemin({optimizationLevel5})).pipe(gulp.dest(dest));}
If you can’t simply filter out unchanged files, but need them in a later phase
of the stream, we recommend these plugins:
functionscripts(){returngulp.src(scriptsGlob).pipe(cache('scripts')).pipe(header('(function () {')).pipe(footer('})();')).pipe(remember('scripts')).pipe(concat('app.js')).pipe(gulp.dest('public/'))}
Автоматизация автоматизации
Вы, возможно, заметили одну вещь — нужно сделать большое число вызовов чтобы включить все необходимые нам плагины.
Мы можем сократить этот список до одного, используя — вот ирония — ещё один плагин gulp-load-plugins. Этот плагин будет автоматически загружать все плагины Gulp из нашего package.json используя ленивую загрузку, что делает их всех доступными как единый объект.
С этого момента все наши плагины будут доступны как $.<плагин>, при этом из имени отделяется gulp- и применяется camelCase. Это значит, что gulp-usemin и gulp-uglify станут $.usemin и $.uglify, соответственно, а gulp-minify-css станет $.minifyCss.
What’s new in 4.0?!
- The task system was rewritten from the ground-up, allowing task composition using and methods
- The watcher was updated, now using chokidar (no more need for gulp-watch!), with feature parity to our task system
- First-class support was added for incremental builds using
- A method was exposed to create symlinks instead of copying files
- Built-in support for sourcemaps was added — the gulp-sourcemaps plugin is no longer necessary!
- Task registration of exported functions — using node or ES exports — is now recommended
- Custom registries were designed, allowing for shared tasks or augmented functionality
- Stream implementations were improved, allowing for better conditional and phased builds
Определение задач
Чтобы определить задачу используйте функцию gulp.task(). Для простой задачи эта функция принимает два параметра: имя задачи и функция для запуска.
Запуск gulp greet выведет «Здравствуй, мир» в консоли.
Задача также может быть списком других задач. Предположим, мы хотим определить задачу build, которая выполняет три других задачи: css, js и imgs. Мы можем сделать это, указав вместо функции массив с задачами:
Они будут запускаться асинхронно, так что вы не можете предполагать, что когда задача css завершится, то запустится задача js — на деле, это, скорее всего, не произойдёт. Чтобы убедиться, что задача завершила работу перед запуском другой задачи, вы можете указать зависимостей путём объединени массива задач с функцией. Например, чтобы определить задачу css, которая перед запуском проверит, что задача greet завершена, вы можете сделать так:
Теперь, когда вы запустите задачу css, Gulp выполнит задачу greet, подождёт, пока она окончится, а затем вызовет указанную функцию.
Разворачивание готовой сборки одной командой
Вы создали сборку, теперь хотите реально создать на ней проект. Достаточно скопировать папку сборки и запустить установку. Вообще при установке должны устанавливаться все последние версии зависимостей, включая сам gulp (при обновлении глобальной версии). Для этого нам необходимо подредактировать файл package.json. В блоке devDependencies, где перечислены установленные расширения вместо версии необходимо указать ключевое слово — . Вот как теперь выглядит мой файл:
Теперь для быстрого разворачивания проекта необходимо сделать следующее — копируем все файлы проекта Gulp за исключением папки node_modules в другую папку вашего проекта. Открываем локально консоль и вводим команду после чего запуститься установка gulp и всех зависимостей. Все, можно начинать работу.
Usage
Note: These examples assume you’re using Gulp 4. For examples that work with Gulp 3, check the docs for an earlier version of .
runs inside of Gulp tasks. No matter what else you do with , you must first import it into your gulpfile, making sure to pass it the compiler of your choice. From there, create a Gulp task that calls either (to asynchronously render your CSS), or (to render it synchronously). Then, export your task with the keyword. We’ll show some examples of how to do that.
️ Note: With Dart Sass, synchronous rendering is twice as fast as asynchronous rendering. The Sass team is exploring ways to improve asynchronous rendering with Dart Sass, but for now you will get the best performance from
Render your CSS
To render your CSS with a build task, then watch your files for changes, you might write something like this.:
'use strict'; var gulp = require('gulp'); var sass = require('gulp-sass')(require('sass')); function buildStyles() { return gulp.src('./sass/**/*.scss') .pipe(sass().on('error', sass.logError)) .pipe(gulp.dest('./css')); }; exports.buildStyles = buildStyles; exports.watch = function () { gulp.watch('./sass/**/*.scss', 'sass'); };
With synchronous rendering, that Gulp task looks like this:
function buildStyles() { return gulp.src('./sass/**/*.scss') .pipe(sass.sync().on('error', sass.logError)) .pipe(gulp.dest('./css')); };
Render with options
To change the final output of your CSS, you can pass an options object to your renderer. supports , with two unsupported exceptions:
- The option, which is used by internally.
- The option, which has undefined behavior that may change without notice.
For example, to compress your CSS, you can call . In the context of a Gulp task, that looks like this:
function buildStyles() { return gulp.src('./sass/**/*.scss') .pipe(sass({outputStyle: 'compressed'}).on('error', sass.logError)) .pipe(gulp.dest('./css')); }; exports.buildStyles = buildStyles;
Or this for synchronous rendering:
function buildStyles() { return gulp.src('./sass/**/*.scss') .pipe(sass.sync({outputStyle: 'compressed'}).on('error', sass.logError)) .pipe(gulp.dest('./css')); }; exports.buildStyles = buildStyles;
Include a source map
can be used in tandem with to generate source maps for the Sass-to-CSS compilation. You will need to initialize before running , and write the source maps after.
var sourcemaps = require('gulp-sourcemaps'); function buildStyles() { return gulp.src('./sass/**/*.scss') .pipe(sourcemaps.init()) .pipe(sass().on('error', sass.logError)) .pipe(sourcemaps.write()) .pipe(gulp.dest('./css')); } exports.buildStyles = buildStyles;
By default, writes the source maps inline, in the compiled CSS files. To write them to a separate file, specify a path relative to the destination in the function.
var sourcemaps = require('gulp-sourcemaps'); function buildStyles() { return gulp.src('./sass/**/*.scss') .pipe(sourcemaps.init()) .pipe(sass().on('error', sass.logError)) .pipe(sourcemaps.write('./maps')) .pipe(gulp.dest('./css')); }; exports.buildStyles = buildStyles;
The gulp-minify example
The plugin minifies JS files.
$ npm i --save-dev gulp-minify
We install the plugin.
src/js/main.js
function hello() { return 'Hello there!'; } hello();
We have a simple file with a function.
gulpfile.js
const { src, dest } = require('gulp'); const minify = require("gulp-minify"); exports.default = () => { return src('src/js/main.js', { allowEmpty: true }) .pipe(minify({noSource: true})) .pipe(dest('dist/js')) }
We read the JS file, pass it through the function
and write the result into the directory.
$ gulp Using gulpfile ~/Documents/prog/js/gulp-lib/gulpfile.js Starting 'default'... Finished 'default' after 75 ms
We run the default Gulp task.
$ cat dist/js/main-min.js function hello(){return"Hello there!"}hello();
These are the contents of the minified
file.
LICENSE
(MIT License)
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
«Software»), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED «AS IS», WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Gulp composing tasks
In the next example, we compose tasks with and
. In this example, we need ,
, , and
plugins.
The minifies CSS. The deletes
files and directories.
src/ ├── js │ └── main.js └── styles └── main.css
We have this directory structure.
src/js/main.js
function hello() { return 'Hello there!'; } hello();
This is a simple file.
src/styles/main.css
body { font-family:georgia; font-size:1em; line-height:1.7em; background: #333; text-align:center; }
This is a simple file.
gulpfile.js
const { src, dest, series, parallel } = require('gulp'); const minify = require("gulp-minify"); const rename = require("gulp-rename"); const cleanCSS = require('gulp-clean-css'); const del = require('del'); const clean = () => del(); function styles() { return src('src/styles/main.css', { allowEmpty: true }) .pipe(cleanCSS()) .pipe(rename({ basename: 'main', suffix: '.min' })) .pipe(dest('dist/styles')) } function scripts() { return src('src/js/main.js', { allowEmpty: true }) .pipe(minify({noSource: true})) .pipe(dest('dist/js')) } const build = series(clean, parallel(styles, scripts)); exports.styles = styles; exports.scripts = scripts; exports.clean = clean; exports.build = build; exports.default = build;
The gulpfile minifies CSS and JS files. It cleans the distribution
directory. The workflow is separated into several tasks.
const clean = () => del();
The task removes the directory.
function styles() { return src('src/styles/main.css', { allowEmpty: true }) .pipe(cleanCSS()) .pipe(rename({ basename: 'main', suffix: '.min' })) .pipe(dest('dist/styles')) }
The task minifies the CSS file and renames it. It adds
the extension.
function scripts() { return src('src/js/main.js', { allowEmpty: true }) .pipe(minify({noSource: true})) .pipe(dest('dist/js')) }
The task minifies the JS file.
const build = series(clean, parallel(styles, scripts));
We define a task. It is a composition of
three tasks. First, the task is run. After
it finishes, the and
are run in parallel.
exports.styles = styles; exports.scripts = scripts; exports.clean = clean; exports.build = build; exports.default = build;
We export five functions. The tasks can be called independently or
composed in the taks. Also, the
task is the default task.
$ gulp build Using gulpfile ~/Documents/prog/js/gulp-lib/gulpfile.js Starting 'build'... Starting 'clean'... Finished 'clean' after 13 ms Starting 'styles'... Starting 'scripts'... Finished 'scripts' after 53 ms Finished 'styles' after 54 ms Finished 'build' after 70 ms
We explicitly run the build task.
In this tutorial we have introduced Gulp.
You might also be interested in the following related tutorials:
Node Sass tutorial,
Gulp minify tutorial,
Gulp Sass tutorial.
List .
Sample gulpfile.js
This file is just a quick sample to give you a taste of what gulp does.
var gulp =require('gulp4');var less =require('gulp-less');var babel =require('gulp-babel');var concat =require('gulp-concat');var uglify =require('gulp-uglify');var rename =require('gulp-rename');var cleanCSS =require('gulp-clean-css');var del =require('del');var paths ={ styles{ src'src/styles/**/*.less', dest'assets/styles/'}, scripts{ src'src/scripts/**/*.js', dest'assets/scripts/'}};functionclean(){returndel('assets');}functionstyles(){returngulp.src(paths.styles.src).pipe(less()).pipe(cleanCSS()).pipe(rename({ basename'main', suffix'.min'})).pipe(gulp.dest(paths.styles.dest));}functionscripts(){returngulp.src(paths.scripts.src,{ sourcemapstrue}).pipe(babel()).pipe(uglify()).pipe(concat('main.min.js')).pipe(gulp.dest(paths.scripts.dest));}functionwatch(){gulp.watch(paths.scripts.src, scripts);gulp.watch(paths.styles.src, styles);}exports.clean= clean;exports.styles= styles;exports.scripts= scripts;exports.watch= watch;var build =gulp.series(clean,gulp.parallel(styles, scripts));gulp.task('build', build);gulp.task('default', build);
Шаг 7: Пожинаем плоды!
Другие плагины, которые могут быть полезны:
- gulp-load-plugins: загружает все модули плагинов Gulp автоматически;
- gulp-preprocess: простой препроцессор HTML и JavaScript;
- gulp-less: плагин препроцессора Less CSS;
- gulp-stylus: плагин препроцессора Stylus CSS;
- gulp-size: отображает размеры файлов;
- gulp-nodemon: использует nodemon для автоматического перезапуска приложений Node.js при их изменении.
Таски Gulp могут запускать любой JavaScript- код или модули Node.js. Они не обязательно должны быть плагинами. Например:
- browser-sync: автоматически перезагружает ресурсы, когда происходят изменения;
- del: удаляет файлы и папки (может очищать папку build в начале каждого запуска).
Преимущества Gulp:
- множество плагинов;
- конфигурация с использованием pipe легко читаема и понятна;
- js можно адаптировать для использования в других проектах;
- упрощает развертывание;
Полезные ссылки:
- домашняя страница Gulp;
- плагины Gulp;
- домашняя страница npm.
После применения описанных выше процессов к простому сайту его общий вес уменьшился более чем на 50%.
Что такое Gulp.js? Gulp – это отличный вариант для автоматического запуска заданий и упрощения процесса разработки.
Ангелина Писанюкавтор-переводчик статьи «An Introduction to Gulp.js»
Автоматизация
Если мы хотим автоматически хранить наши минимизированные файлы обновлёнными в процессе разработки, мы можем использовать функциональность gulp.watch(). Давайте создадим финальную задачу с именем watch:
Здесь мы отслеживаем наши шаблоны, а также все файлы .js и .css из пакетов Bower. Заметьте, что мы исключили файлы .min.js и .min.css.
Затем мы вызываем gulp.watch(), передав в него массив файлов и задачу default, которую мы хотим запускать при обнаружении изменений.
С этого момента Gulp будет сидеть и ждать изменений.
Если вы хотите убедиться, что эта задача выполняется при запуске, то можете установить задачу default как зависимость: