I have the following folder structure:
+---controllers
| | index.js
| |
| +---api
| | index.js
| | test.js
| |
| \---routes
| | index.js
| |
| \---partials
| | index.js
| |
| +---bugs
| +---compatibility
| +---documentation
| | amd.js
| | api.js
| | jquery.js
| | options.js
| | usage.js
| |
| \---installation
I'm trying to create an object out of the tree that would look like this:
{
api: {
index: require("index.js"),
test: require("test.js")
},
routes: {
index: require("index.js"),
partials: {
index: require("index.js"),
bugs: {},
compatibility: {},
documentation: {
amd: require("amd.js"),
api: require("api.js"),
jquery: require("jquery.js"),
options: require("options.js"),
usage: require("usage.js")
},
installation: {}
}
}
}
I just cannot figure the logic to do it, I've managed only to get an array of the tree with the following code:
/**
* Controllers
*/
var path = require("path"),
util = require("util"),
fs = require("fs"),
wrench = require("wrench");
var controllers = {},
tree = wrench.readdirSyncRecursive(path.resolve(__dirname, "./")).filter(function (value) {
return value !== "index.js";
});
var key,
i = tree.length - 1;
while (i >= 0) {
key = tree[i];
console.log(fs.lstatSync(path.resolve(__dirname, key)).isDirectory(), key.split(path.sep));
i--;
}
module.exports = controllers;
I'm not really sure how I'm supposed to create the object after I start looping the folder tree, but I'm thinking that I could only do it if I have some recursive function ?
EDIT:
The reason why I'm trying to do it is because I'm trying to have some kind of dynamic routing for my express application.
In my express application I would have something like:
application.get("/api/index", controllers.api.index);
application.get("/api/test", controllers.api.test);
application.get("/", controllers.routes.index);
application.get("/partials/", controllers.routes.partials.index);
application.get("/partials/documentation/amd", controllers.routes.partials.documentation.amd);
...
And each of those files would export something similar to:
exports.index = function (request, response) {
return response.render("index");
};
Depending on where the file is and maybe with some more logic (in case there is a model that it has to load).
So probably there is a better way of managing dynamic routes than what I'm trying, if so I'm opened for suggestions.
I came up with a recursive file walker for your case.
var fs = require('fs');
var filetree = {};
var walkDirectory = function(path, obj) {
var dir = fs.readdirSync(path);
for (var i = 0; i < dir.length; i++) {
var name = dir[i];
var target = path + '/' + name;
var stats = fs.statSync(target);
if (stats.isFile()) {
if (name.slice(-3) === '.js') {
obj[name.slice(0, -3)] = require(target);
}
} else if (stats.isDirectory()) {
obj[name] = {};
walkDirectory(target, obj[name]);
}
}
};
walkDirectory('./controllers', filetree);
console.log(filetree);
The function will scan the directory, and if the file is a script, then it will be loaded. If it is a directory, the function will pass the directory reference to itself and do the same thing again.