NextJS+GitLab集成Cypress CI/CD启动服务器时触发堆内存错误
一、修复JavaScript堆内存溢出错误
你遇到的FATAL ERROR: Reached heap limit Allocation failed - JavaScript heap out of memory错误,主要是开发服务器(next dev)与Cypress同时运行占用内存过高,或Node.js默认内存限制不足导致,可通过以下方案解决:
1. 增加Node.js内存限制
直接修改开发服务器启动命令,为Node进程分配更大内存:
修改package.json中的setup:cypress:environment命令:
"setup:cypress:environment": "dotenv -e .env.test -- node --max-old-space-size=4096 node_modules/.bin/next dev & wait-on http://localhost:3000"
--max-old-space-size=4096表示分配4GB内存,可根据GitLab Runner的实际资源调整(比如Runner只有2GB就设为2048)。
2. 改用生产模式服务器替代开发模式
next dev是开发热重载模式,内存占用远高于生产模式。建议先构建生产版本,再启动生产服务器:
- 在
package.json添加测试专用的构建和启动命令:"build:test": "dotenv -e .env.test -- next build", "start:test": "dotenv -e .env.test -- next start", "setup:cypress:environment": "npm run build:test && npm run start:test & wait-on http://localhost:3000" - 在
gitlab-ci.yml中配置构建产物复用,避免重复安装依赖和构建:build: stage: build image: cypress/browsers:node16.14.2-slim-chrome100-ff99-edge script: - npm install --frozen-lockfile - npm run build:test artifacts: paths: - .next/ - public/ - node_modules/ expire_in: 1 hour test: image: cypress/browsers:node16.14.2-slim-chrome100-ff99-edge stage: test dependencies: - build script: - npm run test:cypress
3. 提升GitLab Runner资源配额
如果Runner默认内存配额过低(比如1GB),可在gitlab-ci.yml的test阶段指定更大内存:
test: image: cypress/browsers:node16.14.2-slim-chrome100-ff99-edge stage: test resources: requests: memory: "4GB" limits: memory: "4GB" script: - npm run test:cypress
注:需确保GitLab Runner支持资源限制配置。
二、Next.js测试服务器与数据库模拟配置
1. 用独立测试环境隔离数据
保持.env.test的独立性,里面的数据库连接指向专用测试数据库(比如单独的MongoDB/PostgreSQL实例),禁止复用开发/生产数据库。
2. 数据库模拟方案(以Prisma为例)
方案1:使用内存数据库
对于SQLite,在.env.test中配置内存数据库,每次测试自动创建新实例,测试后销毁:
DATABASE_URL="file:./test.db?mode=memory&cache=shared"
方案2:重置测试数据库
在测试前自动重置数据库并初始化测试数据:
在package.json添加数据库初始化命令:
"setup:test-db": "dotenv -e .env.test -- prisma migrate reset --force", "test:cypress": "npm run setup:test-db && npm run setup:cypress:environment && npx cypress run"
3. 无需启动服务器的测试方式(可选)
使用Cypress官方Next.js插件@cypress/nextjs,直接在测试中渲染页面,减少资源占用:
- 安装插件:
npm install @cypress/nextjs --save-dev - 在
cypress.config.js中配置:const { defineConfig } = require('cypress') const { initPlugin } = require('@cypress/nextjs') module.exports = defineConfig({ e2e: { setupNodeEvents(on, config) { initPlugin(on, config) return config }, }, }) - 测试中直接访问页面:
cy.visit('/') // 无需启动服务器,直接渲染Next.js页面
注:此方式适合无需测试API路由的场景,若需测试API路由,仍需启动服务器或模拟请求。
4. 模拟API路由请求
如果需要测试API路由,用Cypress的cy.intercept模拟响应,绕过真实数据库查询:
cy.intercept('GET', '/api/users', { statusCode: 200, body: [{ id: 1, name: 'Test User' }] }).as('getUsers') cy.visit('/users') cy.wait('@getUsers')
内容的提问来源于stack exchange,提问作者stellenberger

