【问题标题】:Gulp task with different source depending on arguments根据参数不同来源的 Gulp 任务
【发布时间】:2015-09-01 01:14:28
【问题描述】:

我想用 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."

随着我们从 dev gulp 任务内部调用越来越多的 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 充满了几个不必要的功能。

有没有更好的办法?

【问题讨论】:

  • 不太熟悉 gulp,但您是否尝试从 move() 本身调用 moveViews()moveJs()
  • 我不明白你为什么要通过 gulp 而不是使用 mvcp 来做到这一点???
  • 这值得更多关注,这是一个多么好的问题——从那以后你找到了一个可行的解决方案吗?我只是遇到了这个。
  • @DanKanze 我也会对您的意见感兴趣,以获取下面的新答案。
  • 你总是知道devprod 的路径吗?如果是这样,只需在 gulpfile 的最高范围内创建一个变量 destination,然后在 task 内设置它。

标签: javascript gulp dry yargs


【解决方案1】:

您的第二次尝试是正确的,只需要使用一点DRYclosures

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

【讨论】:

  • 使用gulp 4,我不得不使用这个任务签名gulp.task('dev', () => { return createTransformTaskClosure(config.output_development) });
【解决方案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 无法处理任务中的参数。为了处理开发/生产构建,我们可以使用yargsgulp-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 mytask --production 运行 gulp,如果确实需要在一个构建中多次运行相同的任务,则确实不适合。它不适合,因为它根本不干。

    例如,如果您需要为不同的站点部分生成多个 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 project 中处理此问题的方式。

    【讨论】:

    • 在没有适当解释的情况下投反对票是令人作呕的。
    【解决方案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】:

      聚会有点晚了。我有类似的问题,找不到简单的解决方案,所以我想出了这种方法来使用 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 的一系列限制。

      【讨论】:

        【解决方案6】:

        这有帮助吗?

        const { src, dest, series } = require('gulp');
        
        function moveJSX(dest = "./output/development/", label = "dev") {
        
          const source = config.sourceJSX;
        
          function task() { return src(source).pipe(dest(dest)); };
        
          task.displayName = `moveJSX:${label}`;
          
          return task;
        }
        
        // usage
        series(moveJSX(), moveJSX("./output/production/", "prod"));
        

        随意删除标签的东西。

        【讨论】:

          【解决方案7】:

          不确定这是否有用,但只是我的几便士的想法:-

          在 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 devgulp 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,那么这是我会采取的方向。

          【讨论】:

            猜你喜欢
            • 2017-12-19
            • 1970-01-01
            • 2015-05-27
            • 2018-03-01
            • 2015-04-16
            • 2016-10-19
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多