Pergunta

I have multiple sets of js modules that I would like to concat into separate files. I don't want to have to create a seperate concat task for each file. It would make more sense to be able to pass arguments into the gulp task "concat". Unfortunately gulp doesn't allow arguments to be passed into tasks(I'm sure for good reason).

Any ideas of how I can accomplish this?


Use Case

A specific scenario would be website that has a global.js file for all pages as well as page specific js files.

Creating a task for each page specific js file will quickly make the gulpfile.js hard to manage as the site grows.


My dev invironment:

I have a dev/js/ directory which has multiple sub-directories. Each sub-directory contains modules for a specific js file. So each sub-directory needs to be concatenated into it's own file within lib/js/.


Perhaps requirejs?

Maybe I should just look into using a module loader like requirejs.

Foi útil?

Solução 3

Note: You'd probably be better off using a bundler like browserify or webpack. Since asking this question I have switched to browserify rather than trying to roll my own solution.

Improved Solution:

var fs = require("fs");
/* other requires omitted */

/* Set JS dev directory in one place */
var jsSrc = "dev/js/";
var jsDest = "lib/js/";

var concat = function (path) {

      path     = path.replace(/\\/g, "/");
  var src      = path.replace(/(\/[^\/]+?\.js$)|(\/$)/, "/*.js";
  var filename = src.match(/\/([^\/]+?)(\/[^\/]+?\.js$)/)[1] + ".js";

  gulp.src(src)
      .pipe(concat(filename)
      .pipe(gulp.dest(jsDest));
});

/* The concat task just runs the concat function for
 * each directory in the javascript development directory.
 * It will take a performance hit, but allows concat to be
 * run as a dependency in a pinch.
 */
gulp.task("concat", function () {
  var dirArr = fs.readdirSync(jsDev);

  for (var d in dirArr) {
    var path = jsDev+dirArr[d]+"/";
    concat(path);
  }
});

/* Run "concat" as a dependency of the default task */
gulp.taks("default", ["concat"], function () {

  var JSWatcher = gulp.watch([jsSrc+"**/*.js"]);

  JSWatcher.on("change", function (event) {
    concat(event.path);
  });

});

Alright, I think this works. It's a little bit of a hack though, and doesn't work for all use cases.

... removed previous example to save space ...

Outras dicas

I needed to take modules from my source sub-directory (src/modules/), concatenate a specific file to each individually (src/distribution), then pipe the result to a sub-directory in my distribution folder (dist/js/modules/).

I wasn't sure how many modules would end up being written for this project so I wanted to do it dynamically and found this to be the best (simplest) solution:

gulp.task("modules:js", () => {
let modules = fs.readdirSync("src/modules");
let concatModule = (module) => {
    return gulp.src([
        'src/distribution',
        module
    ])
    .pipe(concat(module))
    .pipe(gulp.dest("build/js/modules"));
}
for (let module of modules) {
    concatModule(module);
};
});

You could make concatJS a higher-order function:

var concatJS = function (src, filename, dest) {
  return function() {
    gulp.src(src)
      .pipe(concat(filename))
      .pipe(gulp.dest(dest));
  };
};

gulp.task('concat-1', concatJS('src/module-1', 'module-1.js', 'build/module-1'));
gulp.task('concat-2', concatJS('src/module-2', 'module-2.js', 'build/module-2'));
//etc...
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top