20

I'm new to Browserify (and Javascript build systems in general) and have reached a point where I am thoroughly confused.

I have Gulp setup to do my builds, which has always worked fine, and lately I've been using Browserify to bundle -- mostly so I can separate my code into separate files and require() them where they need to be.

My issue is, I have a folder with a bunch of small modules I need to require within another module, and I am trying to avoid hard coding the names of all of them. Is there a way to do a require of all of the files?

I've tried using Bulkify and Folderify but cannot get them to work. For example, with Bulkify, the package installed is called bulkify and is in the node_modules folder, but then they tell you to require bulk-require, which is in a sub node_modules folder of the bulkify package. When I try that, Browserify chokes with a Cannot find module 'bulk-require'... type error.

At this point I am confused because I have no idea why the installation directions of both of those do not work (nor whether they will even help me). Am I supposed to be using them in my Gulp file? Or can I use them in one of my modules and it will get called during the Browserify?

Here is a snippet of my build task for this if this helps:

// Report Builder
gulp.task('script-builder', function() {

    // Unminified
    // **********************************************************
    browserify({entries: './resources/assets/js/report/builder.js'})
        .on('error', function (err) { console.log(err); this.emit('end'); })
        .bundle()
        .on('error', function (err) { console.log(err); this.emit('end'); })
        .pipe(source('builder.js'))
        .on('error', function (err) { console.log(err); this.emit('end'); })
        .pipe(buffer())
        .on('error', function (err) { console.log(err); this.emit('end'); })
        .pipe(gulp.dest('./public/js/debug'));

    // Minified
    // **********************************************************
    browserify({entries: './resources/assets/js/report/builder.js'})
        .on('error', function (err) { console.log(err); this.emit('end'); })
        .bundle()
        .on('error', function (err) { console.log(err); this.emit('end'); })
        .pipe(source('builder.js'))
        .on('error', function (err) { console.log(err); this.emit('end'); })
        .pipe(buffer())
        .on('error', function (err) { console.log(err); this.emit('end'); })
        .pipe(ext_replace('.min.js'))
        .on('error', function (err) { console.log(err); this.emit('end'); })
        .pipe(uglify())
        .on('error', function (err) { console.log(err); this.emit('end'); })
        .pipe(gulp.dest('./public/js/dist'));

});

I have no idea what I am doing here. Am I just going to have to hardcode the paths in my require() calls or is there a better way?


EDIT

I can clearly see bulk-require in the bulkify node module:

enter image description here

But, when I try to require bulk-require, it chokes:

module.exports = function(type, driver, node) {

    var propertiesContainer = '#property-container';

    var bulk = require('bulk-require');
    var mods = bulk(__dirname, ['properties/**/*.js']);

}

Error: Cannot find module 'bulk-require' from '/path/to/my/project/resources/assets/js/report'


EDIT 2

I was able to make this work using the require-globify package (https://github.com/capaj/require-globify). In my javascript, I used:

var properties = require('./properties/*.js', {mode: 'hash', resolve: ['path-reduce', 'strip-ext']});

That returned an object with keys as the filename without extension or the path prefix.

In my gulpfile.js, I did this:

browserify({
    entries: './resources/assets/js/report/builder.js',
    transform: ['require-globify']
})
.on('error', function (err) { console.log(err); this.emit('end'); })
.bundle()
.on('error', function (err) { console.log(err); this.emit('end'); })
.pipe(source('builder.js'))
.on('error', function (err) { console.log(err); this.emit('end'); })
.pipe(buffer())
.on('error', function (err) { console.log(err); this.emit('end'); })
.pipe(gulp.dest('./public/js/debug'));
Jeremy Harris
  • 24,318
  • 13
  • 79
  • 133

2 Answers2

5

That's a pretty easy task to achieve. Using fs you may dynamically require all the dependencies at once simply accessing your node_modules folder.

var normalizedPath = require("path").join(__dirname, "node_modules/bulkify");
require("fs").readdirSync(normalizedPath).forEach(function(file) {
  require("./node_modules/bulkify" + file);
});

More answers on this question can be found here

EDIT Apologies for the generic answer I kinda misunderstood the question about dynamically requiring files into Browserify.

Require-globify seems a neat approach for your problem.

Take a moment to have a look at this answer as well Compiling dynamically required modules with Browserify

Community
  • 1
  • 1
vorillaz
  • 6,098
  • 2
  • 30
  • 46
  • Thank you! Let me give this a try real quick. – Jeremy Harris Jun 30 '15 at 21:23
  • You are welcome. The code is just a sample, it may need a few tweaks to work properly. – vorillaz Jun 30 '15 at 21:24
  • I don't understand how this answer relates to the question, unless I completely misunderstood the question. – JMM Jun 30 '15 at 21:25
  • Now that I am trying to implement it, I'm not sure either. I'm trying to run this inside of a module, but this is node.js specific and won't run in the browserified code that is generated for client side. – Jeremy Harris Jun 30 '15 at 21:27
  • @Theodore Thanks for pointing me at `require-globify`. That did it! – Jeremy Harris Jun 30 '15 at 22:22
  • @Theodore is there a command line command to bundle all *.js under a specific directory into a file ? – eran otzap Sep 29 '15 at 08:41
  • @eranotzap Take a look at this answer using gulp concat http://stackoverflow.com/questions/24591854/using-gulp-to-concatenate-and-uglify-files – vorillaz Sep 29 '15 at 19:15
3

I haven't used it, but I think bulkify will do what you want.

Am I supposed to be using them in my Gulp file? Or can I use them in one of my modules and it will get called during the Browserify?

Yes and yes.

I think the gist of it is something like this:

gulpfile.js

var bulkify = require('bulkify');

browserify(...)
  .transform(bulkify)
  // ...

another-module.js (bundled module)

var bulk = require('bulk-require');
var a_bunch_of_small_modules = bulk(__dirname, ['somdir/**/*.js']);
a_bunch_of_small_modules.somedir.whatever();
JMM
  • 26,019
  • 3
  • 50
  • 55
  • I think your solution is on point with what I am supposed to do here, but I can't seem to get past it not recognizing `bulk-require` (see edit). I'm on OSX and it recognizes anything in the root level of the *node_modules* folder, but any dependencies that a module includes it doesn't recognize. Do you know of anything that might cause that? – Jeremy Harris Jun 30 '15 at 21:34
  • @cillosis I think bulkify is supposed to take care of that. Where is the module that contains the `require('bulk-require')` -- is it under `node_modules`? That would interfere with the bulkify transform running (in that case you might want to add it to the `package.json` that applies to that module). Also, it's not in a `.json` file, right? – JMM Jun 30 '15 at 21:46
  • No, its in a javascript file in "resources" folder, which get built and put in my public folder . It's not a node.js thing -- I just use some node packages as part of my build system. – Jeremy Harris Jun 30 '15 at 21:53
  • I suspect that the transform isn't running for some reason. Can you try stripping it down to a minimal example (without any gulp stuff would be best) and post that code? FYI, people often put stuff like you're describing in `node_modules` (or symlink it there) to avoid having to use file-relative paths in `require()`. – JMM Jun 30 '15 at 22:04
  • I'm having some luck with `require-globify` transform that @Theodore suggested. It is compiling them all now. Just trying to figure out how to get the name of each module to be able to create an instance when necessary. Still playing with it. Thanks for all your help here though! – Jeremy Harris Jun 30 '15 at 22:05