React Monorepo(Vite+npm工作区)Cypress E2E测试覆盖率未采集/上报问题求助
React Monorepo(Vite+npm工作区)Cypress E2E测试覆盖率未采集/上报问题求助
各位开发者大佬好,我目前碰到一个卡了好久的问题,想请教下大家:我用Vite+npm工作区搭建了一个React monorepo,项目结构如下:
myapp - packages - app1 - src ... package.json - app2 - src ... package.json - app3 - src ... package.json - cypress - support e2e.js package.json cypress.config.js
先给大家看下我的核心配置:
根目录package.json
{ "name": "myapp", "type": "module", "scripts": { "preview:watch": "npm run preview --workspaces --if-present", "e2e:open": "concurrently --kill-others \"npm run preview:watch\" \"cypress open --e2e --browser chrome\"", "e2e:headless": "cypress run --e2e --headless", "e2e:coverage": "nyc report --reporter=text --reporter=text-summary --reporter=lcov" }, "nyc": { "report-dir": "cypress-coverage" }, "dependencies": { "react": "^18.2.0", "react-dom": "^18.2.0" }, "devDependencies": { "@cypress/code-coverage": "^3.12.44", "vite": "^5.0.8", "vite-plugin-istanbul": "^6.0.2" }, "workspaces": [ "packages/app1", "packages/app2", "packages/app3" ] }
cypress.config.js
import { defineConfig } from "cypress"; import coverage from "@cypress/code-coverage/task.js"; export default defineConfig({ e2e: { baseUrl: "http://localhost:3000/", setupNodeEvents(on, config) { on("task", { log(message) { console.info(message); return null; }, }); coverage(on, config); return config; }, }, });
cypress/support/e2e.js
import '@cypress/code-coverage/support' ...
vite.config.js
import { defineConfig } from "vite"; import react from "@vitejs/plugin-react"; import istanbul from "vite-plugin-istanbul"; import path from 'path'; import { resolve } from 'path'; export default ({ mode }, packagePath, chunks) => { return defineConfig({ define: { "process.env": JSON.stringify(process.env), }, plugins: [ react(), istanbul({ include: "**", forceBuildInstrument: true, cwd: "../.." }), ], esbuild: { loader: "jsx", }, build: { lib: { entry: resolve(__dirname, `${packagePath}/src/App.jsx`), name: "myapp", fileName: "index", formats: ["es"], }, rollupOptions: { output: { entryFileNames: "index.js", assetFileNames: "index.css", manualChunks: chunks, }, }, }, preview: { port: 3000, open: "http://localhost:8080/landing.html", }, resolve: { alias: { "@parent": path.resolve(__dirname, "."), "@app1": path.resolve(__dirname, "./packages/app1"), "@app2": path.resolve(__dirname, "./packages/app2"), "@app3": path.resolve(__dirname, "./packages/app3") }, }, }); };
问题描述
我现在是通过npm run preview在构建阶段用vite-plugin-istanbul做代码插桩,然后运行npm run e2e:open跑E2E测试。奇怪的是,我在测试iframe里能明确看到window.__coverage__对象,说明代码确实被插桩成功了,但cypress-coverage就是没法正确采集数据,一直报这个错误:
⚠️ file /Users/abc/projects/myapp/.nyc_output/out.json has no coverage information [1] Did you forget to instrument your web application? Read https://github.com/cypress-io/code-coverage#instrument-your-application [1] code-coverage ⚠️ file /Users/abc/projects/myapp/.nyc_output/out.json has no coverage information +18s
我注意到运行npm run preview时,工作目录是packages/app1,所以特意在Vite配置里把istanbul的cwd设为../..,想让它覆盖所有packages下的src文件,但还是没效果。附上截图证明iframe里确实存在__coverage__:

有没有大佬遇到过类似的monorepo覆盖率采集问题?求指点怎么让cypress-coverage正确识别到所有包的覆盖率数据!
备注:内容来源于stack exchange,提问作者RollADie




