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编译:
- 修改
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, });
- 调整
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编译:
- 修改
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;
- 更新
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
相关产品推荐
相关产品推荐

