node.js require all files in a folder?

324,866

Solution 1

When require is given the path of a folder, it'll look for an index.js file in that folder; if there is one, it uses that, and if there isn't, it fails.

It would probably make most sense (if you have control over the folder) to create an index.js file and then assign all the "modules" and then simply require that.

yourfile.js

var routes = require("./routes");

index.js

exports.something = require("./routes/something.js");
exports.others = require("./routes/others.js");

If you don't know the filenames you should write some kind of loader.

Working example of a loader:

var normalizedPath = require("path").join(__dirname, "routes");

require("fs").readdirSync(normalizedPath).forEach(function(file) {
  require("./routes/" + file);
});

// Continue application logic here

Solution 2

I recommend using glob to accomplish that task.

var glob = require( 'glob' )
  , path = require( 'path' );

glob.sync( './routes/**/*.js' ).forEach( function( file ) {
  require( path.resolve( file ) );
});

Solution 3

Base on @tbranyen's solution, I create an index.js file that load arbitrary javascripts under current folder as part of the exports.

// Load `*.js` under current directory as properties
//  i.e., `User.js` will become `exports['User']` or `exports.User`
require('fs').readdirSync(__dirname + '/').forEach(function(file) {
  if (file.match(/\.js$/) !== null && file !== 'index.js') {
    var name = file.replace('.js', '');
    exports[name] = require('./' + file);
  }
});

Then you can require this directory from any where else.

Solution 4

Another option is to use the package require-dir which let's you do the following. It supports recursion as well.

var requireDir = require('require-dir');
var dir = requireDir('./path/to/dir');

Solution 5

I have a folder /fields full of files with a single class each, ex:

fields/Text.js -> Test class
fields/Checkbox.js -> Checkbox class

Drop this in fields/index.js to export each class:

var collectExports, fs, path,
  __hasProp = {}.hasOwnProperty;

fs = require('fs');    
path = require('path');

collectExports = function(file) {
  var func, include, _results;

  if (path.extname(file) === '.js' && file !== 'index.js') {
    include = require('./' + file);
    _results = [];
    for (func in include) {
      if (!__hasProp.call(include, func)) continue;
      _results.push(exports[func] = include[func]);
    }
    return _results;
  }
};

fs.readdirSync('./fields/').forEach(collectExports);

This makes the modules act more like they would in Python:

var text = new Fields.Text()
var checkbox = new Fields.Checkbox()
Share:
324,866
Harry
Author by

Harry

Updated on July 08, 2022

