在另一个文件上导入时,module.exports未定义

Sha*_*gmi 8 commonjs node.js requirejs

这是我的简单Express应用程序的文件结构.

server/
  |- models
  |--- users.js
  |- index.js
Run Code Online (Sandbox Code Playgroud)

index.js 是切入点

const app = require('express')();
const Server = require('http').createServer(app)
const io = require('socket.io')(Server);
......
.....
.....
.....
....
module.exports = {
    Server,
    io
}
Run Code Online (Sandbox Code Playgroud)

在我的内部我models/users.js需要io上面导出的变量,只是在添加新用户时向所有连接的客户端发出一些事件.为此我导入了

const { io } = require('../index');
Run Code Online (Sandbox Code Playgroud)

ioundefined.我尝试过其他类似的方法

const io = require('../index').io // 
Run Code Online (Sandbox Code Playgroud)

const io = require('../').io /index is useless on require
Run Code Online (Sandbox Code Playgroud)

但都没有用.我是傻还是我在这里想念一些东西.任何帮助将受到高度赞赏.

谢谢

Ube*_*rio 6

这是一个问题:

以正确的顺序导入

SlaWitDev 关于线路const socketIOEvents = require('./socketIOEvents');是问题的一部分是正确的。

这是一个实例化users.js. 在实例化时users.js,要包括的文件,你是在实例化的过程。换句话说,我们还没有触及 中代码行的底部index.js,因为它将io对象导出到该文件。

index.js-> socketIOEvents/index.js-> models/index.js, ->models/users.js

检查订单

我在这些文件的顶部添加了一行代码,以便在它们被调用时进行记录,然后module.exportsindex.js文件中添加一行代码:

[nodemon] starting `node server`
index.js
socketIOEvents/index.js
models/index.js
models/users.js
Initializing routes
index.js module.exports assignment
Server is running on port 9000.
Run Code Online (Sandbox Code Playgroud)

如您所见,我们导出模块之前user.js被调用。

检查导入的对象

由于上一个问题,如果我们在users.js

const test = require('../index');
console.log('test', test);
Run Code Online (Sandbox Code Playgroud)

我们得到输出:

test {}
Run Code Online (Sandbox Code Playgroud)

这意味着我们导入的对象没有任何键,因此在您取出io键的位置执行对象解构:

const { io } = require('../index');
Run Code Online (Sandbox Code Playgroud)

不会工作。

一个办法:

如果我们将module.exports行和const io行移动index.js到 socketIOEvents 上方,您将看到它开始工作:

...
const config = require('./config');

// start socket.io
const io = require('socket.io')(Server);

module.exports = {
  Server,
  io
};

const socketIOEvents = require('./socketIOEvents');
...
Run Code Online (Sandbox Code Playgroud)

请注意,这可能是一种反模式,而不是最终解决方案,因为 module.exports 通常位于文件的末尾。

替代解决方案:

  • io在 socketIOEvents 中传递到您的模型中,与将其传递到 socketIOEvents 文件中的方式相同,将其作为参数传递到函数中。

  • 实例io在一个单独的文件中,服务器被传入它。在主index.js文件和users.js文件中使用此引用


Sla*_*Dev -1

如果您有节点 6+ (ES6)

const { io } = require('./../index');
Run Code Online (Sandbox Code Playgroud)

应该管用。在进行要求之前,首先获取当前目录。


编辑1:

我用你的代码做了一些测试。

我几乎可以肯定,它不起作用,因为在server/index.js const socketIOEvents = require('./socketIOEvents'); You require models [users.js] 的这一行 (10) 中,但 const io 在下面(第 23 行)。


在 users.js 中注释第 9 行并放置文件,例如。module 文件夹中的 test.js 内容为:

// testing different import
const { io, Server } = require('./../index');
const io2 = require('./../index').io;
const io3 = require('./../').io

console.log('io', io); // working
console.log('io2', io2); // working
console.log('io3', io3); // working
Run Code Online (Sandbox Code Playgroud)

然后节点 server/models/test.js和 require('./../index') 工作

您只需尝试在存在之前使用变量即可。