389

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);
}};
Braiam
  • 1
  • 11
  • 47
  • 78
Harry
  • 52,711
  • 71
  • 177
  • 261

15 Answers15

590

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
tbranyen
  • 8,507
  • 1
  • 21
  • 18
  • 162
    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 https://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. – Trevor Burnham Apr 26 '11 at 05:18
  • 26
    `require` is a synchronous function so there is no benefits from callback. I would use fs.readdirSync instead. – Rafał Sobota Jan 10 '12 at 22:35
  • 4
    Thanks, ran into this same problem today and thought "why isn't there a require('./routes/*')?". – Richard Clayton Feb 11 '12 at 14:09
  • @TrevorBurnham Thank you! I feel this should be added to the documentation. – Inc1982 Feb 17 '12 at 15:26
  • 1
    @RichardClayton what would the return value be of `require('./routes/*')`? – Robert Martin Jul 24 '12 at 19:59
  • 3
    @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. – Richard Clayton Sep 02 '12 at 12:08
  • 1
    @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.... – Robert Martin Sep 03 '12 at 21:48
  • 2
    @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'}` – antitoxic Oct 02 '12 at 21:11
  • 2
    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. – Cory Gross Jun 29 '13 at 19:45
  • 1
    What is '*'? A file named *.js inside the directory? I'm confused as to what your response means Cory Gross. – tbranyen Jun 30 '13 at 20:51
  • 1
    You'd want to guard against non-JS files with something like `if (path.extname(file) === '.js') require("./routes/" + file)(app);` – james_womack Jul 09 '13 at 10:47
  • @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 https://github.com/abhayathapa/ember-blogger/blob/master/app/initialize.coffee – Abhaya Dec 07 '13 at 14:40
  • 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"))`. – Jason Walton Oct 13 '14 at 03:59
  • 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. – tbranyen Oct 13 '14 at 04:15
229

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 ) );
});
David Weldon
  • 63,632
  • 11
  • 148
  • 146
Diogo Cardoso
  • 21,637
  • 26
  • 100
  • 138
  • 15
    Everybody should use this answer ;) – Jamie Hutber Jul 05 '15 at 12:16
  • 3
    Best answer! Easier than all the other options, especially for recursive-child folders that have files you need to include. – ngDeveloper Jul 08 '15 at 18:36
  • 1
    Recommend globbing due to the overall control you have over the sets of filespec criteria you can specify. – stephenwil Sep 10 '15 at 09:05
  • 6
    `glob`? you mean `glob-savior-of-the-nodejs-race`. Best answer. – deepelement Apr 21 '17 at 16:30
  • 2
    What variables does it save to? `var x = require('x')` What is `var x` in this case? – Matt Westlake Oct 18 '17 at 20:55
  • 1
    glob.sync( __dirname + '/routes/**/*.js' ) – danday74 Feb 01 '18 at 06:41
  • 8
    Use map() for save links: const routes = glob.sync('./routes/**/*.js').map(file => require( path.resolve( file ) )); – lexa-b Mar 02 '18 at 13:59
  • Excellent answer, but no need to use `path.resolve( file );` ! Simply using `require(file);` since `file` is a filename that includes the file path – alwaysbeshels Feb 11 '20 at 21:42
  • 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. – SikoSoft Jun 01 '22 at 21:21
77

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.

Greg Wang
  • 1,357
  • 1
  • 13
  • 17
  • 5
    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? –  Aug 04 '15 at 20:57
71

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');
Stan
  • 25,744
  • 53
  • 164
  • 242
