Code Loader in Node


Helluva snowstorm today. A very simple little snippet today. The two sentences are not related.

This may or may not be best practice as it adds a layer of magic and makes debugging a bit harder if you don't do it right.

The problem is that once your node express project has many routes in include, then the include code begins to look bad. You have a series of app.use() and a directory of routes where you want to load all it anyway.

I originally searched the documentation of express to see if there was a way to include an entire directory but didn't find anything. When I expanded my search to stackoverflow, I found simple solution that I also thought of but didn't quite like. I'm taking the fact that I found it online as a sign that maybe it isn't a bad practice.

The idea of loading an entire directory of code is that you simply read in the directory, looping through each file and requiring it into the project.

This method actually was written for simply requiring files, but I modified it slightly to act as a route loader.

require("fs").readdirSync('./routes').forEach(function (f) {
    if (f === "index.js") return;
    app.use('/', require("./routes/" + f));
app.use('/', require("./routes/index"));

I removed all of the route code and swapped it for this chunk of code. The issue with this, is that now you have no real visibility into what's being loaded and you also lose the url structure, everything will be set to the root path.

I had to modify my routes as I did have different handlers for different sub paths, but I moved the sub paths to inside the route rather than leave it in app.js. This seems to be a small price to pay to make the loading of routes simpler.

This also helps to enforce a bit of code structure which I am happy about. I had some utility functions and middleware in the routes folder which I had to move out of the routes folder as I don't want it loaded. If I didn't move the files, express would throw an error about trying to load middleware that didn't really exist.

I also have an index.js that handles general URLs, this is something that I want at the end of the code load. Once all the routes are set up, I want a fall back route at the very end. However because I can't guarantee the order the directory is read in, I simply check for the index and skip it and handle the load manually.

Even with the downsides of being more careful and being unable to register routes specifically, I think these few lines of code are really clean up the mess it was before.