Comments

  • Harry
    Harry almost 2 years

    How do I require all files in a folder in node.js?

    need something like:

    files.forEach(function (v,k){
      // require routes
      require('./routes/'+v);
    }};
    
  • Trevor Burnham
    Trevor Burnham about 13 years
    To add some clarification: When require is given the path of a folder, it'll look for an index.js in that folder; if there is one, it uses that, and if there isn't, it fails. See github.com/christkv/node-mongodb-native for a real-world example of this: There's an index.js in the root directory that requires ./lib/mongodb, a directory; ./lib/mongodb/index.js' makes everything else in that directory available.
  • Rafał Sobota
    Rafał Sobota over 12 years
    require is a synchronous function so there is no benefits from callback. I would use fs.readdirSync instead.
  • Richard Clayton
    Richard Clayton about 12 years
    Thanks, ran into this same problem today and thought "why isn't there a require('./routes/*')?".
  • Inc1982
    Inc1982 about 12 years
    @TrevorBurnham Thank you! I feel this should be added to the documentation.
  • Robert Martin
    Robert Martin almost 12 years
    @RichardClayton what would the return value be of require('./routes/*')?
  • Richard Clayton
    Richard Clayton over 11 years
    @RobertMartin it's useful when you don't need a handle to anything exported; for instance, if I just wanted to pass an Express app instance to a set of files that would bind routes.
  • Robert Martin
    Robert Martin over 11 years
    @RichardClayton I get that. I am pointing out that normally require will return the exports object. But in the case of requiring multiple files, it would not be obvious what should be the return value....
  • antitoxic
    antitoxic over 11 years
    @TrevorBurnham To add, the main file (i.e. index.js) file of a directory can be changed via package.json in this directory. Like so: {main: './lib/my-custom-main-file.js'}
  • Cory Gross
    Cory Gross almost 11 years
    The return value of require('./directory/*') could be an object with as many properties as there are valid js files in the directory, the name of each property being the basename of the js file, and the value of each being the require of that single file. Its really pretty obvious to me.
  • tbranyen
    tbranyen almost 11 years
    What is '*'? A file named *.js inside the directory? I'm confused as to what your response means Cory Gross.
  • james_womack
    james_womack almost 11 years
    You'd want to guard against non-JS files with something like if (path.extname(file) === '.js') require("./routes/" + file)(app);
  • Abhaya
    Abhaya over 10 years
    @TrevorBurnham I'm having to require all the files here like this. I dont know much about node.Is there anything I can do to iterate the objects without having to require every new file everytime github.com/abhayathapa/ember-blogger/blob/master/app/…
  • Jason Walton
    Jason Walton over 9 years
    Note that the "working example of loader" above is incorrect - readdirSync('./routes') will read the routes directory in the current working directory, when you actually want to load the routes directory in the same folder as the source file. It will appear to work if you run the file from the same folder as the file, but will fail if you try to run it from any other folder. This should be readdirSync(path.join(__dirname, "routes")).
  • tbranyen
    tbranyen over 9 years
    Jason, I believe that path.resolve will work as well. I'll update OP with your fix for now and will update to resolve if that works too.
  • biofractal
    biofractal about 9 years
    +1 for require-dir because it automatically excludes the calling file (index) and defaults to the current directory. Perfect.
  • Jamie Hutber
    Jamie Hutber almost 9 years
    Everybody should use this answer ;)
  • ngDeveloper
    ngDeveloper almost 9 years
    Best answer! Easier than all the other options, especially for recursive-child folders that have files you need to include.
  • Mnebuerquo
    Mnebuerquo almost 9 years
    In npm there are a few more similar packages: require-all, require-directory, require-dir, and others. The most downloaded seems to be require-all, at least in July 2015.
  • Admin
    Admin over 8 years
    I know this is more than a year old, but you can actually require JSON files too, so perhaps something like /\.js(on)?$/ would be better. Also isn't !== null redundant?
  • stephenwil
    stephenwil over 8 years
    Recommend globbing due to the overall control you have over the sets of filespec criteria you can specify.
  • Sean Anderson
    Sean Anderson over 8 years
    require-dir is now the most downloaded (but notably it doesn't support file exclusion at time of writing)
  • deepelement
    deepelement about 7 years
    glob? you mean glob-savior-of-the-nodejs-race. Best answer.
  • thewaywewere
    thewaywewere almost 7 years
    Welcome to SO. Please read this how-to-answer for providing quality answer.
  • Matt Westlake
    Matt Westlake over 6 years
    What variables does it save to? var x = require('x') What is var x in this case?
  • danday74
    danday74 over 6 years
    glob.sync( __dirname + '/routes/**/*.js' )
  • lexa-b
    lexa-b about 6 years
    Use map() for save links: const routes = glob.sync('./routes/**/*.js').map(file => require( path.resolve( file ) ));
  • givemesnacks
    givemesnacks over 4 years
    Three years after Sean's comment above, require-dir added a filter option.
  • alwaysbeshels
    alwaysbeshels about 4 years
    Excellent answer, but no need to use path.resolve( file ); ! Simply using require(file); since file is a filename that includes the file path
  • Werlious
    Werlious about 3 years
    One suggestion for this answer, the current regex will match weird things like "serverjslib.js" and convert it to "servelib", which would break things. Notice how the "r" in server was cut off. Thats because your regex is really matching "[any single character]js". Obviously that module name is terrible, but the same goes for things like "express-json.js", "load-json-file.js" or "parse-json.js", mangling the names into "expresson", "loadon-file" and "parseon" respectively. This can be fixed by changing your regex to /\.js$/, matching only the literal dot and js at the end
  • Artyom Ionash
    Artyom Ionash over 2 years
    But why is path being requested here?
  • SikoSoft
    SikoSoft almost 2 years
    Warning to anyone trying to use this today with a newer Webpack version that it will cause issues due to lack of polyfill support. A number of the packages glob relies on are no longer provided by Webpack (path, assert, fs). Even with configuring webpack resolve fallbacks, I still could not get the solution here to run in a Webpack project.