From 4bb1ecd077fc3724e6c127982f98e1e6b0f1bb98 Mon Sep 17 00:00:00 2001 From: Adam Gastineau Date: Fri, 14 May 2021 10:07:03 -0700 Subject: [PATCH] fix: Properly typecheck webpack-dev-server and fix several undefined issues (#16503) --- npm/webpack-dev-server/src/aut-runner.ts | 2 +- .../src/makeWebpackConfig.ts | 4 +-- .../src/measureWebpackPerformance.ts | 6 ++-- npm/webpack-dev-server/src/plugin.ts | 28 ++++++++++++++----- npm/webpack-dev-server/src/startServer.ts | 4 +-- npm/webpack-dev-server/tsconfig.json | 2 +- yarn.lock | 6 ++-- 7 files changed, 34 insertions(+), 18 deletions(-) diff --git a/npm/webpack-dev-server/src/aut-runner.ts b/npm/webpack-dev-server/src/aut-runner.ts index 84327ea248f9..83252a5f9336 100644 --- a/npm/webpack-dev-server/src/aut-runner.ts +++ b/npm/webpack-dev-server/src/aut-runner.ts @@ -1,6 +1,6 @@ /* eslint-env browser */ -export function init (importPromises, parent: Window = (window.opener || window.parent)) { +export function init (importPromises: Array<() => Promise>, parent: Window = (window.opener || window.parent)) { const Cypress = window.Cypress = parent.Cypress if (!Cypress) { diff --git a/npm/webpack-dev-server/src/makeWebpackConfig.ts b/npm/webpack-dev-server/src/makeWebpackConfig.ts index b44db4b06c6b..b2f44d7df911 100644 --- a/npm/webpack-dev-server/src/makeWebpackConfig.ts +++ b/npm/webpack-dev-server/src/makeWebpackConfig.ts @@ -3,7 +3,7 @@ import * as path from 'path' import * as webpack from 'webpack' import { merge } from 'webpack-merge' import makeDefaultWebpackConfig from './webpack.config' -import CypressCTOptionsPlugin, { CypressCTOptionsPluginOptions } from './plugin' +import CypressCTOptionsPlugin, { CypressCTOptionsPluginOptionsWithEmitter } from './plugin' const debug = debugFn('cypress:webpack-dev-server:makeWebpackConfig') @@ -17,7 +17,7 @@ export interface UserWebpackDevServerOptions { disableLazyCompilation?: boolean } -interface MakeWebpackConfigOptions extends CypressCTOptionsPluginOptions, UserWebpackDevServerOptions { +interface MakeWebpackConfigOptions extends CypressCTOptionsPluginOptionsWithEmitter, UserWebpackDevServerOptions { devServerPublicPathRoute: string isOpenMode: boolean template?: string diff --git a/npm/webpack-dev-server/src/measureWebpackPerformance.ts b/npm/webpack-dev-server/src/measureWebpackPerformance.ts index a227c072ab57..ef23ba8bb14b 100644 --- a/npm/webpack-dev-server/src/measureWebpackPerformance.ts +++ b/npm/webpack-dev-server/src/measureWebpackPerformance.ts @@ -1,11 +1,13 @@ /* eslint-disable no-console */ -import * as webpack from 'webpack' +import type { Configuration } from 'webpack' import path from 'path' import fs from 'fs' import chalk from 'chalk' + +// @ts-ignore import SpeedMeasurePlugin from 'speed-measure-webpack-plugin' -export function measureWebpackPerformance (webpackConfig: webpack.Configuration): webpack.Configuration { +export function measureWebpackPerformance (webpackConfig: Configuration): Configuration { if (!process.env.WEBPACK_PERF_MEASURE) { throw new Error('Performance monitoring is possible only with WEBPACK_PERF_MEASURE env variable set') } diff --git a/npm/webpack-dev-server/src/plugin.ts b/npm/webpack-dev-server/src/plugin.ts index bcadca6fd1da..a478d8f0cfc6 100644 --- a/npm/webpack-dev-server/src/plugin.ts +++ b/npm/webpack-dev-server/src/plugin.ts @@ -4,6 +4,8 @@ import _ from 'lodash' import semver from 'semver' import fs, { PathLike } from 'fs' import path from 'path' +// eslint-disable-next-line no-duplicate-imports +import type { Compilation } from 'webpack' type UtimesSync = (path: PathLike, atime: string | number | Date, mtime: string | number | Date) => void @@ -14,10 +16,23 @@ export interface CypressCTOptionsPluginOptions { devServerEvents?: EventEmitter } +export type CypressCTOptionsPluginOptionsWithEmitter = CypressCTOptionsPluginOptions & { + devServerEvents: EventEmitter +} + export interface CypressCTWebpackContext { _cypress: CypressCTOptionsPluginOptions } +export type Webpack45Compilation = Compilation & { + // TODO: Drop these additional Webpack 4 types + inputFileSystem: { + fileSystem: { + utimesSync: UtimesSync + } + } +} + export default class CypressCTOptionsPlugin { private files: Cypress.Cypress['spec'][] = [] private supportFile: string @@ -26,7 +41,7 @@ export default class CypressCTOptionsPlugin { private readonly projectRoot: string private readonly devServerEvents: EventEmitter - constructor (options: CypressCTOptionsPluginOptions) { + constructor (options: CypressCTOptionsPluginOptionsWithEmitter) { this.files = options.files this.supportFile = options.supportFile this.projectRoot = options.projectRoot @@ -49,7 +64,7 @@ export default class CypressCTOptionsPlugin { if (stats.hasErrors()) { this.errorEmitted = true - this.devServerEvents.emit('dev-server:compile:error', stats.toJson().errors[0]) + this.devServerEvents.emit('dev-server:compile:error', stats.toJson().errors?.[0]) } else if (this.errorEmitted) { // compilation succeed but assets haven't emitted to the output yet this.devServerEvents.emit('dev-server:compile:error', null) @@ -72,7 +87,7 @@ export default class CypressCTOptionsPlugin { * @param compilation webpack 4 `compilation.Compilation`, webpack 5 * `Compilation` */ - private plugin = (compilation) => { + private plugin = (compilation: Webpack45Compilation) => { this.devServerEvents.on('dev-server:specs:changed', (specs) => { if (_.isEqual(specs, this.files)) return @@ -86,10 +101,9 @@ export default class CypressCTOptionsPlugin { // Webpack 5 /* istanbul ignore next */ if ('NormalModule' in webpack) { - // @ts-ignore webpack.NormalModule.getCompilationHooks(compilation).loader.tap( 'CypressCTOptionsPlugin', - this.pluginFunc, + (context) => this.pluginFunc(context as CypressCTWebpackContext), ) return @@ -98,12 +112,12 @@ export default class CypressCTOptionsPlugin { // Webpack 4 compilation.hooks.normalModuleLoader.tap( 'CypressCTOptionsPlugin', - this.pluginFunc, + (context) => this.pluginFunc(context as CypressCTWebpackContext), ) }; apply (compiler: Compiler): void { this.setupCustomHMR(compiler) - compiler.hooks.compilation.tap('CypressCTOptionsPlugin', this.plugin) + compiler.hooks.compilation.tap('CypressCTOptionsPlugin', (compilation) => this.plugin(compilation as Webpack45Compilation)) } } diff --git a/npm/webpack-dev-server/src/startServer.ts b/npm/webpack-dev-server/src/startServer.ts index b29a1b0c3f5f..1670944c7e68 100644 --- a/npm/webpack-dev-server/src/startServer.ts +++ b/npm/webpack-dev-server/src/startServer.ts @@ -50,7 +50,7 @@ export async function start ({ webpackConfig: userWebpackConfig, template, optio debug('starting webpack dev server') let webpackDevServerConfig: WebpackDevServer.Configuration = { - ...userWebpackConfig.devServer, + ...userWebpackConfig?.devServer, hot: false, } @@ -63,7 +63,7 @@ export async function start ({ webpackConfig: userWebpackConfig, template, optio } } else if (webpackDevServerPkg.version.match(/4\./)) { webpackDevServerConfig = { - ...userWebpackConfig.devServer, + ...userWebpackConfig?.devServer, devMiddleware: { publicPath: devServerPublicPathRoute, }, diff --git a/npm/webpack-dev-server/tsconfig.json b/npm/webpack-dev-server/tsconfig.json index 09386eed1869..78589ed6b22f 100644 --- a/npm/webpack-dev-server/tsconfig.json +++ b/npm/webpack-dev-server/tsconfig.json @@ -24,7 +24,7 @@ // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */ /* Strict Type-Checking Options */ - "strict": false /* Enable all strict type-checking options. */, + "strict": true /* Enable all strict type-checking options. */, // "noImplicitAny": true, /* Module Resolution Options */ diff --git a/yarn.lock b/yarn.lock index 94925340ca52..e4e0c3c8b80a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7819,9 +7819,9 @@ source-map "^0.6.0" "@types/webpack@^4.4.31", "@types/webpack@^4.41.21", "@types/webpack@^4.41.26", "@types/webpack@^4.41.8": - version "4.41.27" - resolved "https://registry.yarnpkg.com/@types/webpack/-/webpack-4.41.27.tgz#f47da488c8037e7f1b2dbf2714fbbacb61ec0ffc" - integrity sha512-wK/oi5gcHi72VMTbOaQ70VcDxSQ1uX8S2tukBK9ARuGXrYM/+u4ou73roc7trXDNmCxCoerE8zruQqX/wuHszA== + version "4.41.28" + resolved "https://registry.yarnpkg.com/@types/webpack/-/webpack-4.41.28.tgz#0069a2159b7ad4d83d0b5801942c17d54133897b" + integrity sha512-Nn84RAiJjKRfPFFCVR8LC4ueTtTdfWAMZ03THIzZWRJB+rX24BD3LqPSFnbMscWauEsT4segAsylPDIaZyZyLQ== dependencies: "@types/anymatch" "*" "@types/node" "*"