Подтвердить что ты не робот

Gulp задача с различным источником в зависимости от аргументов

Я хочу сделать что-то простое с помощью gulp. Я хочу написать общий метод для перемещения файлов в выходной каталог из определенного исходного каталога.

притвориться, что у нас что-то вроде этого

var args = require('yargs');
function transform-move-jsx-Development() 
{
  gulp.src(config.sourceJSX)
  .pipe(react, browserify, etc....)
  .pipe(gulp.dest(config.output_development));
};

function transform-move-jsx-Production() 
{
  gulp.src(config.sourceJSX)
  .pipe(react, browserify, etc....)
  .pipe(gulp.dest(config.output_production));
};

gulp.task('transform-move-jsx-Development', transform-move-jsx-Development);
gulp.task('transform-move-jsx-Production', transform-move-jsx-Production);

gulp.task('prod', [transform-move-jsx-Production]);
gulp.task('dev', ['transform-move-jsx-Development']);

Две задачи: transform-move-jsx-Production и transform-move-jsx-Development идентичны, за исключением выходного каталога. Я хочу сделать его более сухим (не повторяй себя). Я должен иметь возможность сделать один метод, который может использовать параметр yarg или что-то в этом роде? В следующем примере я притворяюсь, что могу передать путь как arg

Итак, я пытаюсь что-то вроде этого использовать yargs

var args = require('yargs');

function transform-move-jsx() 
{ 
    return gulp.src(config.sourceJSX)
    .pipe(gulp.dest(args.outputDirectory));
};

gulp.task('dev', ['transform-move-jsx']);

Однако теперь мне нужно добавить аргументы в вызов gulp в командной строке

gulp dev --"path to output, etc."

Это, очевидно, менее обслуживаемо, поскольку мы вызываем все больше задач gulp изнутри задачи dev gulp. И в любом случае будет беспорядочно, поскольку нам не нужно знать детали реализации, как то, что структура выходного каталога при запуске gulp dev

Вместо этого я мог бы сделать что-то вроде этого:

function transform-move-jsx(destination) 
{ 
    return gulp.src(config.sourceJSX)
    .pipe(gulp.dest(destination));
};

function transform-move-jsx-Development() 
{
    transform-move-jsx("./output/development/");
};

function transform-move-jsx-Production() 
{
    transform-move-jsx("./output/production/");
};

gulp.task('transform-move-jsx-Development',transform-move-jsx-Development);
gulp.task('transform-move-jsx-Production', transform-move-jsx-Production);

gulp.task('prod',  transform-move-jsx-Production);
gulp.task('dev',  transform-move-jsx-Development);

Это кажется лучше в том, что он более гибкий, однако теперь мой gulpfile завален несколькими ненужными функциями.

Есть ли лучший способ?

4b9b3361

Ответ 1

Вы были на правильном пути со своей второй попыткой, просто нужно было использовать немного DRY и closures

function createTransformTaskClosure (destination) {
    return function () {
        return gulp.src(config.sourceJSX)
                   .pipe(gulp.dest(destination));
    };
}

gulp.task('dev', createTransformTaskClosure(config.output_development));
gulp.task('prod', createTransformTaskClosure(config.output_production));

Ответ 2

Я сделал что-то подобное, используя одну функцию:

function getDest(folder){
    var folder = folder || '';
    var newDest;
    if (args.build){
        newDest = config.build.home + folder;
    }
    if (args.temp){
        newDest = config.temp.home + folder;
    }
    return newDest;
}

Затем, когда я назову gulp.dest():

.pipe(gulp.dest(getDest())) // defaults to ./ directory

Или, если мне нужна вложенная папка:

.pipe(gulp.dest(getDest(config.css)))

У моего конфигурационного файла просто были пути, т.е.:

config = {
   css: '/css/',
   home: './',
   js: '/js/'
}

Надеюсь, что это поможет.

Ответ 3

Для начала, для записи, соответствующая проблема github gulp # 1225.

Gulp не может обрабатывать параметры в задачах. Чтобы обработать сборку dev/production, мы можем использовать yargs и gulp-if:

var gulp = require('gulp');
var argv = require('yargs').argv;
var gulpif = require('gulp-if');
var production = argv.production;

