如何让Cypress与vue.config.mjs文件兼容运行?
Cypress无法转译TypeScript的问题(Vue项目)
问题概述
在扩展大型Vue项目时编写Cypress组件测试,遇到TypeScript无法被转译为JavaScript的错误。已搭建最小测试环境复现该问题。
最小复现环境文件内容
src/components/HelloWorld.vue
<template> <div class="hello"> <h1>Test</h1> </div> </template> <script lang="ts"> import { Vue } from "vue-class-component"; export default class HelloWorld extends Vue {} </script> <style scoped> </style>
src/components/HelloWorld.cy.ts
import HelloWorld from './HelloWorld.vue' describe('<HelloWorld />', () => { it('renders', () => { cy.mount(HelloWorld) }) })
babel.config.cjs
module.exports = {presets: ['@vue/cli-plugin-babel/preset']}
cypress.config.cjs
module.exports = {component: {devServer: {framework: "vue-cli", bundler: "webpack"}}};
package.json
{ "name": "todoapp", "version": "0.1.0", "private": true, "type": "module", "scripts": { "serve": "vue-cli-service serve", "build": "vue-cli-service build", "lint": "vue-cli-service lint" }, "dependencies": { "core-js": "^3.6.5", "vue": "^3.0.0", "vue-class-component": "^8.0.0-0", "vuex": "^4.0.0-0", "node-polyfill-webpack-plugin": "^2.0.1", "webpack-bundle-tracker": "^1.3.0" }, "devDependencies": { "@cypress/vue": "^3.1.0", "@cypress/webpack-dev-server": "^2.3.0", "@types/jest": "^24.0.19", "@typescript-eslint/eslint-plugin": "^5.1.0", "@typescript-eslint/parser": "^5.1.0", "@vue/cli-plugin-babel": "~5.0.0", "@vue/cli-plugin-eslint": "~5.0.0", "@vue/cli-plugin-typescript": "~5.0.0", "@vue/cli-plugin-unit-jest": "~5.0.0", "@vue/cli-plugin-vuex": "~5.0.0", "@vue/cli-service": "~5.0.0", "@vue/compiler-sfc": "^3.0.0", "@vue/eslint-config-typescript": "^8.0.0", "@vue/test-utils": "^2.0.0-0", "cypress": "^10.7.0", "eslint-plugin-prettier": "^3.3.1", "eslint-plugin-vue": "^7.0.0", "prettier": "^2.2.1", "typescript": "~4.1.5", "vue-jest": "^5.0.0-0" } }
tsconfig.json
{ "compilerOptions": { "target": "esnext", "module": "esnext", "strict": true, "jsx": "preserve", "importHelpers": true, "moduleResolution": "node", "experimentalDecorators": true, "skipLibCheck": true, "esModuleInterop": true, "allowSyntheticDefaultImports": true, "sourceMap": true, "baseUrl": ".", "types": [ "webpack-env", "jest" ], "paths": { "@/*": [ "src/*" ] }, "lib": [ "esnext", "dom", "dom.iterable", "scripthost" ] }, "include": [ "src/**/*.ts", "src/**/*.tsx", "src/**/*.vue", "tests/**/*.ts", "tests/**/*.tsx" ], "exclude": [ "node_modules" ] }
vue.config.mjs
(空文件)
错误信息
The following error originated from your test code, not from Cypress. > Module parse failed: Unexpected token (28:8) You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders | // Alternatively, can be defined in cypress/support/component.d.ts | // with a <reference path="./component" /> at the top of your spec. > declare global { | namespace Cypress { | interface Chainable { When Cypress detects uncaught errors originating from your test code it will automatically fail the current test. Cypress could not associate this error to any specific test. We dynamically generated a new test to display this failure. at (webpack://todoapp/./cypress/support/component.ts?:1:8) at ./cypress/support/component.ts (http://localhost:8081/__cypress/src/cypress_support_component_ts.js:17:2) at __webpack_require__ (http://localhost:8081/__cypress/src/main.js:281:43) at __webpack_require__.t (http://localhost:8081/__cypress/src/main.js:314:39) From previous event: at runScripts (http://localhost:8081/__cypress/runner/cypress_runner.js:165186:63) at onSpecWindow (http://localhost:8081/__cypress/runner/cypress_runner.js:153344:76) at init (webpack://todoapp/../../../../../.cache/Cypress/10.7.0/Cypress/resources/app/node_modules/@packages/server/node_modules/@cypress/webpack-dev-server/dist/aut-runner.js?:11:14) at (webpack://todoapp/../../../../../.cache/Cypress/10.7.0/Cypress/resources/app/node_modules/@packages/server/node_modules/@cypress/webpack-dev-server/dist/browser.js?../../../../../.cache/Cypress/10.7.0/Cypress/resources/app/node_modules/@packages/server/node_modules/@cypress/webpack-dev-server/dist/loader.js:19:8) at ../../../../../.cache/Cypress/10.7.0/Cypress/resources/app/node_modules/ (packages/server/node_modules/@cypress/webpack-dev-server/dist/loader.js!../../../../../.cache/Cypress/10.7.0/Cypress/resources/app/node_modules/@packages/server/node_modules/@cypress/webpack-dev-server/dist/browser.js@http://localhost:8081/__cypress/src/main.js:40:2) at __webpack_require__ (http://localhost:8081/__cypress/src/main.js:281:43) at render (webpack://todoapp/../../../../../.cache/Cypress/10.7.0/Cypress/resources/app/node_modules/@packages/server/node_modules/@cypress/webpack-dev-server/dist/browser.js?:3:25) at (webpack://todoapp/../../../../../.cache/Cypress/10.7.0/Cypress/resources/app/node_modules/@packages/server/node_modules/@cypress/webpack-dev-server/dist/browser.js?:5:2) at ../../../../../.cache/Cypress/10.7.0/Cypress/resources/app/node_modules/ (packages/server/node_modules/@cypress/webpack-dev-server/dist/browser.js@http://localhost:8081/__cypress/src/main.js:30:2) at __webpack_require__ (http://localhost:8081/__cypress/src/main.js:281:43) at (http://localhost:8081/__cypress/src/main.js:535:57) at (http://localhost:8081/__cypress/src/main.js:537:13)
当前情况及诉求
将vue.config.mjs重命名为vue.config.cjs可临时解决问题,但项目要求保留ES模块格式的配置文件,需寻找其他可行方案。
解决线索
1. 手动指定Vue配置文件路径
修改cypress.config.cjs,在devServer选项中明确指定vueConfigPath指向你的vue.config.mjs,确保Cypress能正确识别ES模块格式的配置:
module.exports = { component: { devServer: { framework: "vue-cli", bundler: "webpack", vueConfigPath: "./vue.config.mjs" } } };
2. 完善TypeScript配置
在tsconfig.json的types数组中添加cypress,确保TypeScript能识别Cypress的全局类型定义,避免类型解析问题:
"types": [ "webpack-env", "jest", "cypress" ]
3. 升级Cypress相关依赖
当前使用的@cypress/webpack-dev-server@2.3.0可能与Vue CLI 5的ES模块配置存在兼容性问题,尝试升级到最新兼容版本(如^3.x),同时同步升级@cypress/vue依赖,确保版本匹配。
4. 自定义Cypress Webpack配置
如果自动读取Vue配置存在问题,可在cypress.config.cjs中手动配置Webpack的TypeScript解析规则,强制添加TypeScript loader:
const { defineConfig } = require('cypress') const tsConfig = require('./tsconfig.json') module.exports = defineConfig({ component: { devServer: { framework: 'vue-cli', bundler: 'webpack', webpackConfig: { module: { rules: [ { test: /\.ts$/, exclude: [/node_modules/], use: [ { loader: 'ts-loader', options: { configFile: './tsconfig.json', transpileOnly: true } } ] } ] }, resolve: { extensions: ['.ts', '.js', '.vue'], alias: tsConfig.compilerOptions.paths } } } } })
5. 动态加载ES模块配置
由于项目根目录设置了"type": "module",CommonJS格式的cypress.config.cjs读取ES模块的vue.config.mjs时可能存在加载问题,可尝试在cypress.config.cjs中用动态导入加载Vue配置:
module.exports = async () => { const vueConfig = await import('./vue.config.mjs') return { component: { devServer: { framework: "vue-cli", bundler: "webpack", vueConfig: vueConfig.default } } } }
内容的提问来源于stack exchange,提问作者msebas
相关产品推荐
相关产品推荐

