Reputation: 3196
I'm trying, with Browserify
, to enable node.js
like modules in a socket.io
web client. I'm having problems requiring modules within required modules.
main.js
requires client.js
, which requires admin.js
client.js
require path is relative to main.js
location in the filesystem.
admin.js
require path is relative to client.js
location in the filesystem.
browserify main.js -o client.packaged.js
produces a file with client.js
embedded. admin.js
is required when an event is fired in client.js
. When this event fires, I get the following error:
Uncaught Error: Cannot find module '../../../modules/admin/admin.js'
I've tried changing the path to be relative to the browserified bundle and relative to client.js
, both result in the error above, just different paths.
I've got Chrome open with --alow-file-access-from-files
, so I know that shouldn't be part of the problem.
In the source map produced by browserify
, admin.js
is not anywhere, so it must not be finding it for some reason.
How do you correctly use relative paths within modules to require other modules when using browserify
?
Thanks in advance for any help!
Edit - Added source below to help clarify
main.js
//Include the client
var client = require('../../base/client/client.js').client;
//Start when document is ready
$(function() {
console.log(client);
client.start();
});
client.js
var client = new Object();
client.start = function() {
//Server specific information
var IP = 'localhost';
var PORT = '1337';
//Flags
//SSL - true for secured connections
//DEBUG - true to enable console.log() messages
var SSL = false;
var DEBUG = true;
//Locations of modules to include
var MODULE_LOCATIONS = [
'../../modules/admin/admin.js'
];
//Builds an array of modules to start
var MODULES = [];
for (var i = 0; i < MODULE_LOCATIONS.length; i++) {
MODULES.push(require(MODULE_LOCATIONS[i]));
}
var socket = io.connect(getConnectionString());
socket.on('connection', function(socket) {
client.onConnection(socket);
//Load modules
for (var i = 0; i < MODULES.length; i++) {
MODULES[i].start(socket, io);
}
});
//Returns a connection string to the socket.io server
function getConnectionString() {
if (SSL) {
return 'https://' + IP + ':' + PORT;
} else {
return 'http://' + IP + ':' + PORT;
}
}
};
module.exports.client = client;
admin.js
//Events
var SYSTEM_STATS = 'system_stats';
var start = function(socket, io) {
socket.on(SYSTEM_STATS, function(data) {
admin.onSystemStats(socket, data);
});
}
module.exports.start = start;
Upvotes: 2
Views: 519
Reputation: 146034
//Locations of modules to include
var MODULE_LOCATIONS = [
'../../modules/admin/admin.js'
];
//Builds an array of modules to start
var MODULES = [];
for (var i = 0; i < MODULE_LOCATIONS.length; i++) {
MODULES.push(require(MODULE_LOCATIONS[i]));
}
So yeah, browserify does static analysis. This means it reads and "understands" your code at a statement level, but it doesn't actually execute it. This type of construct defeats the static analysis's capabilities and thus browserify does not detect that the client.js
module depends on admin.js
. Remove this extra metaprogramming logic and put in a plain vanilla require('../../modules/admin/admin.js')
and I think you'll be good to go.
Upvotes: 1