studgeek
  • 14,272
  • 6
  • 84
  • 96
  • 3
    +1 for `require-dir` because it automatically excludes the calling file (index) and defaults to the current directory. Perfect. – biofractal Mar 05 '15 at 09:15
  • 2
    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. – Mnebuerquo Jul 25 '15 at 14:48
  • require-dir is now the most downloaded (but notably it doesn't support file exclusion at time of writing) – Sean Anderson Dec 09 '15 at 17:50
  • Three years after Sean's comment above, `require-dir` added a `filter` option. – givemesnacks Oct 12 '19 at 16:33
7

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()
blented
  • 2,699
  • 2
  • 23
  • 17
6

One more option is require-dir-all combining features from most popular packages.

Most popular require-dir does not have options to filter the files/dirs and does not have map function (see below), but uses small trick to find module's current path.

Second by popularity require-all has regexp filtering and preprocessing, but lacks relative path, so you need to use __dirname (this has pros and contras) like:

var libs = require('require-all')(__dirname + '/lib');

Mentioned here require-index is quite minimalistic.

With map you may do some preprocessing, like create objects and pass config values (assuming modules below exports constructors):

// Store config for each module in config object properties 
// with property names corresponding to module names 
var config = {
  module1: { value: 'config1' },
  module2: { value: 'config2' }
};

// Require all files in modules subdirectory 
var modules = require('require-dir-all')(
  'modules', // Directory to require 
  { // Options 
    // function to be post-processed over exported object for each require'd module 
    map: function(reqModule) {
      // create new object with corresponding config passed to constructor 
      reqModule.exports = new reqModule.exports( config[reqModule.name] );
    }
  }
);

// Now `modules` object holds not exported constructors, 
// but objects constructed using values provided in `config`.
alykoshin
  • 866
  • 8
  • 6
6

I know this question is 5+ years old, and the given answers are good, but I wanted something a bit more powerful for express, so i created the express-map2 package for npm. I was going to name it simply express-map, however the people at yahoo already have a package with that name, so i had to rename my package.

1. basic usage:

app.js (or whatever you call it)

var app = require('express'); // 1. include express

app.set('controllers',__dirname+'/controllers/');// 2. set path to your controllers.

require('express-map2')(app); // 3. patch map() into express

app.map({
    'GET /':'test',
    'GET /foo':'middleware.foo,test',
    'GET /bar':'middleware.bar,test'// seperate your handlers with a comma. 
});

controller usage:

//single function
module.exports = function(req,res){

};

//export an object with multiple functions.
module.exports = {

    foo: function(req,res){

    },

    bar: function(req,res){

    }

};

2. advanced usage, with prefixes:

app.map('/api/v1/books',{
    'GET /': 'books.list', // GET /api/v1/books
    'GET /:id': 'books.loadOne', // GET /api/v1/books/5
    'DELETE /:id': 'books.delete', // DELETE /api/v1/books/5
    'PUT /:id': 'books.update', // PUT /api/v1/books/5
    'POST /': 'books.create' // POST /api/v1/books
});

As you can see, this saves a ton of time and makes the routing of your application dead simple to write, maintain, and understand. it supports all of the http verbs that express supports, as well as the special .all() method.

r3wt
  • 4,642
  • 2
  • 33
  • 55
4

Expanding on this glob solution. Do this if you want to import all modules from a directory into index.js and then import that index.js in another part of the application. Note that template literals aren't supported by the highlighting engine used by stackoverflow so the code might look strange here.

const glob = require("glob");

let allOfThem = {};
glob.sync(`${__dirname}/*.js`).forEach((file) => {
  /* see note about this in example below */
  allOfThem = { ...allOfThem, ...require(file) };
});
module.exports = allOfThem;

Full Example

Directory structure

globExample/example.js
globExample/foobars/index.js
globExample/foobars/unexpected.js
globExample/foobars/barit.js
globExample/foobars/fooit.js

globExample/example.js

const { foo, bar, keepit } = require('./foobars/index');
const longStyle = require('./foobars/index');

console.log(foo()); // foo ran
console.log(bar()); // bar ran
console.log(keepit()); // keepit ran unexpected

console.log(longStyle.foo()); // foo ran
console.log(longStyle.bar()); // bar ran
console.log(longStyle.keepit()); // keepit ran unexpected

globExample/foobars/index.js

const glob = require("glob");
/*
Note the following style also works with multiple exports per file (barit.js example)
but will overwrite if you have 2 exports with the same
name (unexpected.js and barit.js have a keepit function) in the files being imported. As a result, this method is best used when
your exporting one module per file and use the filename to easily identify what is in it.

Also Note: This ignores itself (index.js) by default to prevent infinite loop.
*/

let allOfThem = {};
glob.sync(`${__dirname}/*.js`).forEach((file) => {
  allOfThem = { ...allOfThem, ...require(file) };
});

module.exports = allOfThem;

globExample/foobars/unexpected.js

exports.keepit = () => 'keepit ran unexpected';

globExample/foobars/barit.js

exports.bar = () => 'bar run';

exports.keepit = () => 'keepit ran';

globExample/foobars/fooit.js

exports.foo = () => 'foo ran';

From inside project with glob installed, run node example.js

$ node example.js
foo ran
bar run
keepit ran unexpected
foo ran
bar run
keepit ran unexpected
jtlindsey
  • 4,346
  • 4
  • 45
  • 73
3

One module that I have been using for this exact use case is require-all.

It recursively requires all files in a given directory and its sub directories as long they don't match the excludeDirs property.

It also allows specifying a file filter and how to derive the keys of the returned hash from the filenames.

Thorsten Lorenz
  • 11,781
  • 8
  • 52
  • 62
3

Require all files from routes folder and apply as middleware. No external modules needed.

// require
const { readdirSync } = require("fs");

// apply as middleware
readdirSync("./routes").map((r) => app.use("/api", require("./routes/" + r)));
Ryan Dhungel
  • 3,637
  • 4
  • 19
  • 26
2

I'm using node modules copy-to module to create a single file to require all the files in our NodeJS-based system.

The code for our utility file looks like this:

/**
 * Module dependencies.
 */

var copy = require('copy-to');
copy(require('./module1'))
.and(require('./module2'))
.and(require('./module3'))
.to(module.exports);

In all of the files, most functions are written as exports, like so:

exports.function1 = function () { // function contents };
exports.function2 = function () { // function contents };
exports.function3 = function () { // function contents };

So, then to use any function from a file, you just call:

var utility = require('./utility');

var response = utility.function2(); // or whatever the name of the function is
scottnath
  • 71
  • 6
2

Using this function you can require a whole dir.

const GetAllModules = ( dirname ) => {
    if ( dirname ) {
        let dirItems = require( "fs" ).readdirSync( dirname );
        return dirItems.reduce( ( acc, value, index ) => {
            if ( PATH.extname( value ) == ".js" && value.toLowerCase() != "index.js" ) {
                let moduleName = value.replace( /.js/g, '' );
                acc[ moduleName ] = require( `${dirname}/${moduleName}` );
            }
            return acc;
        }, {} );
    }
}

// calling this function.

let dirModules = GetAllModules(__dirname);
M. Hamza Rajput
  • 7,810
  • 2
  • 41
  • 36
  • 1
    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 – Werlious Apr 13 '21 at 20:21
1

Can use : https://www.npmjs.com/package/require-file-directory

  • Require selected files with name only or all files.
  • No need of absoulute path.
  • Easy to understand and use.
  • 2
    Welcome to SO. Please read this [how-to-answer](http://stackoverflow.com/help/how-to-answer) for providing quality answer. – thewaywewere May 25 '17 at 08:03
1

Create an index.js file in your folder with this code :

const fs = require('fs')    
const files = fs.readdirSync('./routes')
for (const file of files) {
  require('./'+file)
}

And after that you can simply load all the folder with require("./routes")

-2

If you include all files of *.js in directory example ("app/lib/*.js"):

In directory app/lib

example.js:

module.exports = function (example) { }

example-2.js:

module.exports = function (example2) { }

In directory app create index.js

index.js:

module.exports = require('./app/lib');
xav
  • 5,452
  • 7
  • 48
  • 57