如何在Node.js中从app.js导出一个变量到另一个路由

5

我在我的node项目中使用socket.io,并想知道如何导出io变量。

到目前为止,我所做的是这样的,但是我得到了错误:Object #<Object> has no method 'on'

在app.js中:

        var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');

var routes = require('./routes/index')(io);
var users = require('./routes/user');

var app = require('express')();
var server = require('http').Server(app);
var io = require('socket.io')(server);
server.listen(4000);

require('./routes/index')(io);

// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');

// app.use(favicon(__dirname + '/public/img/favicon.ico'));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({
  extended: true
}));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));

app.use('/', routes);
app.use('/users', users);

/// catch 404 and forward to error handler
app.use(function(req, res, next) {
    var err = new Error('Not Found');
    err.status = 404;
    next(err);
});

/// error handlers

// development error handler
// will print stacktrace
if (app.get('env') === 'development') {
    app.use(function(err, req, res, next) {
        res.status(err.status || 500);
        res.render('error', {
            message: err.message,
            error: err,
            title: 'error'
        });
    });
}

// production error handler
// no stacktraces leaked to user
app.use(function(err, req, res, next) {
    res.status(err.status || 500);
    res.render('error', {
        message: err.message,
        error: {},
        title: 'error'
    });
});
/*
io.on('connection', function (socket) {
  socket.emit('news', { hello: 'world' });
  socket.on('my other event', function (data) {
    console.log(data);
  });
});
*/

module.exports = app;

in index.js

var io = require('../app');

io.on('connection', function (socket) {
  socket.emit('news', { hello: 'world' });
  socket.on('my other event', function (data) {
    console.log(data);
  });
});

我想导出变量的原因是我不想像在app.js中那样定义io,这会导致我基本上定义了服务器和应用程序两个变量!
我只想在index.js路由中处理所有我的socket.io事务(除了在index.js中重新定义app、server和io变量之外)!
希望我已经足够清楚地解释了。
谢谢!

我是否错了,还是你有循环依赖?[http://selfcontained.us/2012/05/08/node-js-circular-dependencies/] - mattr
我正在使用Express框架,所以我认为我可以这样做。 - ipalibowhyte
我是指app.js需要index.js,而index.js需要app.js。此外,看起来在你有机会初始化app之前就需要了index。我认为这是一个先有鸡还是先有蛋的问题。 - mattr
我对Node.js还是比较新的。这是Yomean生成文件的方式,而且在app.js中还没有做任何事情。请问我该如何解决这个问题? - ipalibowhyte
好的,我会添加一个重构代码的答案,可能会暂时解决问题,敬请关注! ;) - mattr
只是为了澄清 var routes = require ('./routes / index');...这是相同的 index.js 文件,正确吗? - mattr
4个回答

14

您的依赖项设置不正确。在io初始化之前,您正在执行index.js

var routes = require('./routes/index');
/* index.js starts being executed at this point
 * hence, io is undefined inside index.js
 */

反而,为什么不试试

app.js

var app = require('express')();
var server = require('http').Server(app);
var io = require('socket.io')(server);
server.listen(4000);
module.exports = io;

var routes = require('./routes/index');
var users = require('./routes/user');

index.js

->

index.js

 var io = require('../app');

io.on('connection', function (socket) {
    socket.emit('news', { hello: 'world' });
    socket.on('my other event', function (data) {
    console.log(data);
    });
});

1

我认为你需要使用套接字。

io.sockets.on('connection', ... ); 

在index.js中添加了代码,结果出现了“无法调用未定义的'on'方法”的错误。 - ipalibowhyte

0

看起来像是循环依赖(app.js需要index.js,而index.js又需要app.js)

试试这个。

将app.js改为:

var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');

var users = require('./routes/user');

var app = require('express')();
var server = require('http').Server(app);
var io = require('socket.io')(server);
server.listen(4000);

require('./routes/index')(io);

// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');

// app.use(favicon(__dirname + '/public/img/favicon.ico'));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({
  extended: true
}));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));

app.use('/users', users);

/// catch 404 and forward to error handler
app.use(function(req, res, next) {
  var err = new Error('Not Found');
  err.status = 404;
  next(err);
});

/// error handlers

// development error handler
// will print stacktrace
if (app.get('env') === 'development') {
  app.use(function(err, req, res, next) {
    res.status(err.status || 500);
    res.render('error', {
      message: err.message,
      error: err,
      title: 'error'
    });
  });
}

// production error handler
// no stacktraces leaked to user
app.use(function(err, req, res, next) {
  res.status(err.status || 500);
  res.render('error', {
    message: err.message,
    error: {},
    title: 'error'
  });
});
/*
 io.on('connection', function (socket) {
 socket.emit('news', { hello: 'world' });
 socket.on('my other event', function (data) {
 console.log(data);
 });
 });
 */

module.exports = app;

将 index.js 更改为:

module.exports = function(io){
  io.on('connection', function (socket) {
    socket.emit('news', { hello: 'world' });
    socket.on('my other event', function (data) {
      console.log(data);
    });
  });
}  

给我这个错误 /Desktop/blah Site/node_modules/express/lib/router/index.js:114 debug('dispatching %s %s', req.method, req.url); :( - ipalibowhyte
我已经在app.js中更新了我的问题的完整代码。 - ipalibowhyte
你没有按照我指定的方式精确地更改代码。我看到 require('./routes/index')(io) 重复了一次,而且在 io 定义之前出现了一次。请删除第一个版本。 - mattr
同时删除app.use('/', routes);这一行。 - mattr
显然,这个错误来自于 require('./routes/index')(io); 的 io 部分。 - ipalibowhyte
显示剩余3条评论

0
在 app.js 中使用 "global.io" 而不是 "var io"。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接