aseemk / requireDir

Node.js helper to require() directories.
MIT License
484 stars 60 forks source link

Support for Parameters #15

Closed willpracht closed 6 years ago

willpracht commented 9 years ago

It would be fantastic to have the ability to pass in parameters to the require().

Example:

require('require-dir')('./path/to/tasks', [gulp, $]);

becomes something like...

_.each(tasks, function (task) {
  require(task)(gulp, $);
}

This would give us the ability to split up Gulp tasks into their own files.

Full Example:

// ./tasks/artifact.js

module.exports = function (gulp, $) {
  'use strict';

  /**
   * Artifact
   * @description Build `./target/app.zip` from distribution files.
   */
  return gulp.task('artifact', 'Build `./target/app.zip` from distribution files.', ['build'], function () {
    log('Building artifact...');

    gulp.src(config.dist + '**')
      .pipe($.if(args.verbose, $.print()))
      .pipe($.zip(config.artifact.filename))
      .pipe(gulp.dest('./.tmp'))
      .pipe($.notify(_.extend(config.notify, {
        message: 'Artifact created: ' + config.target + config.artifact.filename
      })));
  });
};
// ./gulpfile.js

require('require-dir')('./path/to/tasks', [gulp, $]);

Does anyone have any thoughts on this?

willpracht commented 9 years ago

Actually, the syntax would be more like this:

require('require-dir')('./path/to/tasks')(gulp, $, config);
ceoaliongroo commented 9 years ago

:+1:

klarkc commented 9 years ago

I want this plz

dsebastien commented 8 years ago

This one is a blocker for me, I'll try to look into it.

dsebastien commented 8 years ago

Now that I've looked a bit more at how require-dir actually works, I realize that we could simply achieve what we want by iterating over the object returned when calling requireDir(...). Basically if the required module returns a function, one can easily invoke it afterwards.

I'll send a pull request anyway to add support for an 'args' property on the options object that require-dir already has; this can still be used as a short-hand way of passing some value/object to all loaded modules (assuming they all export a function that can be directly invoked)

willpracht commented 8 years ago

+1 @dsebastien

dsebastien commented 8 years ago

Just for the record here's a simplified version of what I've ended up doing in my project:

// ./gulp/tasks/something.js
...
module.exports = {
    registerTask: function(gulp){
    ...
}
...

// consumer
const loadedModules = requireDir("./gulp/tasks", {
    recurse: false
});

for(let key in loadedModules){
    if(loadedModules.hasOwnProperty(key)){
        let loadedModule = loadedModules[ key ];

        if(loadedModule.registerTask){
            console.log(`Registering module: ${key}`);
            loadedModule.registerTask(gulp);
        } else{
            throw new TypeError(`One of the loaded modules does not expose the expected interface: ${key}`);
        }
    }
}

You might need something a bit more crafty if you need recursion though :)

cauealvesbraz commented 8 years ago

:+1:

matiasgabrielgarcia commented 8 years ago

i was thinking something like this:

require('require-dir')('./tasks',{'params':[someArg1, someArg2, someArg3]});

When require, pass params trough apply function.

  if (opts.duplicates) {
    map[file] = require(path).apply(this,opts.params);
    if (!map[base]) {
      map[base] = map[file];
    }
  } else {
    map[base] = require(path).apply(this,opts.params);
    break;
  }
yocontra commented 6 years ago

You can do this with the new mapValue parameter: mapValue(fn) { return fn(args); }