There are many different schemes for sharing a central variable (like your io
variable) with other modules. How exactly makes sense to do it depends upon an overall architecture, how you want your modules to be resuable, etc... but all use some combination of importing and exporting to share data between modules without using global
.
In your specific case, you can do something very simple:
server.js
const options = {
key: fs.readFileSync('./certs/file.key'),
cert: fs.readFileSync('./certs/file.crt'),
requestCert: false
};
const app = express();
const server = require('https').createServer(options, app);
const io = require('./socket.js').init(server);
io.on('connection', function(socket) { .. }
socket.js
let io;
module.exports = {
init: function(server) {
// start socket.io server and cache io value
io = require('socket.io').listen(server); io.origins('*:*');
return io;
}
getio: function() {
// return previously cached value
if (!io) {
throw new Error("must call .init(server) before you can call .getio()");
}
return io;
}
}
In other modules that want access to io
const io = require('./socket.js').getio();
It should go without saying here that you have to call .init(server)
before you can call .getio()
. This takes advantage of the node.js module caching system so that each time you call require('./socket.js')
it is returning to you the same module that was first loaded and thus you have access to the previously cached io
instance.
FYI, this is called a "pull" model where a module that wants access to something else uses a require()
statement to "pull" in the variable it wants.
There is also a push module where the loader of the module pushes the data to the module by calling a function in that module after it loads the module.
Here are some other ways to do it:
Export from app.js
You have to watch out for circular dependencies with this scheme because if app.js does require('./a.js')
and then a.js
does require('./app.js'), you can create a circular dependency which will fail. So, this model only works if
a.jsis doing a
require('./app.js')` after module load (like in a module constructor).
app.js
const options = {
key: fs.readFileSync('./certs/file.key'),
cert: fs.readFileSync('./certs/file.crt'),
requestCert: false
};
const app = express();
const server = require('https').createServer(options, app);
const io = require('socket.io').listen(server); io.origins('*:*');
io.on('connection', function(socket) { .. }
// exports some things we want to share
module.exports = {
io: io,
app: app
};
some other files that wants access to io
// module constructor
modules.exports = function() {
// can use io in here
const io = require('./app.js').io;
}
Push Model
In this module, you pass the io
variable to any other module that needs it when you load that other module.
app.js
const options = {
key: fs.readFileSync('./certs/file.key'),
cert: fs.readFileSync('./certs/file.crt'),
requestCert: false
};
const app = express();
const server = require('https').createServer(options, app);
const io = require('socket.io').listen(server); io.origins('*:*');
io.on('connection', function(socket) { .. }
// load someotherfile.js and pass it the io variable
require('./someotherfile.js')(io);
some other files that wants access to io
module.exports = function(io) {
// put whatever code for your module here
setInterval(function() {
io.emit(...);
}, 1000);
}