Разбиваем gulpfile на несколько файлов
Инструменты

Разбиваем gulpfile на несколько файлов

Оригинал: Splitting a gulpfile into multiple files, Callum Macrae

На некоторых проектах gulpfile настолько разрастается, что имеет смысл разбить его на несколько файлов, по одной задаче в каждом. Ниже показаны два способа, как этого можно добиться; оба они очень простые.

Вот довольно простой gulpfile, который мы будем разделять в этой статье. Он не делает ничего особенного, просто обрабатывает JavaScript и Sass.


var gulp = require('gulp');
var concat = require('gulp-concat');
var uglify = require('gulp-uglify');
var sass = require('gulp-ruby-sass');
var autoprefixer = require('gulp-autoprefixer');
var minifyCss = require('gulp-minify-css');

gulp.task('scripts', function () {
    gulp.src('src/js/**/*.js')
        .pipe(concat('scripts.js'))
        .pipe(uglify())
        .pipe(gulp.dest('dest'));
});

gulp.task('sass', function () {
    gulp.src('src/sass/styles.scss')
        .pipe(sass())
        .pipe(autoprefixer())
        .pipe(minifyCss())
        .pipe(gulp.dest('dest'));
});

gulp.task('default', ['scripts', 'sass'], function () {
    gulp.watch('src/js/**/*.js', ['scripts']);
    gulp.watch('src/sass/**/*.{sass,scss}', ['sass']);
});

Способ первый

Каждую задачу поместим в отдельный файл. Этот способ предусматривает буквальное перемещение задачи в новый файл и подробнее описан в рецептах в репозитории Gulp.

gulp-tasks/scripts.js:


var gulp = require('gulp');
var concat = require('gulp-concat');
var uglify = require('gulp-uglify');

gulp.task('scripts', function () {
    gulp.src('src/js/**/*.js')
        .pipe(concat('scripts.js'))
        .pipe(uglify())
        .pipe(gulp.dest('dest'));
});

gulp-tasks/sass.js:


var gulp = require('gulp');
var sass = require('gulp-ruby-sass');
var autoprefixer = require('gulp-autoprefixer');
var minifyCss = require('gulp-minify-css');

gulp.task('sass', function () {
    gulp.src('src/sass/styles.scss')
        .pipe(sass())
        .pipe(autoprefixer())
        .pipe(minifyCss())
        .pipe(gulp.dest('dest'));
});

Теперь можно использовать модуль require-dir, чтобы подключить каждый файл из директории gulp-tasks в gulpfile.

Ниже показано все содержимое gulpfile:


var gulp = require('gulp');

var requireDir = require('require-dir');
requireDir('./gulp-tasks');

gulp.task('default', ['scripts', 'sass'], function () {
    gulp.watch('src/js/**/*.js', ['scripts']);
    gulp.watch('src/sass/**/*.{sass,scss}', ['sass']);
});

Задачу по умолчанию вы тоже можете вынести в отдельный файл, но я предпочитаю этого не делать.

Также можно сократить подключение и вызов require-dir до одной строки:


require('require-dir')('./gulp-tasks');

Этот способ хорош для простых файлов, но если вы хотите делать более сложные вещи, например, хранить пути к исходникам и папкам назначения в объекте или использовать gulp-load-plugins, этот способ будет приводить к излишнему дублированию.

Рассмотрим второй способ.

Второй способ

Этот способ немного сложнее, но он избавляет нас от дублирования. Я также считаю, что он делает более явной зависимость одних задач от других. Способ состоит в разбиении gulpfile на функции, каждая из которых подключается в соответствующей задаче. Опять же, это проще показать на примере.

В примере ниже мы использовали gulp-load-plugins для загрузки модулей в объект plugins.

gulp-tasks/scripts.js:


module.exports = function (gulp, plugins) {
    return function () {
        gulp.src('src/js/**/*.js')
            .pipe(plugins.concat('scripts.js'))
            .pipe(plugins.uglify())
            .pipe(gulp.dest('dest'));
    };
};

gulp-tasks/sass.js:


module.exports = function (gulp, plugins) {
    return function () {
        gulp.src('src/sass/styles.scss')
            .pipe(plugins.sass())
            .pipe(plugins.autoprefixer())
            .pipe(plugins.minifyCss())
            .pipe(gulp.dest('dest'));
    };
};

gulpfile.js:


var gulp = require('gulp');
var plugins = require('gulp-load-plugins')();

gulp.task('scripts', require('./gulp-tasks/scripts')(gulp, plugins));
gulp.task('sass', require('./gulp-tasks/sass')(gulp, plugins));

gulp.task('default', ['scripts', 'sass'], function () {
    gulp.watch('src/js/**/*.js', ['scripts']);
    gulp.watch('src/sass/**/*.{sass,scss}', ['sass']);
});

Результирующий файл не такой простой как в первом случае, но этот способ гораздо более мощный. Подключение файла с задачей можно выделить в отдельную функцию:


var gulp = require('gulp');
var plugins = require('gulp-load-plugins')();

function getTask(task) {
    return require('./gulp-tasks/' + task)(gulp, plugins);
}

gulp.task('scripts', getTask('scripts'));
gulp.task('sass', getTask('sass'));

gulp.task('default', ['scripts', 'sass'], function () {
    gulp.watch('src/js/**/*.js', ['scripts']);
    gulp.watch('src/sass/**/*.{sass,scss}', ['sass']);
});

Второй способ намного лучше, когда у вас есть задачи, вызывающие другие задачи: например, задача default вызывает задачу scripts, которая в свою очередь вызывает задачу lint. При таком способе вызов других задач более наглядный, нет необходимости заглядывать в каждый файл.

Ниже показан gulpfile проекта, на который я ссылаюсь в конце статьи. Действительно, очень просто проследить зависимости между задачами.


gulp.task('auto-reload', getTask('auto-reload'));
gulp.task('html', getTask('html'));
gulp.task('js', ['js-quality'], getTask('js'));
gulp.task('js-quality', getTask('js-quality'));
gulp.task('scss', getTask('scss'));

gulp.task('build', ['html', 'js', 'scss']);
gulp.task('default', ['build'], getTask('default'));

Более сложные примеры gulpfile вы можете найти в проекте, над которым я сейчас работаю, Lostmyname/monkey. Здесь находится gulpfile, а здесь содержатся сами задачи. Обратите внимание, что в этом проекте я вынес и задачу default, поскольку кроме gulp.watch() запускаю в ней BrowserSync.

Рассылка
Подпишитесь на рассылку и получайте дайджест новостей и статей.
Никакого спама!
Подписаться