web-dev-qa-db-ja.com

module.exportsは、別のファイルにインポートしている間は未定義です

これは、シンプルなExpressアプリのファイル構造です。

server/
  |- models
  |--- users.js
  |- index.js

index.jsはエントリポイントです

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

私の内部models/users.js上記でエクスポートしたio変数は、新しいユーザーが追加された場合に接続されているすべてのクライアントにイベントを発行するためだけに必要です。これのためにインポートしました

const { io } = require('../index');

しかし、ioundefinedです。他のいくつかの同様の方法を試しました

const io = require('../index').io // 

そして

const io = require('../').io /index is useless on require

しかし、どれもうまくいきませんでした。ばかげているのか、ここで何かを逃したのか。どんな助けも高く評価されます。

ありがとう

8
Shankar Regmi

これは次の問題です:

正しい順序でインポートする

SlaWitDevはconst socketIOEvents = require('./socketIOEvents');という行が問題の一部であることを正しく理解していました。

これは、users.jsをインスタンス化するファイルです。 users.jsのインスタンス化時に、インスタンス化中のファイルを含めています。言い換えると、ioオブジェクトをそのファイルにエクスポートするために、index.jsのコード行の最後に到達していません。

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

注文の確認

これらのファイルの先頭にコード行を追加して、それらが呼び出されたときにログに記録し、次にmodule.exportsファイルのindex.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.

ご覧のとおり、user.jsが呼び出されますbeforeモジュールをエクスポートします。

インポートしたオブジェクトを確認する

前の問題の結果、この行をusers.jsに追加すると、次のようになります。

const test = require('../index');
console.log('test', test);

出力を取得します。

test {}

これは、インポートしたオブジェクトにキーがないため、ioキーを次の場所に引き出すオブジェクトの分解を実行することを意味します。

const { io } = require('../index');

動作しません。

解決策:

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');
...

Module.exportsは通常ファイルの最後にあるため、これはおそらくアンチパターンであり、最終的なソリューションではないことに注意してください。

代替ソリューション:

  • ioを関数に引数として渡すことにより、socketIOEventsファイルに渡すのと同じ方法で、socketIOEventsのモデルに渡します。

  • 別のファイル内のインスタンスioに、サーバーが渡されます。このリファレンスは、メインのindex.jsファイルとusers.jsファイルの両方で使用します

4
UberMario