在Cypress中运行E2E测试时,如何处理客户端JS文件中的process.env?
问题:Cypress运行时抛出
process is not defined错误 被这个问题卡了好几天,工作任务急需推进。运行Cypress时,前端代码里的process.env.VUE_APP_ENV触发了process is not defined错误,错误指向sentryMixin.js里的对应位置。正常运行前端应用时能正常访问process.env,完全搞不懂为什么Cypress会报错,当前使用Node.js v14.x.x版本。

相关配置文件
vue.config.js
const { defineConfig } = require('@vue/cli-service') // const { VueLoaderPlugin } = require('vue-loader') module.exports = defineConfig({ css: { loaderOptions: { sass: { additionalData: '@import src/styles/base/entry.scss', }, }, }, lintOnSave: false, publicPath: '/', transpileDependencies: true, })
package.json
{ "name": "test2", "version": "0.1.0", "private": true, "scripts": { "serve": "vue-cli-service serve", "build": "vue-cli-service build", "test:unit": "vue-cli-service test:unit", "test:e2e": "vue-cli-service test:e2e", "lint": "vue-cli-service lint" }, "dependencies": { "@sentry/apm": "^5.27.1", "@sentry/browser": "^7.28.1", "@sentry/integrations": "^7.28.1", "auth0-js": "^9.20.0", "axios": "^1.2.2", "axios-retry": "^3.3.1", "big.js": "^6.2.1", "core-js": "^3.8.3", "css-loader": "^6.7.3", "moment": "^2.29.4", "moment-timezone": "^0.5.40", "style-loader": "^3.3.1", "toastr": "^2.1.4", "uuid": "^9.0.0", "vue": "^2.6.14", "vue-router": "^3.5.2" }, "devDependencies": { "@babel/core": "^7.20.7", "@babel/eslint-parser": "^7.19.1", "@babel/preset-env": "^7.20.2", "@cypress/webpack-preprocessor": "^5.16.1", "@vue/cli-plugin-babel": "~5.0.0", "@vue/cli-plugin-e2e-cypress": "~5.0.0", "@vue/cli-plugin-eslint": "~5.0.0", "@vue/cli-plugin-unit-jest": "~5.0.0", "@vue/cli-service": "~5.0.0", "@vue/test-utils": "^1.1.3", "@vue/vue2-jest": "^27.0.0-alpha.2", "babel-jest": "^27.0.6", "babel-loader": "^8.0.2", "cypress": "^9.7.0", "eslint": "^7.32.0", "eslint-plugin-vue": "^8.0.3", "jest": "^27.0.5", "node-sass": "^4.14.0", "sass-loader": "^12.6.0", "ts-jest": "^27.0.4", "vue-loader": "^15.0.1", "vue-template-compiler": "^2.6.14", "webpack": "^5.75.0" } }
Cypress webpack配置(plugins/index.js)
/// <reference types="cypress" /> // *********************************************************** // This example plugins/index.js can be used to load plugins // // You can change the location of this file or turn off loading // the plugins file with the 'pluginsFile' configuration option. // // You can read more here: // https://on.cypress.io/plugins-guide // *********************************************************** // This function is called when a project is opened or re-opened (e.g. due to // the project's config changing) const { VueLoaderPlugin } = require('vue-loader') const webpackPreprocessor = require('@cypress/webpack-preprocessor') /** * @type {Cypress.PluginConfig} */ // eslint-disable-next-line no-unused-vars module.exports = (on, config) => { // `on` is used to hook into various events Cypress emits // `config` is the resolved Cypress config const defaults = webpackPreprocessor.defaultOptions // Add to existing rules defaults.webpackOptions.module.rules.push( { test: /\.vue$/, loader: 'vue-loader', }, { test: /\.sass$/i, use: [ // creates 'style' nodes from JS strings "vue-style-loader", // Translates CSS into CommonJS "css-loader", // Compiles Sass to CSS { loader: "sass-loader", options: { additionalData: '@import src/styles/base/entry.scss', // sass-loader >= 8 sassOptions: { indentedSyntax: true, }, }, }, ], } ) // Add first plugin defaults.webpackOptions.plugins = [ new VueLoaderPlugin() ] console.log(defaults) on('file:preprocessor', webpackPreprocessor(defaults)) }
错误触发文件sentryMixin.js片段
... const environment = process.env.VUE_APP_ENV ^ 此处为错误指向位置 ...
解决方案
方法1:在Cypress webpack配置中注入环境变量
正常Vue项目运行时,vue-cli-service会通过webpack.DefinePlugin把process.env注入浏览器环境,但你自定义的Cypress webpack预处理器没包含这个逻辑,需要手动添加:
修改Cypress插件文件(plugins/index.js):
const webpack = require('webpack') const { VueLoaderPlugin } = require('vue-loader') const webpackPreprocessor = require('@cypress/webpack-preprocessor') module.exports = (on, config) => { const defaults = webpackPreprocessor.defaultOptions // 保留原有的rules配置 defaults.webpackOptions.module.rules.push( { test: /\.vue$/, loader: 'vue-loader', }, { test: /\.sass$/i, use: [ "vue-style-loader", "css-loader", { loader: "sass-loader", options: { additionalData: '@import src/styles/base/entry.scss', sassOptions: { indentedSyntax: true, }, }, }, ], } ) // 添加环境变量注入插件 defaults.webpackOptions.plugins = [ new VueLoaderPlugin(), new webpack.DefinePlugin({ 'process.env': JSON.stringify({ VUE_APP_ENV: process.env.VUE_APP_ENV || 'development' // 其他需要的VUE_APP_开头变量也可以在这里添加 }) }) ] on('file:preprocessor', webpackPreprocessor(defaults)) return config }
启动Cypress前确保环境变量已设置,比如在终端执行:
VUE_APP_ENV=development npm run test:e2e
方法2:改用Cypress内置环境变量
修改前端代码兼容Cypress环境,直接用Cypress.env()获取变量:
修改sentryMixin.js:
const environment = typeof Cypress !== 'undefined' ? Cypress.env('VUE_APP_ENV') : process.env.VUE_APP_ENV
然后在cypress.config.js中配置变量:
const { defineConfig } = require('cypress') module.exports = defineConfig({ env: { VUE_APP_ENV: 'development' } })
关键原因
process是Node.js的全局对象,浏览器环境本身不存在。正常运行Vue项目时,vue-cli-service会通过webpack插件把process.env注入到浏览器代码中,但你自定义的Cypress webpack预处理器没有继承这个逻辑,导致浏览器中找不到process对象,从而报错。
内容的提问来源于stack exchange,提问作者Taylor Johnson
相关产品推荐
相关产品推荐

