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

Next.js13中如何用SWC替代Babel实现Cypress代码覆盖率?

在Next.js 13中实现Cypress代码覆盖率的问题及解决方法

问题背景

  • 项目已集成Cypress测试,功能正常,但代码覆盖率实现遇阻
  • Next.js 13默认使用SWC,不支持.babelrc配置文件,但Istanbul依赖Babel配置实现代码覆盖率
  • 配置.babelrc.js后,Cypress测试、构建脚本可正常运行,但执行npm run dev时触发报错:next/font需要SWC,但自定义Babel配置导致Next.js切换为Babel编译,二者冲突
  • 临时方案:构建时先移走.babelrc.js,构建后恢复,不够优雅
  • 另一种尝试:将.babelrc.js重命名为.babelrc.build.js,npm run dev恢复正常,但Cypress组件测试出现TS语法报错(无法解析类型标注)

可行解决方案

方案1:仅在Cypress构建链中注入Babel配置(推荐)

直接在Cypress的Webpack配置中整合Babel+Istanbul,无需项目根目录的.babelrc.js,完全避免影响Next.js的SWC编译:

  1. 修改cypress.config.ts,添加TypeScript预设解决TS语法问题,同时配置babel-plugin-istanbul:
import { defineConfig } from "cypress";

export default defineConfig({
  component: {
    devServer: {
      framework: "next",
      bundler: "webpack",
      webpackConfig: {
        mode: "development",
        devtool: false,
        module: {
          rules: [
            {
              test: /\.(ts|tsx)$/,
              exclude: /node_modules/,
              use: {
                loader: "babel-loader",
                options: {
                  presets: [
                    "@babel/preset-env",
                    "@babel/preset-react",
                    "@babel/preset-typescript" // 新增:处理TS/TSX类型语法
                  ],
                  plugins: ["istanbul"], // 注入覆盖率工具
                },
              },
            },
          ],
        },
      },
    },
    setupNodeEvents(on, config) {
      require("@cypress/code-coverage/task")(on, config);
      return config;
    },
  },
  e2e: {
    setupNodeEvents(on, config) {
      require("@cypress/code-coverage/task")(on, config);
      return config;
    },
  },
  video: false,
});
  1. 调整package.json脚本,移除依赖.babelrc.js的冗余命令:
{
  "scripts": {
    "cypress-open-component": "cypress open --component",
    "cypress-open-e2e": "cypress open --e2e",
    "cypress-run-component": "cypress run --component --spec src/components/core/*/*.cy.tsx --headless",
    "coverage-report": "npx nyc report --reporter=html",
    "build": "next build",
    "start": "next start",
    "lint": "next lint"
  }
}

(注:移除了instrument脚本,因为Cypress的Webpack配置已通过babel-plugin-istanbul完成代码注入)

方案2:用环境变量控制Next.js是否加载Babel配置

通过环境变量切换Next.js的Babel配置逻辑,兼顾Cypress覆盖率和Next.js默认SWC编译:

  1. 修改next.config.ts,根据环境变量决定是否启用自定义Babel配置:
/** @type {import('next').NextConfig} */
const nextConfig = {
  async rewrites() {
    if (process.env.NODE_ENV === "development") {
      return [
        {
          source: "/components",
          destination: "/page",
        },
      ];
    }
    return [];
  },
  // 仅当CYPRESS_COVERAGE变量存在时,启用Babel配置
  babel: process.env.CYPRESS_COVERAGE ? {} : undefined,
};

module.exports = nextConfig;
  1. 更新package.json脚本,在Cypress命令前注入环境变量:
{
  "scripts": {
    "cypress-open-component": "CYPRESS_COVERAGE=true cypress open --component",
    "cypress-open-e2e": "CYPRESS_COVERAGE=true npm run instrument && cypress open --e2e",
    "cypress-run-component": "CYPRESS_COVERAGE=true npm run instrument && cypress run --component --spec src/components/core/*/*.cy.tsx --headless",
    "instrument": "npx nyc instrument --compact=false src instrumented",
    "coverage-report": "npx nyc report --reporter=html",
    "build": "next build",
    "start": "next start",
    "lint": "next lint"
  }
}

(注:此方案保留.babelrc.js,但Next.js仅在运行Cypress时才会加载它)

关键问题解析

之前重命名.babelrc.js后出现TS语法报错,核心原因是Babel配置中缺少@babel/preset-typescript,无法解析TSX中的类型标注(如}: IButtonProps)这类语法),添加该预设即可解决。

内容的提问来源于stack exchange,提问作者Ala Eddine Menai

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 22:15:32