使用循环创建任务[gulp]

cma*_*cre 18 javascript gulp

我正在尝试基于jsFiles对象动态创建任务(minify和concat).该密钥将给予目标文件名和数组包含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);
Run Code Online (Sandbox Code Playgroud)

Ove*_*ous 22

另一个选择是使用功能数组循环函数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'));
   });
});
Run Code Online (Sandbox Code Playgroud)

我觉得这有点干净,因为你在同一个地方有循环和功能,所以它更容易维护.


oal*_*nik 6

使用IIFE在每次迭代中捕获'key'变量的值.在您的示例中,在concat调用循环的时刻已经完成,变量键将具有最后一个值.

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

}
Run Code Online (Sandbox Code Playgroud)

有关详细说明,请参阅此函数闭包 - 避免参考问题部分

  • 这个解决方案有效,但lint一直警告在循环内创建函数. (2认同)

小智 6

使用 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' )
   )
);
Run Code Online (Sandbox Code Playgroud)

为我工作,我喜欢它!感谢 OverZealous 为我指明了道路。


cma*_*cre 0

基于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);
Run Code Online (Sandbox Code Playgroud)