Skip to content

Commit

Permalink
feat: support webpack-dev-server v5 in @cypress/webpack-dev-server (#…
Browse files Browse the repository at this point in the history
…29306)

* feat: support webpack-dev-server-5 for @cypress/webpack-dev-server [run ci]

* sidestep Forge types installed by webpack dev server [run ci]

* add changelog entry

* remove webpack 4 types

* format changelog

* Update cli/CHANGELOG.md

* Update npm/webpack-dev-server/src/helpers/sourceRelativeWebpackModules.ts

Co-authored-by: Matt Schile <mschile@cypress.io>

* add back in importsNotUsedAsValues and update system test snapshot

---------

Co-authored-by: Jennifer Shehane <jennifer@cypress.io>
Co-authored-by: Matt Schile <mschile@cypress.io>
  • Loading branch information
3 people committed Apr 18, 2024
1 parent b50ddd6 commit d7e9d60
Show file tree
Hide file tree
Showing 26 changed files with 12,344 additions and 282 deletions.
10 changes: 5 additions & 5 deletions .circleci/workflows.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ macWorkflowFilters: &darwin-workflow-filters
- equal: [ 'update-v8-snapshot-cache-on-develop', << pipeline.git.branch >> ]
- equal: [ 'cacie/dep/electron-27', << pipeline.git.branch >> ]
- equal: [ 'feat/protocol_shadow_dom_support', << pipeline.git.branch >> ]
- equal: [ 'chore/move_off_circle_to_macstadium_amd64', << pipeline.git.branch >> ]
- equal: [ 'feat/support_wds5', << pipeline.git.branch >> ]
- matches:
pattern: /^release\/\d+\.\d+\.\d+$/
value: << pipeline.git.branch >>
Expand All @@ -57,8 +57,8 @@ linuxArm64WorkflowFilters: &linux-arm64-workflow-filters
# 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: [ 'cacie/dep/electron-27', << pipeline.git.branch >> ]
- equal: [ 'feat/protocol_shadow_dom_support', << pipeline.git.branch >> ]
- equal: [ 'chore/move_off_circle_to_macstadium_amd64', << pipeline.git.branch >> ]
- equal: [ 'feat/support_wds5', << pipeline.git.branch >> ]
- equal: [ 'em/circle2', << pipeline.git.branch >> ]
- matches:
pattern: /^release\/\d+\.\d+\.\d+$/
value: << pipeline.git.branch >>
Expand All @@ -84,7 +84,7 @@ windowsWorkflowFilters: &windows-workflow-filters
- equal: [ 'cacie/dep/electron-27', << pipeline.git.branch >> ]
- equal: [ 'feat/protocol_shadow_dom_support', << pipeline.git.branch >> ]
- equal: [ 'lerna-optimize-tasks', << pipeline.git.branch >> ]
- equal: [ 'chore/move_off_circle_to_macstadium_amd64', << pipeline.git.branch >> ]
- equal: [ 'feat/support_wds5', << pipeline.git.branch >> ]
- matches:
pattern: /^release\/\d+\.\d+\.\d+$/
value: << pipeline.git.branch >>
Expand Down Expand Up @@ -151,7 +151,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" != "publish-binary" && "$CIRCLE_BRANCH" != "feat/protocol_shadow_dom_support" && "$CIRCLE_BRANCH" != "chore/move_off_circle_to_macstadium_amd64" ]]; then
echo 'if ! [[ "$CIRCLE_BRANCH" != "develop" && "$CIRCLE_BRANCH" != "release/"* && "$CIRCLE_BRANCH" != "publish-binary" && "$CIRCLE_BRANCH" != "feat/protocol_shadow_dom_support" && "$CIRCLE_BRANCH" != "feat/support_wds5" ]]; 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
8 changes: 6 additions & 2 deletions cli/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
<!-- See the ../guides/writing-the-cypress-changelog.md for details on writing the changelog. -->
## 13.7.4
## 13.8.0

_Released 4/16/2024 (PENDING)_
_Released 4/23/2024 (PENDING)_

**Features:**

