在 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}`);
});
});
}
通常情况下,从您的应用程序入口点导出内容以供整个库使用是不可持续的。通常您会看到这些类型的变量被传递到方法中,而不是在整个应用程序的不同文件中被全局引用。
我正在用打字稿制作一个 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}`);
});
});
}
通常情况下,从您的应用程序入口点导出内容以供整个库使用是不可持续的。通常您会看到这些类型的变量被传递到方法中,而不是在整个应用程序的不同文件中被全局引用。