【问题标题】:creating tasks using a loop [gulp]使用循环创建任务 [gulp]
【发布时间】:2014-04-09 16:25:35
【问题描述】:

我正在尝试基于 jsFiles 对象动态创建任务(缩小和连接)。 键将给出目标文件名,数组包含 src 文件。当我运行 gulp 时,我看到所有任务名称都在运行,但它只写入最后一个键,在这种情况下是 group2.js。这里有什么问题?

// imports here

var jsFiles = 
{
    group1:[file1.js,file2.js],
    group2:[file2.js,file3.js]
};

for (var key in jsFiles)
{
    gulp.task(key, function() {
        return gulp.src(jsFiles[key])
        .pipe(jshint())
        .pipe(uglify())
        .pipe(concat(key + '.js'))  // <- HERE
        .pipe(gulp.dest('public/js'));
    });
}

var defaultTasks = [];
for (var key in jsFiles)
{
    defaultTasks.push(key);
}
gulp.task('default', defaultTasks);

【问题讨论】:

    标签: javascript gulp


    【解决方案1】:

    另一种选择是使用与Object.keys 结合的函数式数组循环函数,如下所示:

    var defaultTasks = Object.keys(jsFiles);
    
    defaultTasks.forEach(function(taskName) {
       gulp.task(taskName, function() {
           return gulp.src(jsFiles[taskName])
              .pipe(jshint())
              .pipe(uglify())
              .pipe(concat(key + '.js'))
              .pipe(gulp.dest('public/js'));
       });
    });
    

    我觉得这样更简洁一些,因为循环和函数在同一个地方,所以更容易维护。

    【讨论】:

    • 然后使用 Gulp 4,您可以并行调用这些任务:gulp.parallel("scripts:app", "scripts:vendor") !简单,精彩^^
    • 但是你如何处理所有需要以相同方式工作的 50 个单独的任务,你还会使用 gulp.parallel 吗?
    • 我参加聚会有点晚了,但我通常会并行调用这 50 个任务,除非这些任务或您的计算机异常缓慢。我在大约 200 个简单的任务中使用它。
    【解决方案2】:

    使用 IIFE 在每次迭代中捕获“key”变量的值。 在您的示例中,在 concat 调用循环将已经完成并且变量 key 将具有最后一个值。

    for (var key in jsFiles)
    {
        (function(key) {
            gulp.task(key, function() {
                return gulp.src(jsFiles[key])
                    .pipe(jshint())
                    .pipe(uglify())
                    .pipe(concat(key + '.js'))  // <- HERE
                    .pipe(gulp.dest('public/js'));
            });
    
        })(key);
    
    }
    

    有关详细说明,请参阅function closures - 避免参考问题部分

    【讨论】:

    • 此解决方案有效,但 lint 不断警告在循环内创建函数。
    • @cmancre 可以声明并在循环中使用 key 参数调用分隔函数,该参数将由 ref 发送到函数中。当前问题的答案是捕获迭代变量。您没有在问题中提到有关成功 linting 的要求(:
    【解决方案3】:

    使用 Gulp#4.0,我喜欢使用 gulp.parallel() 比如:

    var plugins = require('gulp-load-plugins');
    var $ = plugins();
    
    var jsFiles = {
       // Libraries required by Foundation
       "jquery" : [
          "bower_components/jquery/dist/jquery.js",
          "bower_components/motion-ui/dist/motion-ui.js",
          "bower_components/what-input/dist/what-input.js"
       ],
       "angular" : [
          "bower_components/angular/angular.min.js",
          "bower_components/angular-animate/angular-animate.min.js",
          "bower_components/angular-aria/angular-aria.min.js",
          "bower_components/angular-material/angular-material.min.js",
          "bower_components/angular-messages/angular-messages.min.js",
          "bower_components/angular-sanitize/angular-sanitize.min.js",
          "bower_components/angular-ui-i18n/angular-ui-i18n.min.js"
       ],
       // Core Foundation files
       "foundation-sites" : [
          "bower_components/foundation-sites/dist/js/foundation.js"
       ],
       // Dropzone Library
       "dropzone" : [
          "bower_components/dropzone/dist/dropzone.js",
          "bower_components/ng-dropzone/dist/ng-dropzone.min.js"
       ]
    };
    
    var defaultTasks = Object.keys(jsFiles);
    
    defaultTasks.forEach(function (libName) {
       gulp.task( 'scripts:'+libName, function () {
          return gulp.src(jsFiles[libName])
             //.pipe($.jshint()) // if you want it
             //.pipe($.uglify()) // if you like it
             //.pipe($.concat(libName+'.js')) // .min.js if you Uglified it
             .pipe(gulp.dest('dist/lib/'+libName));
       });
    });
    
    gulp.task( 'bundle_javascript_dependencies',
       gulp.parallel(
          defaultTasks.map(function(name) { return 'scripts:'+name; })
       )
    );
    
    gulp.task('build',
       gulp.series(
          'clean',
          gulp.parallel( /* Any other task of function */ 'bundle_javascript_dependencies' )
       )
    );
    

    为我工作,我喜欢它!感谢 OverZealous 给我指路。

    【讨论】:

    • 不适合我,得到:“AssertionError [ERR_ASSERTION]: Task never defined: bundling libs: common”
    • 编辑:现在可以使用,在映射过程中使用了错误的名称
    【解决方案4】:

    cmancre 解决方案工作正常......但这里是我目前正在使用的修改和工作的解决方案:

    var jsFiles = 
    {
        group1:[file1.js,file2.js],
        group2:[file2.js,file3.js]
    };
    
    var defaultTasks = [];
    
    function createTask(key)
    {
        gulp.task(key, function() {
            return gulp.src(jsFiles[key])
                .pipe(uglify())
                .pipe(concat(key + '.js'))
                .pipe(rename({suffix: ".min"})) //Will create group1.min.js
                .pipe(gulp.dest('./assets/js'));
        });
    }
    
    for (var key in jsFiles)
    {
        createTask(key);
        defaultTasks.push(key);
    }
    
    gulp.task('default', defaultTasks, function(){
        for (var key in jsFiles)
        {
            //Will watch each js defined in group1 or group2
            gulp.watch(jsFiles[key], [key]) 
        }
    });
    

    【讨论】:

      【解决方案5】:

      基于 jslinterrors.com/dont-make-functions-within-a-loop 的解决方案:

      var jsFiles = 
      {
          group1:[file1.js,file2.js],
          group2:[file2.js,file3.js]
      };
      
      function createTask(key)
      {
         return gulp.src(jsFiles[key])
              .pipe(jshint())
              .pipe(uglify())
              .pipe(concat(key + '.js'))
              .pipe(gulp.dest('public/js'));
      
      }
      
      for (var key in jsFiles)
      {
          createTask(key);
      }
      
      var defaultTasks = [];
      for (var key in jsFiles)
      {
          defaultTasks.push(key);
      }
      gulp.task('default', defaultTasks);
      

      【讨论】:

      • 这个解决方案对我不起作用。看来 createTask(key) 是不够的。如果您没有显式调用 gulp.task(key),gulp 在执行默认任务时将无法找到该任务。我最终使用了 oaleynik 的答案。
      • 我怎样才能异步运行所有的任务?
      猜你喜欢
      • 1970-01-01
      • 2015-10-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多