17

I am using Browserify to compile a large Node.js application into a single file (using options --bare and --ignore-missing [to avoid troubles with lib-cov in Express]). I have some code to dynamically load modules based on what is available in a directory:

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

fs.readdirSync(__dirname).forEach(function (file) {
    if (file !== 'index.js' && fs.statSync(path.join(__dirname, file)).isFile()) {
        module.exports[file.substring(0, file.length-3)] = require(path.join(__dirname, file));
    }
});

I'm getting strange errors in my application where aribtrary text files are being loaded from the directory my compiled file is loaded in. I think it's because paths are no longer set correctly, and because Browserify won't be able to require() the correct files that are dynamically loaded like this.

Short of making a static index.js file, is there a preferred method of dynamically requiring a directory of modules that is out-of-the-box compatible with Browserify?

Brad
  • 159,648
  • 54
  • 349
  • 530

3 Answers3

21

This plugin allows to require Glob patterns: require-globify

Then, with a little hack you can add all the files on compilation and not executing them:

// Hack to compile Glob files. Don´t call this function!
function ಠ_ಠ() {
  require('views/**/*.js', { glob: true })
}

And, for example, you could require and execute a specific file when you need it :D

var homePage = require('views/'+currentView)
mjlescano
  • 847
  • 9
  • 13
  • 5
    Muahhhahha, tricking static analyser into believing you're using them — classic :D – BorisOkunskiy Oct 07 '15 at 13:41
  • Why is that, require("app/" + module) only works when I put it in the same file where the require("app/*.js") is? The required JSs are in the compiled JS, I can find them but can not access ... – haxpanel Mar 10 '16 at 18:51
2

Browserify does not support dynamic requires - see GH issue 377.

The only method for dynamically requiring a directory I am aware of: a build step to list the directory files and write the "static" index.js file.

Miroslav Bajtoš
  • 10,667
  • 1
  • 41
  • 99
  • Thanks for the note. I ended up creating a static include file as you suggested. For now, I only have about 15 things in there anyway. – Brad May 20 '14 at 15:07
2

There's also the bulkify transform, as documented here:

https://github.com/chrisdavies/tech-thoughts/blob/master/browserify-include-directory.md

Basically, you can do this in your app.js or whatever:

var bulk = require('bulk-require');

// Require all of the scripts in the controllers directory
bulk(__dirname, ['controllers/**/*.js']);

And my gulpfile has something like this in it:

gulp.task('js', function () {
  return gulp.src('./src/js/init.js')
    .pipe(browserify({
      transform: ['bulkify']
    }))
    .pipe(rename('app.js'))
    .pipe(uglify())
    .pipe(gulp.dest('./dest/js'));
});
Christopher Davies
  • 4,461
  • 2
  • 34
  • 33