Затем, например, в задаче CSS:

return gulp.src(paths.css)
  .pipe(gulpif(!production, sourcemaps.init()))
  .on('error', handleError('CSS'))
  .pipe(concat('style.min.css'))
  .pipe(gulpif(production, autoprefixer(config.autoprefixer_versions)))
  .pipe(gulpif(production, minifyCSS()))
  .pipe(sourcemaps.write())
  .pipe(gulp.dest(paths.build + 'css/'));

Как вы можете видеть, использование gulp -if правильно обрабатывает канал.

Но выше все еще нужно запустить gulp с gulp mytask --production и не подходит, действительно, если одна и та же задача должна выполняться в одной сборке несколько раз. Это не подходит, потому что это не СУХОЙ вообще.

Например, если вам нужно создать несколько сборников CSS для разных частей сайта, вам нужно будет повторить вышеуказанную задачу n раз. Но так как gulp не может обрабатывать параметры, нам нужно сделать что-то вроде:

var taskMethods = {
  css: function (paths) {
    return gulp.src(paths.css)
      .pipe(gulpif(!production, sourcemaps.init()))
      .on('error', handleError('CSS'))
      .pipe(concat('style.min.css'))
      .pipe(gulpif(production, autoprefixer(config.autoprefixer_versions)))
      .pipe(gulpif(production, minifyCSS()))
      .pipe(sourcemaps.write())
      .pipe(gulp.dest(paths.build + 'css/'));
  }
};

var pathsIndex = {
  css: [...],
  build: '...'
};

var tasksIndex = {
  css: function() { return taskMethods(pathsIndex); }
}

var pathsAdmin = {...};
var tasksAdmin = {...};

gulp.task('cssIndex', tasksIndex.css);
gulp.task('cssAdmin', tasksAdmin.css);

Таким образом, по существу мы отделяем метод задачи от задачи gulp, причем стоимость необходимости указывать "подключение" метода задачи к новой функции, которая использует определенную конфигурацию пути. Но это имеет то преимущество, что всякий раз, когда вам нужно внести изменения в метод задачи, он находится в одном месте. Также вы можете легко увидеть, какая часть сайта использует какие методы.

Также я рассматриваю эту проблему в моем проекте gulpfile.

Ответ 4

Как насчет следующего:

var args = require('yargs');
function transform-move-jsx(destination) {
    return function(){
        return gulp.src(config.sourceJSX)
                   .pipe(react, browserify, etc....)
                   .pipe(gulp.dest(destination));
    }
};

gulp.task('transform-move-jsx-Development', transform-move-jsx(config.output_development));
gulp.task('transform-move-jsx-Production', transform-move-jsx(config.output_production));

gulp.task('prod', [transform-move-jsx-Production]);
gulp.task('dev', ['transform-move-jsx-Development']);  

Ответ 5

Не уверен, что это какое-то использование, но всего лишь моя небольшая пенсия по идее: -

В файле gulp укажите следующее.

var args = require('yargs'),
    config = require('./config.js'),
    run = require('gulp-sequence');

gulp.task('transform-move-jsx-all', function() {
    return gulp.src(config.sourceJSX)
        .pipe(react, browserify, etc....)
        .pipe(gulp.dest(config.current.output));
};

gulp.task('prod', function(done) {
    config.current = config.prod;
    run( 'transform-move-jsx' /* and any additional sequential tasks here*/)(done);
});

gulp.task('dev', function(done) {
    config.current = config.dev;
    run( 'transform-move-jsx' /* and any additional sequential tasks here*/)(done);
});

Затем это позволяет выполнять простые задачи в gulp, например gulp dev или gulp prod.

Он ожидает файл config.js, похожий на ниже, хотя:

var config = {
    current : {
        // Will set when running each task
    },
    /* Keep dev and prod adhering to the same structure/model so that they are interchangable */
    dev : {
        output : 'dev_output',
    },
    prod : {
        output : 'prod_output'
    },
    sourceJSX : [ 'file1.jsx' ],
    etc...
}

Есть, вероятно, более аккуратные способы сделать это с помощью yargs, но если вы просто хотите чистый gulp + task, тогда это будет направление, которое я возьму.