Задача 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 завален несколькими ненужными функциями.

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

6 ответов


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

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));

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

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;
}

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

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

или если бы я хотел подпапку:

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

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

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

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


для начала, для записи, соответствующий выпуск github залпом#1225.

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

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, со стоимостью необходимости указывать "проводку" задачи метод для новой функции, которая использует определенный путь config. Но это имеет то преимущество, что всякий раз, когда вам нужно внести изменения в способ задачи, то в одном месте. Также вы можете легко увидеть, какая часть сайта использует какие методы.

Это также то, как я справляюсь с этой проблемой в моем проект gulpfile.


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

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']);  

немного опоздал на вечеринку. У меня есть аналогичная проблема, не удалось найти простое решение, поэтому я придумал этот подход, чтобы использовать комбинацию npm и gulp.

скажите, что ваш gulpfile:

var args = require('yargs');

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

и ваш файл npm:

{
  ...
  "scripts": {
    "dev" : "gulp transform-moove-jsx --./output/development/ && gulp one && gulp two",
    "prod" : "gulp transform-moove-jsx --./output/production/  && gulp one && gulp two",
  }
}

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


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

имейте следующее в файле 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 dev или gulp prod.

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

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...
}

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