Build Tools: Grunt vs Gulp
JavaScript развивается безумными темпами, соответственно постоянно появляются новые вещи, которые упрощают нашу жизнь как разработчика и позволяют автоматизировать некоторые процессы. Вы наверняка слышали о Build Tools, которые помогают нам, так сказать, по частям собрать проект в одно целое. В этой статье я предлагаю к Вашему рассмотрению Grunt и Gulp, которые выполняют одинаковые задачи, что перед ними поставлены, но делают это совершенно по-разному.
Прежде чем мы рассмотрим, как эти инструменты сборки отличаются, стоит отметить, что они оба предназначены для того, чтобы сделать то же самое: автоматизировать задачи, которые вам в противном случае пришлось бы делать вручную. Эти задачи могут включать:
- Компиляция Less / Sass в CSS
- Конкатенирование и минимизация CSS и JavaScript
- Linting code
- Оптимизация изображений
- Запуск тестов и т.д.
Grunt, вероятно, более интуитивно понятен из двух инструментов сборки, поскольку он работает, определяя задачи в одном файле конфигурации Gruntfile.js. Вы можете указать конфигурацию для каждой задачи, и Grunt будет последовательно выполнять каждую из них. Это упрощает чтение и понимание файлов Grunt.
Gulp, с другой стороны, фокусируется на принципе «code over configuration», делая каждое определение задачи функцией JavaScript. Gulp обычно намного быстрее, чем Grunt, хотя и может иметь немного более крутую кривую обучения из-за использования streams и promises.
Grunt
Grunt работает на Node.js, устанавливается и управляется через менеджер пакетов npm.
Первое что нужно сделать — инициализировать проект. Запустите в командной строке:
npm init
После автоматически будет создан файл package.json.
Введите все необходимые данные, такие как имя проекта, описание и т.д. Дальше устанавливаем Grunt:
npm install grunt --save-dev
«save-dev» нужен для того, что бы наш пакет появился в файл package.json в раздел devDependencies. Раздел Dependencies (ключ —save) — это пакеты которые нужны для работы проекта и будут установлены на продакшн, а devDependencies — это те которые нужны для разработки. При использовании этих ключей мы одной командой можем установить все нужные пакеты:
npm install
Если мы не укажем ключ save или save-dev, то пакет не пропишется в файле package.json и после удаления папки node_modules командой npm install
мы уже не сможем вернуть эти пакеты.
Для начала работы нам необходимо установить интерфейс командной строки (CLI):
npm install -g grunt-cli
CLI нужен для того, что б проект запускал локальную версию Grunt.
Если найден локально установленный Grunt, CLI загружает локальную установку библиотеки Grunt, применяет конфигурацию из вашего Gruntfile и выполняет любые задачи, которые вы запросили для его запуска.
Дальше следует создать файл Gruntfile.js в корне Вашего проекта. К его заполнению мы приступим несколько позже.
Далее командой
npm install {package} --save-dev
Устанавливаем необходимые для работы пакеты, например:
- grunt-contrib-concat — автоматическое объединение файлов
- grunt-contrib-uglify — минимизирование js файлов
- grunt-sass — компилятор Sass в CSS, вы можете спокойной писать стили на Sass, об остальном позаботится Grunt
После установки открываем Gruntfile.js, теперь нам нужно его заполнить с настройкой всех установленных пакетов.
module.exports = function (grunt) {
grunt.initConfig({
sass: {
dist: {
files: {
'dist-grunt/css/style.css': 'assets/scss/style.scss'
}
}
},
concat: {
css: {
files: {
'dist-grunt/css/styles.css': [
'dist-grunt/css/style.css',
'assets/css/test.css'
],
},
},
js: {
files: {
'dist-grunt/js/scripts.js': [
'assets/js/test1.js',
'assets/js/test2.js'
],
},
},
},
uglify: {
dist: {
files: {
'dist-grunt/js/scripts.min.js': ['dist-grunt/js/scripts.js']
}
}
}
});
grunt.loadNpmTasks('grunt-sass');
grunt.loadNpmTasks('grunt-contrib-concat');
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.registerTask('default', ['sass', 'concat', 'uglify']);
};
В initConfig мы указываем настройки для конкретного пакета, например, места где лежат скрипты которые мы будем минимизировать через uglify, скрипты и файлы стилей которые будем объединять через concat, а так же название и расположение файла, который будет получен в результате и путь к папке в которой лежат наши sass файлы, а так же путь куда будут создаваться css файлы.
Через loadNpmTasks подгружаем пакеты и registerTask регистрируем конфигурацию.
Gulp
Посмотрим как подобные настройки будут выглядеть при помощи Gulp.
Сначала установим его через npm:
npm install gulp --save-dev
Далее подтянем пакеты с помощью команды
npm install {package} --save-dev
Создаем файл Gulpfile.js в корне проекта и приступаем к заполнению:
var gulp = require('gulp');
var sass = require('gulp-sass');
var concat = require('gulp-concat');
var uglify = require('gulp-uglify');
gulp.task('sass', function () {
return gulp.src('assets/scss/**/*.scss')
.pipe(sass().on('error', sass.logError))
.pipe(gulp.dest('dist-gulp/css'));
});
gulp.task('css', ['sass'], function () {
return gulp.src([
'dist-gulp/css/style.css',
'assets/css/test.css'
])
.pipe(concat('styles.min.css'))
.pipe(gulp.dest('dist-gulp/css'));
});
gulp.task('js', function () {
return gulp.src('assets/js/**/*.js')
.pipe(concat('scripts.min.js'))
.pipe(uglify())
.pipe(gulp.dest('dist-gulp/js'));
});
gulp.task('default', ['css', 'js']);
С помощью require
подключаем каждый пакет в Gulpfile.js. Далее создаем блоки для sass
,css
и js
файлов, указываем папку с исходниками и место куда мы будем генерировать результат — файл или папку, после через pipe указываем обработчики. С помощью реализации потоков в Gulp каждая задача может выполняться параллельно, что в результате выполнит все таски быстрее, чем Grunt.
Производительность
Теперь, после запуска обоих сценариев сборки мы можем проанализировать как быстро они выполняются.
1. Grunt: 1.6 secs
2. Gulp: 0.59 secs
В результате мы видим насколько быстрее Gulp справляется чем Grunt. В небольшом проекте, подобном нашему, разница в 1 секунду может быть не заметной, но для больших проектов разница в скорости может существенно влиять на производительность и скорость разработки.
Выводы
Нет какого-то однозначного решения, что конкретно стоит использовать, и в том и в том подходе есть свои преимущества.
Grunt
+ Простота обучения и настройки
+ Множество плагинов
— Может работать медленнее на больших проектах
Gulp
+ Гораздо быстрее из-за использования стримов
+ Имеет более гибкую структуру
— Крутая кривая обучения
Используете ли вы инструменты сборки, например Grunt или Gulp, для компиляции ваших проектов? Вы предпочитаете Grunt или Gulp, почему? Дайте нам знать об этом в комментариях.