在 node.js 中交叉导入

Cross import in node.js

我正在用打字稿制作一个 node.js 项目。我想把我的 socket.io 代码放在一个单独的文件中进行整理。 我在控制台中看到 socketHandling.ts 在 index.ts 之前加载,我觉得这很奇怪。

但问题是 socketHandling.ts 中的 Typeof server 未定义。

如何确保在执行 socketHandling.ts 之前定义来自 index.ts 的服务器变量?

index.ts

import * as express from "express";
import * as path from "path";
import * as socketHandle from "./socketHandling";
console.log("index.ts loaded");

export const server = express()
  .use(express.static(path.join(__dirname, "../../public")))
  .set("views", path.join(__dirname, "../../views"))
  .set("view engine", "ejs")
  .get("/*", httpGet)
  .post("/*", httpPost)
  .listen(PORT, () => console.log(`Listening on ${PORT}`));

socketHandle.initSockets();

socketHandling.ts

import { Server } from "socket.io";
import { server } from "./index";
console.log("socketHandling.ts loaded");

console.log(server);
const io = new Server(server);

export function initSockets(): void {
  io.on("connection", (socket) => {
    console.log(`Client connected ${socket.id}`);
    socket.on("disconnect", () => {
      console.log(`Client disconnected ${socket.id}`);
    });
  });
}

为什么在定义索引服务器之前要经过socketHandling?

如果 index.ts 是您的入口点,一旦程序计数器到达 index.ts 的第 3 行,导入将使其开始执行 socketHandling.ts,其中包含另一个返回到 index.ts,它甚至还没有完成执行。所以这看起来像是一个循环导入,也许你应该完全避免这种情况。

建议的解决方案: 通过从顶部将服务器传入从库文件导入的 initSockets 方法来避免循环导入。

尝试以下重构:

index.ts

import * as express from "express";
import * as path from "path";
import * as socketHandle from "./socketHandling";
console.log("index.ts loaded");

export const server = express()
  .use(express.static(path.join(__dirname, "../../public")))
  .set("views", path.join(__dirname, "../../views"))
  .set("view engine", "ejs")
  .get("/*", httpGet)
  .post("/*", httpPost)
  .listen(PORT, () => console.log(`Listening on ${PORT}`));

socketHandle.initSockets(server);

socketHandling.ts

import { Server } from "socket.io";
console.log("socketHandling.ts loaded");

let io: Server;

export function initSockets(server): void {
  if (!io) {
      io = new Server(server);
  }
  io.on("connection", (socket) => {
    console.log(`Client connected ${socket.id}`);
    socket.on("disconnect", () => {
      console.log(`Client disconnected ${socket.id}`);
    });
  });
}

通常情况下,从您的应用程序入口点导出内容以供整个库使用是不可持续的。通常您会看到这些类型的变量被传递到方法中,而不是在整个应用程序的不同文件中被全局引用。