添加require语句后出现EADDRINUSE端口占用错误的原因排查
问题
服务器收到请求时执行cmd命令运行deploy.js,原本运行正常,但在deploy.js中添加const { getSimpleMessage } = require('../src/server')语句后,出现端口3000已被占用的EADDRINUSE错误,请问这是为什么?
Server.js 代码
app.post("/", (req,res) =>{ console.log("Get from /"); SimpleMessage = 'Hello world'; exec('npx hardhat run scripts/deploy.js --network goerli', (error, stdout, stderr) => { console.log(stdout); console.log(stderr); if (error !== null) { console.log("v error") console.log(`exec error: ${error}`); } }); res.send("Server received the request"); }); // starting the server app.listen(3000, () => { console.log('listening on port 3000'); });
Deploy.js 代码
const { getSimpleMessage } = require('../src/server'); //THIS LINE CAUSES ERROR async function main() { const HelloWorld = await ethers.getContractFactory("HelloWorld"); // Start deployment, returning a promise that resolves to a contract object const hello_world = await HelloWorld.deploy("HelloWorld"); console.log("Contract deployed to address:", hello_world.address); } main() .then(() => process.exit(0)) .catch(error => { console.error(error); process.exit(1); });
运行命令:node src/server
原因分析
核心问题是循环引用+重复启动服务器:
- 你通过
node src/server启动主服务器时,server.js里的app.listen(3000)已经占用了3000端口。 - 当请求触发
exec命令时,会启动一个新的子进程运行deploy.js。 - 而
deploy.js里的require('../src/server')会完整加载整个server.js文件,包括其中的app.listen(3000)语句——相当于在子进程里又尝试启动一个监听3000端口的服务器,但该端口已经被主进程占用,因此触发EADDRINUSE错误。
解决方案
把共享业务逻辑和服务器启动代码拆分,避免重复加载服务器文件:
提取共享函数到独立文件
创建src/utils.js,把需要在deploy.js中调用的函数单独存放:// src/utils.js function getSimpleMessage() { return 'Hello world'; } module.exports = { getSimpleMessage };修改server.js
从utils.js导入共享函数,不再让deploy.js直接引用整个服务器文件:const { getSimpleMessage } = require('./utils'); app.post("/", (req,res) =>{ console.log("Get from /"); const simpleMessage = getSimpleMessage(); exec('npx hardhat run scripts/deploy.js --network goerli', (error, stdout, stderr) => { console.log(stdout); console.log(stderr); if (error !== null) { console.log("v error") console.log(`exec error: ${error}`); } }); res.send("Server received the request"); }); app.listen(3000, () => { console.log('listening on port 3000'); });修改deploy.js
从utils.js导入需要的函数,移除对server.js的引用:const { getSimpleMessage } = require('../src/utils'); async function main() { const message = getSimpleMessage(); const HelloWorld = await ethers.getContractFactory("HelloWorld"); const hello_world = await HelloWorld.deploy(message); console.log("Contract deployed to address:", hello_world.address); } main() .then(() => process.exit(0)) .catch(error => { console.error(error); process.exit(1); });
内容的提问来源于stack exchange,提问作者Nina
相关产品推荐
相关产品推荐

