How does requiring modules manually differ from calling them dynamically with browserify?

Sorry for the awkward post title but it's a very weird situation to be in. In my project I have a folder structure like so:

/filters
     index.js
     [...]
/controllers
     index.js
     [...]
app.js

app.js is basically the entry point of my application and I thought it would be cool if I could automatically load the contents of those directories by require()ing the directory and having index.js in each of those directories take care of loading whatever it needs to load.

But I'm running into a problem I don't understand. Because I'm being intentionally obtuse (this is a learning/experimentation exercise) I decided to try and keep it as DRY as humanly possible so I tried this big of code to handle the module loading:

'use strict';

var customModules = [
    'controllers',
    'filters'
];

//require('./controllers');
//require('./filters');

for (var i in customModules) {
    if (customModules.hasOwnProperty(i)) {
        require('./' + customModules[i]);
    }
}

var nativeModules = [
    'ngSanitize'
];

angular.module('app', customModules.concat(nativeModules));

I'm planning on extracting that to it's own module but it'll do for demonstration. For some reason this code throws this exception:

Uncaught Error: Cannot find module './controllers'

But when I load it using a static string

require('./controllers');

No problems, everything works and my sample application behaves as expected.

Checkout the Browserify Handbook at how browserify works (emphasis mine):

Browserify starts at the entry point files that you give it and searches for any require() calls it finds using static analysis of the source code's abstract syntax tree.

For every require() call with a string in it, browserify resolves those module strings to file paths and then searches those file paths for require() calls recursively until the entire dependency graph is visited.

Bottom line: the dependencies must be statically declared; your code involving the dynamcally-created require() calls cannot work (although a good idea in principle).

You could achieve a similar result using server-side or build-time techniques.