Cypress returns Create React App 中 .scss 文件的 webpack 编译错误
Cypress returns webpack compilation error for .scss file in Create React App
我正在尝试将 Cypress 添加到一个非常基本的 CRA 中,但是 运行 正在解决 Cypress 能够理解 .scss 文件的问题。
当我运行npm run cypress
到运行测试时,我收到以下错误:
Error: Webpack Compilation Error
./src/App.scss 1:0
Module parse failed: Unexpected token (1:0)
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
> .app {
| align-items: center;
| display: flex !important;
@ ./src/App.jsx 28:0-21
@ ./cypress/integration/App.spec.js
...
当 Cypress 尝试挂载组件时,似乎没有使用 sass-loader?我该如何解决这个问题?
package.json:
{
"name": "cypress_test",
"version": "0.1.0",
"private": true,
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"cypress": "cypress open",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"dependencies": {
"@cypress/react": "^5.12.4",
"@cypress/webpack-dev-server": "^1.8.4",
"@emotion/react": "^11.9.0",
"@emotion/styled": "^11.8.1",
"@fontsource/roboto": "^4.5.5",
"@mui/icons-material": "^5.6.2",
"@mui/material": "^5.6.3",
"@mui/styled-engine-sc": "^5.6.1",
"@testing-library/jest-dom": "^5.16.4",
"@testing-library/react": "^12.1.5",
"@testing-library/user-event": "^13.5.0",
"cypress": "^9.6.0",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-scripts": "5.0.1",
"sass": "^1.51.0",
"styled-components": "^5.3.5",
"web-vitals": "^2.1.4"
},
"devDependencies": {
"@babel/core": "^7.17.9",
"@babel/preset-env": "^7.16.11",
"@cypress/webpack-preprocessor": "^5.11.1",
"babel-loader": "^8.2.5",
"eslint-plugin-cypress": "^2.12.1",
"html-webpack-plugin": "^4.5.2",
"webpack": "^5.72.0"
},
"eslintConfig": {
"extends": [
"react-app",
"react-app/jest"
]
},
"overrides": [
{
"extends": [
"plugin:cypress/recommended"
],
"files": [
"cypress/**/*.js"
]
}
],
"resolutions": {
"@mui/styled-engine": "npm:@mui/styled-engine-sc@latest"
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
},
"jest": {
"coveragePathIgnorePatterns": [
"<rootDir>/cypress/"
]
}
}
App.spec.js:
import React from 'react';
import data from '../fixtures/data.json';
import App from '../../src/App.jsx';
describe('Test search functionality', () => {
beforeEach(() => {
cy.mount(<App />);
});
it('renders new fact when search is performed', () => {
cy.visit('http://localhost:3001')
// Type in search input
cy.get('input').type('Test');
// Click on search button
cy.get('.submit-btn').click();
// Intercept the request and return the mock data
cy
.intercept({
method: 'GET',
url: `${process.env.REACT_APP_API_ENDPOINT}/jokes/search?query=Test`
}, {
fixture: data.result[1]
})
.as('fetchFact');
// cy.wait(['@fetchFact']);
cy.get('p.copy').should('contain', data.result[1].value);
})
});
cypress/plugins/index.js:
const injectDevServer = require('@cypress/react/plugins/react-scripts');
module.exports = (on, config) => {
injectDevServer(on, config);
return config;
};
更新:
在尝试下面提出的修改 plugins/index.js 文件的解决方案后,我收到一个新错误:
Error: For the selected environment is no default script chunk format available:
JSONP Array push can be chosen when 'document' or 'importScripts' is available.
CommonJs exports can be chosen when 'require' or node builtins are available.
Make sure that your 'browserslist' includes only platforms that support these features or select an appropriate 'target' to allow selecting a chunk format by default. Alternatively specify the 'output.chunkFormat' directly.
更新/cypress/plugins/index.js:
const findWebpack = require('find-webpack')
const webpackPreprocessor = require('@cypress/webpack-preprocessor');
const injectDevServer = require('@cypress/react/plugins/react-scripts');
module.exports = (on, config) => {
const webpackOptions = findWebpack.getWebpackOptions();
if (!webpackOptions) {
throw new Error('Could not find Webpack in this project');
}
const cleanOptions = { reactScripts: true };
findWebpack.cleanForCypress(cleanOptions, webpackOptions);
const options = {
webpackOptions,
watchOptions: {},
};
on('file:preprocessor', webpackPreprocessor(options));
injectDevServer(on, config);
return config;
};
我还从 package.json 中删除了 browserslist
密钥。
尝试将 CRA webpack 配置添加到 cypress 的 plugins/index
文件中:
/// <reference types="cypress" />
/// <reference types="../../../.." />
// @ts-check
const findWebpack = require('find-webpack')
const webpackPreprocessor = require('../../../..')
/**
* @type {Cypress.PluginConfig}
*/
module.exports = (on) => {
// find the Webpack config used by react-scripts
const webpackOptions = findWebpack.getWebpackOptions()
if (!webpackOptions) {
throw new Error('Could not find Webpack in this project ')
}
// if we just pass webpackOptions to the preprocessor
// it won't work - because react-scripts by default
// includes plugins that split specs into chunks, etc.
// https://github.com/cypress-io/cypress-webpack-preprocessor/issues/31
// solution 1
// blunt: delete entire optimization object
// delete webpackOptions.optimization
// solution 2
// use a module that carefully removes only plugins
// that we found to be breaking the bundling
// https://github.com/bahmutov/find-webpack
const cleanOptions = {
reactScripts: true,
}
findWebpack.cleanForCypress(cleanOptions, webpackOptions)
const options = {
webpackOptions,
watchOptions: {},
}
on('file:preprocessor', webpackPreprocessor(options))
}
以下是一些可能有用的链接:
Cypress Webpack 预处理器:https://github.com/cypress-io/cypress/tree/develop/npm/webpack-preprocessor#cypress-webpack-preprocessor
如何通过 react-scripts 依赖项将 Cypress 指向 Webpack 配置:https://github.com/cypress-io/cypress/tree/develop/npm/webpack-preprocessor/examples/react-app
我正在尝试将 Cypress 添加到一个非常基本的 CRA 中,但是 运行 正在解决 Cypress 能够理解 .scss 文件的问题。
当我运行npm run cypress
到运行测试时,我收到以下错误:
Error: Webpack Compilation Error
./src/App.scss 1:0
Module parse failed: Unexpected token (1:0)
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
> .app {
| align-items: center;
| display: flex !important;
@ ./src/App.jsx 28:0-21
@ ./cypress/integration/App.spec.js
...
当 Cypress 尝试挂载组件时,似乎没有使用 sass-loader?我该如何解决这个问题?
package.json:
{
"name": "cypress_test",
"version": "0.1.0",
"private": true,
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"cypress": "cypress open",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"dependencies": {
"@cypress/react": "^5.12.4",
"@cypress/webpack-dev-server": "^1.8.4",
"@emotion/react": "^11.9.0",
"@emotion/styled": "^11.8.1",
"@fontsource/roboto": "^4.5.5",
"@mui/icons-material": "^5.6.2",
"@mui/material": "^5.6.3",
"@mui/styled-engine-sc": "^5.6.1",
"@testing-library/jest-dom": "^5.16.4",
"@testing-library/react": "^12.1.5",
"@testing-library/user-event": "^13.5.0",
"cypress": "^9.6.0",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-scripts": "5.0.1",
"sass": "^1.51.0",
"styled-components": "^5.3.5",
"web-vitals": "^2.1.4"
},
"devDependencies": {
"@babel/core": "^7.17.9",
"@babel/preset-env": "^7.16.11",
"@cypress/webpack-preprocessor": "^5.11.1",
"babel-loader": "^8.2.5",
"eslint-plugin-cypress": "^2.12.1",
"html-webpack-plugin": "^4.5.2",
"webpack": "^5.72.0"
},
"eslintConfig": {
"extends": [
"react-app",
"react-app/jest"
]
},
"overrides": [
{
"extends": [
"plugin:cypress/recommended"
],
"files": [
"cypress/**/*.js"
]
}
],
"resolutions": {
"@mui/styled-engine": "npm:@mui/styled-engine-sc@latest"
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
},
"jest": {
"coveragePathIgnorePatterns": [
"<rootDir>/cypress/"
]
}
}
App.spec.js:
import React from 'react';
import data from '../fixtures/data.json';
import App from '../../src/App.jsx';
describe('Test search functionality', () => {
beforeEach(() => {
cy.mount(<App />);
});
it('renders new fact when search is performed', () => {
cy.visit('http://localhost:3001')
// Type in search input
cy.get('input').type('Test');
// Click on search button
cy.get('.submit-btn').click();
// Intercept the request and return the mock data
cy
.intercept({
method: 'GET',
url: `${process.env.REACT_APP_API_ENDPOINT}/jokes/search?query=Test`
}, {
fixture: data.result[1]
})
.as('fetchFact');
// cy.wait(['@fetchFact']);
cy.get('p.copy').should('contain', data.result[1].value);
})
});
cypress/plugins/index.js:
const injectDevServer = require('@cypress/react/plugins/react-scripts');
module.exports = (on, config) => {
injectDevServer(on, config);
return config;
};
更新: 在尝试下面提出的修改 plugins/index.js 文件的解决方案后,我收到一个新错误:
Error: For the selected environment is no default script chunk format available:
JSONP Array push can be chosen when 'document' or 'importScripts' is available.
CommonJs exports can be chosen when 'require' or node builtins are available.
Make sure that your 'browserslist' includes only platforms that support these features or select an appropriate 'target' to allow selecting a chunk format by default. Alternatively specify the 'output.chunkFormat' directly.
更新/cypress/plugins/index.js:
const findWebpack = require('find-webpack')
const webpackPreprocessor = require('@cypress/webpack-preprocessor');
const injectDevServer = require('@cypress/react/plugins/react-scripts');
module.exports = (on, config) => {
const webpackOptions = findWebpack.getWebpackOptions();
if (!webpackOptions) {
throw new Error('Could not find Webpack in this project');
}
const cleanOptions = { reactScripts: true };
findWebpack.cleanForCypress(cleanOptions, webpackOptions);
const options = {
webpackOptions,
watchOptions: {},
};
on('file:preprocessor', webpackPreprocessor(options));
injectDevServer(on, config);
return config;
};
我还从 package.json 中删除了 browserslist
密钥。
尝试将 CRA webpack 配置添加到 cypress 的 plugins/index
文件中:
/// <reference types="cypress" />
/// <reference types="../../../.." />
// @ts-check
const findWebpack = require('find-webpack')
const webpackPreprocessor = require('../../../..')
/**
* @type {Cypress.PluginConfig}
*/
module.exports = (on) => {
// find the Webpack config used by react-scripts
const webpackOptions = findWebpack.getWebpackOptions()
if (!webpackOptions) {
throw new Error('Could not find Webpack in this project ')
}
// if we just pass webpackOptions to the preprocessor
// it won't work - because react-scripts by default
// includes plugins that split specs into chunks, etc.
// https://github.com/cypress-io/cypress-webpack-preprocessor/issues/31
// solution 1
// blunt: delete entire optimization object
// delete webpackOptions.optimization
// solution 2
// use a module that carefully removes only plugins
// that we found to be breaking the bundling
// https://github.com/bahmutov/find-webpack
const cleanOptions = {
reactScripts: true,
}
findWebpack.cleanForCypress(cleanOptions, webpackOptions)
const options = {
webpackOptions,
watchOptions: {},
}
on('file:preprocessor', webpackPreprocessor(options))
}
以下是一些可能有用的链接:
Cypress Webpack 预处理器:https://github.com/cypress-io/cypress/tree/develop/npm/webpack-preprocessor#cypress-webpack-preprocessor
如何通过 react-scripts 依赖项将 Cypress 指向 Webpack 配置:https://github.com/cypress-io/cypress/tree/develop/npm/webpack-preprocessor/examples/react-app