Skip to content

Commit

Permalink
feat: support webpack-dev-server v4 (#17918)
Browse files Browse the repository at this point in the history
* feat: migrate to new webpack-dev-server public api

* fix: extract version check, and disallow minor releases matching `/3\./` with a starts with req.

* feat: support webpack-dev-server v4

* fix webpack warning causing overlay and types

* pin test dependency

* fix tests that were using incorrect wewbpack configuration

Co-authored-by: Ollie Relph <[email protected]>
  • Loading branch information
ZachJW34 and BBB authored Aug 30, 2021
1 parent 175ae3e commit 16e4759
Show file tree
Hide file tree
Showing 15 changed files with 576 additions and 252 deletions.
2 changes: 1 addition & 1 deletion npm/angular/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@
"tslib": "^2.2.0",
"tslint": "5.20.1",
"typescript": "4.2.4",
"webpack-dev-server": "3.11.2",
"webpack-dev-server": "4.0.0",
"zone.js": "0.11.4"
},
"peerDependencies": {
Expand Down
7 changes: 4 additions & 3 deletions npm/webpack-dev-server/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
"scripts": {
"build": "tsc",
"build-prod": "tsc",
"test": "tsc && mocha -r @packages/ts/register test/**/*.spec.ts test/*.spec.ts --exit",
"test": "node ./test-wds-3.js",
"test-all": "tsc && mocha -r @packages/ts/register test/**/*.spec.ts test/*.spec.ts --exit",
"watch": "tsc -w"
},
"dependencies": {
Expand All @@ -16,15 +17,15 @@
},
"devDependencies": {
"@types/webpack": ">=4",
"@types/webpack-dev-server": "^3.11.1",
"@types/webpack-dev-server": "^4.0.0",
"chai": "^4.2.0",
"html-webpack-plugin": "4.x",
"mocha": "^8.1.3",
"snap-shot-it": "7.9.3",
"speed-measure-webpack-plugin": "1.4.2",
"typescript": "^4.2.3",
"webpack": "^4.44.2",
"webpack-dev-server": "^3.11.0"
"webpack-dev-server": "^4.0.0"
},
"peerDependencies": {
"html-webpack-plugin": ">=4",
Expand Down
36 changes: 26 additions & 10 deletions npm/webpack-dev-server/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { debug as debugFn } from 'debug'
import { AddressInfo } from 'net'
import { Server } from 'http'
import { start as createDevServer, StartDevServer } from './startServer'
import { webpackDevServerFacts } from './webpackDevServerFacts'

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

Expand All @@ -17,26 +18,41 @@ export { StartDevServer }
export async function startDevServer (startDevServerArgs: StartDevServer, exitProcess = process.exit) {
const webpackDevServer = await createDevServer(startDevServerArgs, exitProcess)

return new Promise<ResolvedDevServerConfig>((resolve) => {
const httpSvr = webpackDevServer.listen(0, '127.0.0.1', () => {
// webpack-dev-server v3 returns `http.Server`.
// v4 returns a Promise that resolves `http.Server`.
// use Promise.resolve to make sure we get the `http.Server`,
// regardless of webpack-dev-server version.
Promise.resolve(httpSvr).then((server: Server) => {
return new Promise<ResolvedDevServerConfig>(async (resolve, reject) => {
if (webpackDevServerFacts.isV3()) {
const server: Server = webpackDevServer.listen(0, '127.0.0.1', () => {
// FIXME: handle address returning a string
const port = (server.address() as AddressInfo).port

debug('Component testing webpack server started on port', port)

return resolve({
resolve({
port,
close: (done?: DoneCallback) => {
httpSvr.close()
server.close()
done?.()
},
})
})
})

return
}

if (webpackDevServerFacts.isV4()) {
await webpackDevServer.start()

resolve({
// @ts-expect-error @types do not yet support v4
port: webpackDevServer.options.port,
close: (done?: DoneCallback) => {
webpackDevServer.stop()
done?.()
},
})

return
}

reject(webpackDevServerFacts.unsupported())
})
}
24 changes: 17 additions & 7 deletions npm/webpack-dev-server/src/startServer.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import Debug from 'debug'
import webpack from 'webpack'
import WebpackDevServer from 'webpack-dev-server'
import webpackDevServerPkg from 'webpack-dev-server/package.json'
import { makeWebpackConfig, UserWebpackDevServerOptions } from './makeWebpackConfig'
import { webpackDevServerFacts } from './webpackDevServerFacts'

export interface StartDevServer extends UserWebpackDevServerOptions {
/* this is the Cypress options object */
Expand Down Expand Up @@ -53,25 +53,35 @@ export async function start ({ webpackConfig: userWebpackConfig, template, optio
hot: false,
}

if (webpackDevServerPkg.version.match(/3\./)) {
if (webpackDevServerFacts.isV3()) {
debug('using webpack-dev-server v3')
webpackDevServerConfig = {
...webpackDevServerConfig,
// @ts-expect-error ignore webpack-dev-server v3 type errors
inline: false,
publicPath: devServerPublicPathRoute,
noInfo: false,
}
} else if (webpackDevServerPkg.version.match(/4\./)) {

// @ts-expect-error ignore webpack-dev-server v3 type errors
return new WebpackDevServer(compiler, webpackDevServerConfig)
}

if (webpackDevServerFacts.isV4()) {
debug('using webpack-dev-server v4')
webpackDevServerConfig = {
host: 'localhost',
port: 'auto',
...userWebpackConfig?.devServer,
devMiddleware: {
publicPath: devServerPublicPathRoute,
},
hot: false,
}
} else {
throw Error(`@cypress/webpack-dev-server only supports webpack-dev-server v3 and v4. Found: ${webpackDevServerPkg.version}.`)

// @ts-expect-error Webpack types are clashing between Webpack and WebpackDevServer
return new WebpackDevServer(webpackDevServerConfig, compiler)
}

// @ts-ignore types for webpack v5 are incorrect?
return new WebpackDevServer(compiler, webpackDevServerConfig)
throw webpackDevServerFacts.unsupported()
}
14 changes: 14 additions & 0 deletions npm/webpack-dev-server/src/webpackDevServerFacts.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import webpackDevServerPkg from 'webpack-dev-server/package.json'

export const webpackDevServerFacts = {
version: webpackDevServerPkg.version,
isV3 (version = webpackDevServerPkg.version) {
return /^3\./.test(version)
},
isV4 (version = webpackDevServerPkg.version) {
return /^4\./.test(version)
},
unsupported () {
return Error(`@cypress/webpack-dev-server only supports webpack-dev-server v3 and v4. Found: ${webpackDevServerFacts.version}.`)
},
}
49 changes: 49 additions & 0 deletions npm/webpack-dev-server/test-wds-3.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
const execa = require('execa')
const pkg = require('./package.json')
const fs = require('fs')

/**
* This file installs WebpackDevServer 3 and runs the tests for the dev-server.
* We read package.json, update the webpack version, then re-run yarn install.
* After it finishes, pass or fail,
* we revert the package.json back to the original state.
*
* The tests for the example projects (inside of examples) run with WebpackDevServer 3.
* This ensures we have some coverage for both versions.
*/
const main = async () => {
const originalPkg = JSON.stringify(pkg, null, 2)

const resetPkg = async () => {
fs.writeFileSync('package.json', originalPkg, 'utf8')
await execa('yarn', ['install'], { stdio: 'inherit' })
}

const checkExit = async ({ exitCode }) => {
if (typeof exitCode !== 'number') {
// eslint-disable-next-line no-console
console.error(`Finished with missing exit code from execa (received ${exitCode})`)
}

await resetPkg()
process.exit(exitCode)
}

pkg.devDependencies['webpack-dev-server'] = '3.11.0'
// eslint-disable-next-line no-console
console.log('[@cypress/webpack-dev-server]: updating package.json...')
fs.writeFileSync('package.json', JSON.stringify(pkg, null, 2))

// eslint-disable-next-line no-console
console.log('[@cypress/webpack-dev-server]: install dependencies...')
await execa('yarn', ['install'], { stdio: 'inherit' })

const { exitCode } = await execa('yarn', ['test-all'], { stdio: 'inherit' })

await checkExit({ exitCode })
}

// execute main function if called from command line
if (require.main === module) {
main()
}
12 changes: 6 additions & 6 deletions npm/webpack-dev-server/test/e2e.spec.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import webpack from 'webpack'
import path from 'path'
import sinon from 'sinon'
import { expect } from 'chai'
import { EventEmitter } from 'events'
import http from 'http'
import fs from 'fs'
import { webpackDevServerFacts } from '../src/webpackDevServerFacts'

import { startDevServer } from '../'

Expand Down Expand Up @@ -34,11 +34,11 @@ const requestSpecFile = (port: number) => {

const root = path.join(__dirname, '..')

const webpackConfig: webpack.Configuration = {
output: {
path: root,
publicPath: root,
},
const webpackConfig = {
devServer: webpackDevServerFacts.isV3()
? { contentBase: root }
: { static: { directory: root } },

}

const specs: Cypress.Cypress['spec'][] = [
Expand Down
19 changes: 19 additions & 0 deletions npm/webpack-dev-server/test/unit/webpackDevServerFacts.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { expect } from 'chai'
import { webpackDevServerFacts } from '../../src/webpackDevServerFacts'

describe('webpackDevServerFacts', () => {
it('should detect v3', () => {
expect(webpackDevServerFacts.isV3('3.0.0')).equals(true)
expect(webpackDevServerFacts.isV3('3.1.4')).equals(true)
expect(webpackDevServerFacts.isV3('4.0.0')).equals(false)
expect(webpackDevServerFacts.isV3('4.3.0')).equals(false)
})

it('should detect v4', () => {
expect(webpackDevServerFacts.isV4('3.0.0')).equals(false)
expect(webpackDevServerFacts.isV4('3.1.4')).equals(false)
expect(webpackDevServerFacts.isV4('3.4.4')).equals(false)
expect(webpackDevServerFacts.isV4('4.0.0')).equals(true)
expect(webpackDevServerFacts.isV4('4.3.0')).equals(true)
})
})
1 change: 1 addition & 0 deletions packages/runner-ct/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
"@fortawesome/free-regular-svg-icons": "5.15.2",
"@fortawesome/react-fontawesome": "^0.1.14",
"@packages/driver": "0.0.0-development",
"@types/http-proxy": "1.17.4",
"@types/node": "14.14.31",
"@types/sockjs-client": "1.1.0",
"ansi-to-html": "0.6.14",
Expand Down
3 changes: 0 additions & 3 deletions packages/server-ct/example/webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,4 @@ module.exports = {
output: {
publicPath: '/',
},
devServer: {
publicPath: '/',
},
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,6 @@ module.exports = (on, config) => {
output: {
publicPath: '/',
},
devServer: {
publicPath: '/',
},
},
options,
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,6 @@ const webpackConfig = {
output: {
publicPath: '/',
},
devServer: {
publicPath: '/',
},
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,6 @@ const webpackConfig = {
output: {
publicPath: '/',
},
devServer: {
publicPath: '/',
},
}

/**
Expand Down
2 changes: 1 addition & 1 deletion packages/ui-components/src/file-opener/file-opener.scss
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ $font-sans: "Helvetica Neue", Helvetica, Arial, sans-serif !default;

.editor-picker {
label {
align-items: start;
align-items: flex-start;
display: flex;
flex-wrap: wrap;
}
Expand Down
Loading

0 comments on commit 16e4759

Please sign in to comment.