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

在Cypress测试文件中启动本地服务器遇Webpack编译错误求助

问题分析与解决方案

核心问题

你遇到的Webpack编译错误,本质是错误地在浏览器环境的测试代码中引入了Node.js专属的服务器依赖:

  • Cypress测试代码运行在浏览器环境,Webpack会尝试打包所有引入的模块,但mysql2等Node模块使用了Webpack默认配置不支持的ES私有类字段语法(static #constructing),导致编译失败。
  • 你的服务器文件导出逻辑错误:module.exports = test();直接执行了启动函数,导出的是app.listen返回的Server实例,而非可调用的函数,测试文件里的xxxx.tes()本身就是无效调用。

解决方案步骤

1. 重构服务器文件,支持启动/关闭控制

修改index.js,导出可控制的启动、停止函数和app实例,方便后续在Node环境中管理:

const express = require("express");
const app = express();
const port = 3000;
const programmingLanguagesRouter = require("./routes/programmingLanguages");

app.use(express.json());
app.use(express.urlencoded({ extended: true }));

app.get("/", (req, res) => {
  res.json({ message: "ok" });
});

app.use("/programming-languages", programmingLanguagesRouter);

/* Error handler middleware */
app.use((err, req, res, next) => {
  const statusCode = err.statusCode || 500;
  console.error(err.message, err.stack);
  res.status(statusCode).json({ message: err.message });
  return;
});

let server;

// 启动服务器,返回Promise便于异步控制
function startServer() {
  return new Promise((resolve) => {
    server = app.listen(port, () => {
      console.log(`Example app listening at http://localhost:${port}`);
      resolve(server);
    });
  });
}

// 关闭服务器,返回Promise
function stopServer() {
  return new Promise((resolve, reject) => {
    if (server) {
      server.close((err) => err ? reject(err) : resolve());
    } else {
      resolve();
    }
  });
}

module.exports = { startServer, stopServer, app };

2. 在Node环境启动/关闭服务器(避免Webpack编译)

Cypress允许通过配置文件或cy.task在Node环境执行代码,不会经过浏览器端的Webpack编译,这才是启动测试服务器的正确方式。

方案一:全局钩子控制(所有测试共用服务器)

修改cypress.config.js(旧版Cypress用cypress/plugins/index.js),在测试全局生命周期中启动/关闭服务器:

const { defineConfig } = require("cypress");
// 替换为你的服务器文件实际路径
const { startServer, stopServer } = require("../server/index.js");

module.exports = defineConfig({
  e2e: {
    setupNodeEvents(on, config) {
      let server;

      // 所有测试启动前启动服务器
      on("before:run", async () => {
        server = await startServer();
      });

      // 所有测试结束后关闭服务器
      on("after:run", async () => {
        await stopServer();
      });
    },
  },
});

方案二:单个测试文件控制(灵活启停)

如果需要在单个测试文件中控制服务器,先在cypress.config.js注册任务:

const { defineConfig } = require("cypress");
const { startServer, stopServer } = require("../server/index.js");

module.exports = defineConfig({
  e2e: {
    setupNodeEvents(on, config) {
      let server;

      on("task", {
        startServer: async () => {
          if (!server) server = await startServer();
          return "Server started";
        },
        stopServer: async () => {
          await stopServer();
          return "Server stopped";
        },
      });
    },
  },
});

然后修改测试文件test.spec.js:

describe("Calling the endpoint", () => {
  // 测试前启动服务器
  before(() => {
    cy.task("startServer");
  });

  // 测试后关闭服务器
  after(() => {
    cy.task("stopServer");
  });

  context("Test", () => {
    it("should return 200 for programming-languages endpoint", () => {
      cy.request({
        method: 'GET',
        headers: {
          'Content-Type': 'application/json',
          'accept': 'application/json'
        },
        url: 'http://localhost:3000/programming-languages'
      }).then((res) => {
        expect(res.status).to.equal(200);
      });
    });
  });
});

内容的提问来源于stack exchange,提问作者EFPM_S

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 19:44:51