- Added support for `webpack-dev-server` `v5` to `@cypress/webpack-dev-server`. Addresses [#29305](https://github.com/cypress-io/cypress/issues/29305).

**Misc:**

Expand Down
1 change: 1 addition & 0 deletions npm/webpack-dev-server/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ This module should be primarily covered by system-tests / open-mode tests. All s
`webpack${major}_wds${devServerMajor}-$framework{-$variant}`

- webpack4_wds3-react
- webpack5_wds5-react
- webpack4_wds4-next-11
- webpack5_wds3-next-12
- webpack4_wds4-create-react-app
Expand Down
117 changes: 72 additions & 45 deletions npm/webpack-dev-server/__snapshots__/makeWebpackConfig.spec.ts.js
Original file line number Diff line number Diff line change
@@ -1,50 +1,77 @@
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": {
"magicHtml": true,
"client": {
"progress": false,
"overlay": false
}
},
"optimization": {
"emitOnErrors": true,
"sideEffects": false,
"splitChunks": {
"chunks": "all"
}
},
"devtool": "inline-source-map",
"mode": "development",
"plugins": [
"HtmlWebpackPlugin",
"CypressCTWebpackPlugin"
]
'output': {
'publicPath': '/test-public-path/',
'filename': '[name].js',
},
'devServer': {
'magicHtml': true,
'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 v3 1'] = {
"output": {
"publicPath": "/test-public-path/",
"filename": "[name].js"
},
"devServer": {
"progress": true,
"overlay": false
},
"optimization": {
"noEmitOnErrors": false,
"sideEffects": false,
"splitChunks": {
"chunks": "all"
}
},
"devtool": "inline-source-map",
"mode": "development",
"plugins": [
"HtmlWebpackPlugin",
"CypressCTWebpackPlugin"
]
'output': {
'publicPath': '/test-public-path/',
'filename': '[name].js',
},
'devServer': {
'progress': true,
'overlay': false,
},
'optimization': {
'noEmitOnErrors': false,
'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/',
'filename': '[name].js',
},
'devServer': {
'magicHtml': true,
'client': {
'progress': false,
'overlay': false,
},
},
'optimization': {
'emitOnErrors': true,
'sideEffects': false,
'splitChunks': {
'chunks': 'all',
},
},
'devtool': 'inline-source-map',
'mode': 'development',
'plugins': [
'HtmlWebpackPlugin',
'CypressCTWebpackPlugin',
],
}
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_wds3-react', 'webpack4_wds4-react', 'webpack5_wds3-react', 'webpack5_wds4-react']
const WEBPACK_REACT: ProjectDirs[number][] = ['webpack4_wds3-react', 'webpack4_wds4-react', 'webpack5_wds3-react', 'webpack5_wds4-react', 'webpack5_wds5-react']

