Skip to content

breaking: remove support for webpack 4 and webpack-dev-server 4 inside @cypress/webpack-preprocessor and @cypress/webpack-dev-server #31506

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 1, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .circleci/cache-version.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
# Bump this version to force CI to re-create the cache from scratch.

4-24-2025
4-28-2025
10 changes: 5 additions & 5 deletions .circleci/workflows.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ mainBuildFilters: &mainBuildFilters
- /^release\/\d+\.\d+\.\d+$/
# use the following branch as well to ensure that v8 snapshot cache updates are fully tested
- 'update-v8-snapshot-cache-on-develop'
- 'feat/replace_tsnode_for_tsx_config_process'
- 'breaking/remove_webpack_4'

# usually we don't build Mac app - it takes a long time
# but sometimes we want to really confirm we are doing the right thing
Expand All @@ -49,7 +49,7 @@ macWorkflowFilters: &darwin-workflow-filters
- equal: [ develop, << pipeline.git.branch >> ]
# use the following branch as well to ensure that v8 snapshot cache updates are fully tested
- equal: [ 'update-v8-snapshot-cache-on-develop', << pipeline.git.branch >> ]
- equal: [ 'feat/replace_tsnode_for_tsx_config_process', << pipeline.git.branch >> ]
- equal: [ 'breaking/remove_webpack_4', << pipeline.git.branch >> ]
- matches:
pattern: /^release\/\d+\.\d+\.\d+$/
value: << pipeline.git.branch >>
Expand All @@ -60,7 +60,7 @@ linuxArm64WorkflowFilters: &linux-arm64-workflow-filters
- equal: [ develop, << pipeline.git.branch >> ]
# use the following branch as well to ensure that v8 snapshot cache updates are fully tested
- equal: [ 'update-v8-snapshot-cache-on-develop', << pipeline.git.branch >> ]
- equal: [ 'feat/replace_tsnode_for_tsx_config_process', << pipeline.git.branch >> ]
- equal: [ 'breaking/remove_webpack_4', << pipeline.git.branch >> ]
- matches:
pattern: /^release\/\d+\.\d+\.\d+$/
value: << pipeline.git.branch >>
Expand All @@ -83,7 +83,7 @@ windowsWorkflowFilters: &windows-workflow-filters
- equal: [ develop, << pipeline.git.branch >> ]
# use the following branch as well to ensure that v8 snapshot cache updates are fully tested
- equal: [ 'update-v8-snapshot-cache-on-develop', << pipeline.git.branch >> ]
- equal: [ 'feat/replace_tsnode_for_tsx_config_process', << pipeline.git.branch >> ]
- equal: [ 'breaking/remove_webpack_4', << pipeline.git.branch >> ]
- matches:
pattern: /^release\/\d+\.\d+\.\d+$/
value: << pipeline.git.branch >>
Expand Down Expand Up @@ -157,7 +157,7 @@ commands:
name: Set environment variable to determine whether or not to persist artifacts
command: |
echo "Setting SHOULD_PERSIST_ARTIFACTS variable"
echo 'if ! [[ "$CIRCLE_BRANCH" != "develop" && "$CIRCLE_BRANCH" != "release/"* && "$CIRCLE_BRANCH" != "feat/replace_tsnode_for_tsx_config_process" ]]; then
echo 'if ! [[ "$CIRCLE_BRANCH" != "develop" && "$CIRCLE_BRANCH" != "release/"* && "$CIRCLE_BRANCH" != "breaking/remove_webpack_4" ]]; then
export SHOULD_PERSIST_ARTIFACTS=true
fi' >> "$BASH_ENV"
# You must run `setup_should_persist_artifacts` command and be using bash before running this command
Expand Down
2 changes: 2 additions & 0 deletions cli/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ _Released 07/01/2025 (PENDING)_
- Removed support for Node.js 18 and Node.js 23. Addresses [#31302](https://github.com/cypress-io/cypress/issues/31302).
- Removed support for [Chrome DevTools Protocol](https://chromedevtools.github.io/devtools-protocol) with the [firefox](https://www.mozilla.org/) browser. Addresses [#31189](https://github.com/cypress-io/cypress/issues/31189).
- The Cypress configuration wizard for Component Testing supports TypeScript 5.0 or greater. Addresses [#31187](https://github.com/cypress-io/cypress/issues/31187).
- `@cypress/webpack-dev-server` and `@cypress/webpack-preprocessor` no longer support `webpack` version 4. Addresses [#31344](https://github.com/cypress-io/cypress/issues/31344). If you still need to use `webpack` version 4, please see our [migration guide](https://docs.cypress.io/app/references/migration-guide#Migrating-to-Cypress-150).
- `@cypress/webpack-dev-server` no longer supports `webpack-dev-server` version 4. Addresses [#31605](https://github.com/cypress-io/cypress/issues/31605). If you still need to use `webpack-dev-server` version 4, please see our [migration guide](https://docs.cypress.io/app/references/migration-guide#Migrating-to-Cypress-150).

**Features:**

Expand Down
2 changes: 1 addition & 1 deletion npm/webpack-batteries-included-preprocessor/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ This preprocessor is a wrapper for [@cypress/webpack-preprocessor](https://githu

Note that installing [@cypress/webpack-preprocessor](https://github.com/cypress-io/cypress-webpack-preprocessor) is also required. This allows you to update its version separately from this wrapper.

For webpack `v5`, use `@cypress/[email protected]`. For webpack `v4`, use `@cypress/[email protected]`.
For webpack `v5`, use `@cypress/[email protected]` and up. For webpack `v4`, use `@cypress/[email protected]`.

```sh
npm install --save-dev @cypress/webpack-batteries-included-preprocessor @cypress/webpack-preprocessor
Expand Down
2 changes: 1 addition & 1 deletion npm/webpack-batteries-included-preprocessor/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@
"typescript": "~5.4.5"
},
"peerDependencies": {
"@cypress/webpack-preprocessor": "^5.4.4"
"@cypress/webpack-preprocessor": "^6.0.4"
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this will need to be @cypress/webpack-preprocessor@7 in Cypress 15

},
"files": [
"index.js",
Expand Down
26 changes: 0 additions & 26 deletions npm/webpack-dev-server/__snapshots__/makeWebpackConfig.spec.ts.js
Original file line number Diff line number Diff line change
@@ -1,29 +1,3 @@
exports['makeWebpackConfig ignores userland webpack `output.publicPath` and `devServer.overlay` with webpack-dev-server v4 1'] = {
'output': {
'publicPath': '/test-public-path/',
'filename': '[name].js',
},
'devServer': {
'client': {
'progress': false,
'overlay': false,
},
},
'optimization': {
'emitOnErrors': true,
'sideEffects': false,
'splitChunks': {
'chunks': 'all',
},
},
'devtool': 'inline-source-map',
'mode': 'development',
'plugins': [
'HtmlWebpackPlugin',
'CypressCTWebpackPlugin',
],
}

exports['makeWebpackConfig ignores userland webpack `output.publicPath` and `devServer.overlay` with webpack-dev-server v5 1'] = {
'output': {
'publicPath': '/test-public-path/',
Expand Down
2 changes: 1 addition & 1 deletion npm/webpack-dev-server/cypress/e2e/react.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import dedent from 'dedent'

type ProjectDirs = typeof fixtureDirs

const WEBPACK_REACT: ProjectDirs[number][] = ['webpack4_wds4-react', 'webpack5_wds4-react', 'webpack5_wds5-react']
const WEBPACK_REACT: ProjectDirs[number][] = ['webpack5_wds5-react']

// Add to this list to focus on a particular permutation
const ONLY_PROJECTS: ProjectDirs[number][] = []
Expand Down
16 changes: 8 additions & 8 deletions npm/webpack-dev-server/cypress/e2e/webpack-dev-server.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

describe('Config options', () => {
it('supports supportFile = false', () => {
cy.scaffoldProject('webpack5_wds4-react')
cy.openProject('webpack5_wds4-react', ['--config-file', 'cypress-webpack-no-support.config.ts', '--component'])
cy.scaffoldProject('webpack5_wds5-react')
cy.openProject('webpack5_wds5-react', ['--config-file', 'cypress-webpack-no-support.config.ts', '--component'])
cy.startAppServer('component')

cy.visitApp()
Expand All @@ -26,8 +26,8 @@ describe('Config options', () => {
})

it('supports @cypress/webpack-dev-server', () => {
cy.scaffoldProject('webpack5_wds4-react')
cy.openProject('webpack5_wds4-react', ['--config-file', 'cypress-webpack-dev-server-function.config.ts', '--component'])
cy.scaffoldProject('webpack5_wds5-react')
cy.openProject('webpack5_wds5-react', ['--config-file', 'cypress-webpack-dev-server-function.config.ts', '--component'])
cy.startAppServer('component')

cy.visitApp()
Expand All @@ -38,8 +38,8 @@ describe('Config options', () => {
})

it('supports webpackConfig as an async function', () => {
cy.scaffoldProject('webpack5_wds4-react')
cy.openProject('webpack5_wds4-react', ['--config-file', 'cypress-webpack-dev-server-async-config.config.ts', '--component'])
cy.scaffoldProject('webpack5_wds5-react')
cy.openProject('webpack5_wds5-react', ['--config-file', 'cypress-webpack-dev-server-async-config.config.ts', '--component'])
cy.startAppServer('component')

cy.visitApp()
Expand All @@ -56,8 +56,8 @@ describe('Config options', () => {
})

it('recompiles with new spec and custom indexHtmlFile', () => {
cy.scaffoldProject('webpack5_wds4-react')
cy.openProject('webpack5_wds4-react', ['--config-file', 'cypress-webpack-dev-server-custom-index.config.ts', '--component'])
cy.scaffoldProject('webpack5_wds5-react')
cy.openProject('webpack5_wds5-react', ['--config-file', 'cypress-webpack-dev-server-custom-index.config.ts', '--component'])
cy.startAppServer('component')

cy.visitApp()
Expand Down
7 changes: 2 additions & 5 deletions npm/webpack-dev-server/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
"dependencies": {
"find-up": "6.3.0",
"fs-extra": "9.1.0",
"html-webpack-plugin-4": "npm:html-webpack-plugin@^4",
"html-webpack-plugin-5": "npm:html-webpack-plugin@^5",
"local-pkg": "0.4.1",
"semver": "^7.7.1",
Expand All @@ -39,12 +38,10 @@
"sinon": "^13.0.1",
"snap-shot-it": "^7.9.10",
"ts-node": "^10.9.2",
"webpack": "npm:webpack@^5",
"webpack-4": "npm:webpack@^4",
"webpack-dev-server-4": "npm:webpack-dev-server@^4"
"webpack": "npm:webpack@^5"
},
"peerDependencies": {
"cypress": ">=14.0.0"
"cypress": ">=15.0.0"
},
"files": [
"dist"
Expand Down
37 changes: 0 additions & 37 deletions npm/webpack-dev-server/src/createWebpackDevServer.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import debugLib from 'debug'
import type { Configuration as WebpackDevServer5Configuration } from 'webpack-dev-server'
import type { Configuration as WebpackDevServer4Configuration } from 'webpack-dev-server-4'
import type { WebpackDevServerConfig } from './devServer'
import type { SourceRelativeWebpackResult } from './helpers/sourceRelativeWebpackModules'
import { makeWebpackConfig } from './makeWebpackConfig'
Expand Down Expand Up @@ -51,12 +50,6 @@ export async function createWebpackDevServer (
return webpackDevServer5(config, webpackCompiler, finalWebpackConfig)
}

if (webpackDevServerMajorVersion === 4) {
debug('using webpack-dev-server v4')

return webpackDevServer4(config, webpackCompiler, finalWebpackConfig)
}

throw new Error(`Unsupported webpackDevServer version ${webpackDevServerMajorVersion}`)
}

Expand Down Expand Up @@ -94,33 +87,3 @@ function webpackDevServer5 (
compiler,
}
}

function webpackDevServer4 (
config: CreateFinalWebpackConfig,
compiler: object,
finalWebpackConfig: Record<string, any>,
) {
const { devServerConfig: { cypressConfig: { devServerPublicPathRoute } } } = config
const isOpenMode = !config.devServerConfig.cypressConfig.isTextTerminal
const WebpackDevServer = config.sourceWebpackModulesResult.webpackDevServer.module
const webpackDevServerConfig: WebpackDevServer4Configuration = {
host: '127.0.0.1',
port: 'auto',
// @ts-ignore
...finalWebpackConfig?.devServer,
devMiddleware: {
publicPath: devServerPublicPathRoute,
stats: finalWebpackConfig.stats ?? 'minimal',
},
hot: false,
// Only enable file watching & reload when executing tests in `open` mode
liveReload: isOpenMode,
}

const server = new WebpackDevServer(webpackDevServerConfig, compiler)

return {
server,
compiler,
}
}
6 changes: 0 additions & 6 deletions npm/webpack-dev-server/src/devServer.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
/// <reference types="cypress" />

import type WebpackDevServer5 from 'webpack-dev-server'
import type WebpackDevServer4 from 'webpack-dev-server-4'

import type { Compiler, Configuration } from 'webpack'

import { createWebpackDevServer } from './createWebpackDevServer'
Expand Down Expand Up @@ -40,10 +38,6 @@ export type WebpackDevServerConfig = {
* @internal
*/
type DevServerCreateResult = {
version: 4
server: WebpackDevServer4
compiler: Compiler
} | {
version: 5
server: WebpackDevServer5
compiler: Compiler
Expand Down
27 changes: 6 additions & 21 deletions npm/webpack-dev-server/src/helpers/sourceRelativeWebpackModules.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,6 @@ import debugFn from 'debug'

const debug = debugFn('cypress:webpack-dev-server:sourceRelativeWebpackModules')

class CypressWebpackDevServerError extends Error {
constructor (message: string) {
super(message)
this.name = 'CypressWebpackDevServerError'
}
}

export type ModuleClass = typeof Module & {
_load(id: string, parent: Module, isMain: boolean): any
_resolveFilename(request: string, parent: Module, isMain: boolean, options?: { paths: string[] }): string
Expand Down Expand Up @@ -147,7 +140,7 @@ export function sourceWebpack (config: WebpackDevServerConfig, framework: Source
webpack.importPath = path.dirname(webpackJsonPath)
webpack.packageJson = require(webpackJsonPath)
webpack.module = require(webpack.importPath)
webpack.majorVersion = getMajorVersion(webpack.packageJson, [4, 5])
webpack.majorVersion = getMajorVersion(webpack.packageJson, [5])

debug('Webpack: Successfully sourced webpack - %o', webpack)

Expand Down Expand Up @@ -211,25 +204,17 @@ export function sourceWebpackDevServer (config: WebpackDevServerConfig, webpackM
webpackDevServer.importPath = path.dirname(webpackDevServerJsonPath)
webpackDevServer.packageJson = require(webpackDevServerJsonPath)
webpackDevServer.module = require(webpackDevServer.importPath)
webpackDevServer.majorVersion = getMajorVersion(webpackDevServer.packageJson, [4, 5])
webpackDevServer.majorVersion = getMajorVersion(webpackDevServer.packageJson, [5])

debug('WebpackDevServer: Successfully sourced webpack-dev-server - %o', webpackDevServer)
if (webpackMajorVersion < 5 && webpackDevServer.majorVersion === 5) {
const json = webpackDevServer.packageJson

throw new CypressWebpackDevServerError(
`Incompatible major versions of webpack and webpack-dev-server!
webpack-dev-server major version ${webpackDevServer.majorVersion} only works with major versions of webpack 5 - saw webpack-dev-server version ${json.version}.
If using webpack major version 4, please install webpack-dev-server version 4 to be used with @cypress/webpack-dev-server or upgrade to webpack 5.`,
)
}

return webpackDevServer
}

// Source the html-webpack-plugin module from the provided framework or projectRoot.
// If none is found, we fallback to the version bundled with this package dependent on the major version of webpack.
// We ship both v4 and v5 of 'html-webpack-plugin' by aliasing the package with the major version (check package.json).
// We ship v5 of 'html-webpack-plugin' by aliasing the package with the major version (check package.json). This allows
// us to support newer major versions of 'html-webpack-plugin' easily'.
export function sourceHtmlWebpackPlugin (config: WebpackDevServerConfig, framework: SourcedDependency | null, webpack: SourcedWebpack): SourcedHtmlWebpackPlugin {
const searchRoot = framework?.importPath ?? config.cypressConfig.projectRoot

Expand All @@ -244,9 +229,9 @@ export function sourceHtmlWebpackPlugin (config: WebpackDevServerConfig, framewo
})

htmlWebpackPlugin.packageJson = require(htmlWebpackPluginJsonPath)
// Check that they're not using v3 of html-webpack-plugin. Since we should be the only consumer of it,
// Check that they're not using v3 or v4 of html-webpack-plugin. Since we should be the only consumer of it,
// we shouldn't be concerned with using our own copy if they've shipped w/ an earlier version
htmlWebpackPlugin.majorVersion = getMajorVersion(htmlWebpackPlugin.packageJson, [4, 5])
htmlWebpackPlugin.majorVersion = getMajorVersion(htmlWebpackPlugin.packageJson, [5])
} catch (e) {
const err = e as Error & {code?: string}

Expand Down
44 changes: 0 additions & 44 deletions npm/webpack-dev-server/test/devServer-unit.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,50 +14,6 @@ const cypressConfig = {
describe('devServer', function () {
this.timeout(10 * 1000)

it('creates a new devServer webpack4, webpackDevServer4', async () => {
const { devServer } = proxyquire('../src/devServer', {
'./helpers/sourceRelativeWebpackModules': {
sourceDefaultWebpackDependencies: () => {
return createModuleMatrixResult({
webpack: 4,
webpackDevServer: 4,
})
} },
}) as typeof import('../src/devServer')

const result = await devServer.create({
specs: [],
cypressConfig,
webpackConfig: {},
devServerEvents: new EventEmitter(),
})

expect(result.server).to.be.instanceOf(require('webpack-dev-server-4'))
expect(result.version).to.eq(4)
})

it('creates a new devServer webpack5, webpackDevServer4', async () => {
const { devServer } = proxyquire('../src/devServer', {
'./helpers/sourceRelativeWebpackModules': {
sourceDefaultWebpackDependencies: () => {
return createModuleMatrixResult({
webpack: 5,
webpackDevServer: 4,
})
} },
}) as typeof import('../src/devServer')

const result = await devServer.create({
specs: [],
cypressConfig,
webpackConfig: {},
devServerEvents: new EventEmitter(),
})

expect(result.server).to.be.instanceOf(require('webpack-dev-server-4'))
expect(result.version).to.eq(4)
})

it('creates a new devServer webpack5, webpackDevServer5', async () => {
const { devServer } = proxyquire('../src/devServer', {
'./helpers/sourceRelativeWebpackModules': {
Expand Down
Loading
Loading