You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

添加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错误。

解决方案

把共享业务逻辑和服务器启动代码拆分,避免重复加载服务器文件:

  1. 提取共享函数到独立文件
    创建src/utils.js,把需要在deploy.js中调用的函数单独存放:

    // src/utils.js
    function getSimpleMessage() {
      return 'Hello world';
    }
    module.exports = { getSimpleMessage };
    
  2. 修改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');
    });
    
  3. 修改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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 12:36:14