Expressjs 4 route separation

2020-08-04 06:58发布

问题:

I'm messing around with socketIO and currently I have a separate route file:

//api.js
var express  = require('express');
var router   = express.Router();

router.get('/test', function (req, res) {
  io.sockets.emit("change", {message: "this is a test"}); //io is NOT referenced!!!
  response.send(200);
});

module.exports = router;

where io is referenced in my server.js like so

var express = require('express');
var io = require('socket.io');
var app = express(),
server = require('http').createServer(app).listen(8080),
io = io.listen(server);

Before using socketIO I included the api routes file and prefixed all routes with /api like this:

var api = require('./server/routes/api');
app.use('/api', api);

Question: How can I pass the reference to socketIO io to the routes file?

回答1:

The api prefix isn't related.

(Very) Roughly it would look something like this:

api.js

var router  = require('express').Router();

module.exports = function(io) {
  router.get('/test', function (req, res) {
    io.sockets.emit("change", {message: "this is a test"});
    response.send(200);
  });

  return router;
};

server.js fragment

var api = require('./server/routes/api')(io);
app.use('/api', api);

You don't need to expose only that function at the module level, for example, you could expose an init function, like a normal module exposes functions:

api.js

exports.init = function (io) {
  router.get('/test', function (req, res) {
    io.sockets.emit("change", {message: "this is a test"});
    response.send(200);
  });

  return router;
};

server.js fragment

var api = require('./server/routes/api');
app.use('/api', api.init(io));

I'm away from anything I can test with, but the nutshell explanation is that you want to expose a function that accepts the io variable. Inside that function io is whatever you've passed in.



回答2:

There are a number of ways to do this. You could pass your instance directly to your routes like so:

// api.js
var express  = require('express');
var router   = express.Router();
var io;

router.get('/test', function (req, res) {
  io.sockets.emit("change", {message: "this is a test"});
  response.send(200);
});

module.exports = function(sio) {
  io = sio;
  return router;
};


// server.js
var api = require('./server/routes/api');
app.use('/api', api(io));

Or you could put your socket.io instance in a separate file that you require() in any files that need the socket.io instance.