// Add to this list to focus on a particular permutation
const ONLY_PROJECTS: ProjectDirs[number][] = []
Expand Down
3 changes: 2 additions & 1 deletion npm/webpack-dev-server/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@
"ts-node": "^10.9.2",
"webpack": "npm:webpack@^5",
"webpack-4": "npm:webpack@^4",
"webpack-dev-server-3": "npm:webpack-dev-server@^3"
"webpack-dev-server-3": "npm:webpack-dev-server@^3",
"webpack-dev-server-5": "npm:webpack-dev-server@^5"
},
"files": [
"dist"
Expand Down
42 changes: 42 additions & 0 deletions npm/webpack-dev-server/src/createWebpackDevServer.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import debugLib from 'debug'
import type { Configuration as WebpackDevServer3Configuration } from 'webpack-dev-server-3'
import type { Configuration as WebpackDevServer4Configuration } from 'webpack-dev-server'
import type { Configuration as WebpackDevServer5Configuration } from 'webpack-dev-server-5'

import type { WebpackDevServerConfig } from './devServer'
import type { SourceRelativeWebpackResult } from './helpers/sourceRelativeWebpackModules'
Expand Down Expand Up @@ -46,6 +47,12 @@ export async function createWebpackDevServer (
const finalWebpackConfig = await makeWebpackConfig(config)
const webpackCompiler = webpack(finalWebpackConfig)

if (webpackDevServerMajorVersion === 5) {
debug('using webpack-dev-server v5')

return webpackDevServer5(config, webpackCompiler, finalWebpackConfig)
}

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

Expand All @@ -61,6 +68,41 @@ export async function createWebpackDevServer (
throw new Error(`Unsupported webpackDevServer version ${webpackDevServerMajorVersion}`)
}

function webpackDevServer5 (
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: WebpackDevServer5Configuration = {
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,
}

debug(WebpackDevServer)
debug(webpackDevServerConfig)

const server = new WebpackDevServer(webpackDevServerConfig, compiler)

debug(server)

return {
server,
compiler,
}
}

function webpackDevServer4 (
config: CreateFinalWebpackConfig,
compiler: object,
Expand Down
2 changes: 1 addition & 1 deletion npm/webpack-dev-server/src/helpers/nextHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -310,7 +310,7 @@ const originalModuleLoad = (Module as ModuleClass)._load
function sourceNextWebpackDeps (devServerConfig: WebpackDevServerConfig) {
const framework = sourceFramework(devServerConfig)!
const webpack = sourceNextWebpack(devServerConfig, framework)
const webpackDevServer = sourceWebpackDevServer(devServerConfig, framework)
const webpackDevServer = sourceWebpackDevServer(devServerConfig, webpack.majorVersion, framework)
const htmlWebpackPlugin = sourceHtmlWebpackPlugin(devServerConfig, framework, webpack)

return {
Expand Down
25 changes: 20 additions & 5 deletions npm/webpack-dev-server/src/helpers/sourceRelativeWebpackModules.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,13 @@ 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 All @@ -30,7 +37,7 @@ export interface SourcedWebpackDevServer extends SourcedDependency {
module: {
new (...args: unknown[]): unknown
}
majorVersion: 3 | 4
majorVersion: 3 | 4 | 5
}

export interface SourcedHtmlWebpackPlugin extends SourcedDependency {
Expand Down Expand Up @@ -180,11 +187,10 @@ export function sourceWebpack (config: WebpackDevServerConfig, framework: Source

// Source the webpack-dev-server module from the provided framework or projectRoot.
// If none is found, we fallback to the version bundled with this package.
export function sourceWebpackDevServer (config: WebpackDevServerConfig, framework?: SourcedDependency | null): SourcedWebpackDevServer {
export function sourceWebpackDevServer (config: WebpackDevServerConfig, webpackMajorVersion: 4 | 5, framework?: SourcedDependency | null): SourcedWebpackDevServer {
const searchRoot = framework?.importPath ?? config.cypressConfig.projectRoot

debug('WebpackDevServer: Attempting to source webpack-dev-server from %s', searchRoot)

const webpackDevServer = { } as SourcedWebpackDevServer
let webpackDevServerJsonPath: string

Expand All @@ -208,9 +214,18 @@ export function sourceWebpackDevServer (config: WebpackDevServerConfig, framewor
webpackDevServer.importPath = path.dirname(webpackDevServerJsonPath)
webpackDevServer.packageJson = require(webpackDevServerJsonPath)
webpackDevServer.module = require(webpackDevServer.importPath)
webpackDevServer.majorVersion = getMajorVersion(webpackDevServer.packageJson, [3, 4])
webpackDevServer.majorVersion = getMajorVersion(webpackDevServer.packageJson, [3, 4, 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 ${webpackMajorVersion} - 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
}
Expand Down Expand Up @@ -268,7 +283,7 @@ export function sourceHtmlWebpackPlugin (config: WebpackDevServerConfig, framewo
export function sourceDefaultWebpackDependencies (config: WebpackDevServerConfig): SourceRelativeWebpackResult {
const framework = sourceFramework(config)
const webpack = sourceWebpack(config, framework)
const webpackDevServer = sourceWebpackDevServer(config, framework)
const webpackDevServer = sourceWebpackDevServer(config, webpack.majorVersion, framework)
const htmlWebpackPlugin = sourceHtmlWebpackPlugin(config, framework, webpack)

return {
Expand Down
12 changes: 12 additions & 0 deletions npm/webpack-dev-server/src/makeDefaultWebpackConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,18 @@ export function makeCypressWebpackConfig (
}
}

if (webpackDevServerMajorVersion === 5) {
return {
...finalConfig,
devServer: {
port: webpackDevServerPort,
client: {
overlay: false,
},
},
}
}

if (webpackDevServerMajorVersion === 4) {
return {
...finalConfig,
Expand Down
22 changes: 22 additions & 0 deletions npm/webpack-dev-server/test/devServer-unit.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,4 +79,26 @@ describe('devServer', function () {
expect(result.server).to.be.instanceOf(require('webpack-dev-server'))
expect(result.version).to.eq(4)
})

it('creates a new devServer webpack5, webpackDevServer5', async () => {
const { devServer } = proxyquire('../src/devServer', {
'./helpers/sourceRelativeWebpackModules': {
sourceDefaultWebpackDependencies: () => {
return createModuleMatrixResult({
webpack: 5,
webpackDevServer: 5,
})
} },
}) 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-5'))
expect(result.version).to.eq(5)
})
})

5 comments on commit d7e9d60

@cypress-bot
Copy link
Contributor

@cypress-bot cypress-bot bot commented on d7e9d60 Apr 18, 2024

Choose a reason for hiding this comment

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

Circle has built the linux x64 version of the Test Runner.

Learn more about this pre-release build at https://on.cypress.io/advanced-installation#Install-pre-release-version

Run this command to install the pre-release locally:

npm install https://cdn.cypress.io/beta/npm/13.7.4/linux-x64/develop-d7e9d6068c6ab01ab58f9959ea7ad6a361087764/cypress.tgz

@cypress-bot
Copy link
Contributor

@cypress-bot cypress-bot bot commented on d7e9d60 Apr 18, 2024

Choose a reason for hiding this comment

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

Circle has built the linux arm64 version of the Test Runner.

Learn more about this pre-release build at https://on.cypress.io/advanced-installation#Install-pre-release-version

Run this command to install the pre-release locally:

npm install https://cdn.cypress.io/beta/npm/13.7.4/linux-arm64/develop-d7e9d6068c6ab01ab58f9959ea7ad6a361087764/cypress.tgz

@cypress-bot
Copy link
Contributor

@cypress-bot cypress-bot bot commented on d7e9d60 Apr 18, 2024

Choose a reason for hiding this comment

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

Circle has built the darwin arm64 version of the Test Runner.

Learn more about this pre-release build at https://on.cypress.io/advanced-installation#Install-pre-release-version

Run this command to install the pre-release locally:

npm install https://cdn.cypress.io/beta/npm/13.7.4/darwin-arm64/develop-d7e9d6068c6ab01ab58f9959ea7ad6a361087764/cypress.tgz

@cypress-bot
Copy link
Contributor

@cypress-bot cypress-bot bot commented on d7e9d60 Apr 18, 2024

Choose a reason for hiding this comment

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

Circle has built the darwin x64 version of the Test Runner.

Learn more about this pre-release build at https://on.cypress.io/advanced-installation#Install-pre-release-version

Run this command to install the pre-release locally:

npm install https://cdn.cypress.io/beta/npm/13.7.4/darwin-x64/develop-d7e9d6068c6ab01ab58f9959ea7ad6a361087764/cypress.tgz

@cypress-bot
Copy link
Contributor

@cypress-bot cypress-bot bot commented on d7e9d60 Apr 18, 2024

Choose a reason for hiding this comment

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

Circle has built the win32 x64 version of the Test Runner.

Learn more about this pre-release build at https://on.cypress.io/advanced-installation#Install-pre-release-version

Run this command to install the pre-release locally:

npm install https://cdn.cypress.io/beta/npm/13.7.4/win32-x64/develop-d7e9d6068c6ab01ab58f9959ea7ad6a361087764/cypress.tgz

Please sign in to comment.