diff --git a/.cspell.json b/.cspell.json index 1976882978..4a7bc2be12 100644 --- a/.cspell.json +++ b/.cspell.json @@ -71,7 +71,8 @@ "eslintcache", "hono", "privkey", - "geomanist" + "geomanist", + "nodenext" ], "ignorePaths": [ "CHANGELOG.md", diff --git a/.eslintignore b/.eslintignore deleted file mode 100644 index 9bc9ffb002..0000000000 --- a/.eslintignore +++ /dev/null @@ -1,8 +0,0 @@ -/client -/dist -!/test/client -coverage -node_modules -examples/**/main.js -examples/client/trusted-types-overlay/app.js -test/fixtures/reload-config/foo.js diff --git a/.eslintrc.js b/.eslintrc.js deleted file mode 100644 index 24127cd2b2..0000000000 --- a/.eslintrc.js +++ /dev/null @@ -1,86 +0,0 @@ -"use strict"; - -module.exports = { - extends: ["webpack", "prettier"], - parser: "@babel/eslint-parser", - parserOptions: { - sourceType: "script", - ecmaVersion: 2018, - }, - reportUnusedDisableDirectives: true, - env: { - node: true, - es6: true, - }, - rules: { - curly: "error", - "consistent-return": "off", - "no-param-reassign": "off", - "no-underscore-dangle": "off", - "prefer-destructuring": ["error", { object: false, array: false }], - "prefer-rest-params": "off", - strict: ["error", "safe"], - "global-require": "off", - "spaced-comment": [ - "error", - "always", - { - line: { - exceptions: ["-", "+"], - markers: ["=", "!", "/"], - }, - block: { - exceptions: ["-", "+"], - markers: ["=", "!"], - balanced: false, - }, - }, - ], - }, - overrides: [ - { - files: ["client-src/**/*.js"], - excludedFiles: [ - "client-src/webpack.config.js", - "client-src/modules/logger/SyncBailHookFake.js", - ], - parserOptions: { - sourceType: "module", - allowImportExportEverywhere: true, - }, - env: { - browser: true, - }, - rules: { - "import/extensions": ["error", "always"], - }, - }, - { - files: ["test/**/*.js"], - rules: { - "no-console": "off", - }, - }, - { - files: [ - "test/client/**/*.js", - "test/e2e/**/*.js", - "test/fixtures/**/*.js", - "test/server/liveReload-option.test.js", - ], - env: { - browser: true, - node: true, - }, - }, - { - files: ["examples/**/*.js"], - env: { - browser: true, - }, - rules: { - "no-console": "off", - }, - }, - ], -}; diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS deleted file mode 100644 index 2ee9facf39..0000000000 --- a/.github/CODEOWNERS +++ /dev/null @@ -1 +0,0 @@ -* @alexander-akait @hiroppy @Loonride @snitin315 @anshumanv diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml deleted file mode 100644 index 5e7c7b6d7a..0000000000 --- a/.github/FUNDING.yml +++ /dev/null @@ -1 +0,0 @@ -open_collective: webpack diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md deleted file mode 100644 index 618ed3a8ce..0000000000 --- a/.github/ISSUE_TEMPLATE.md +++ /dev/null @@ -1,51 +0,0 @@ - - - - -- [ ] This is a **bug** -- [ ] This is a **modification** request - -### Code - - - -```js -// webpack.config.js -``` - -```js -// additional code, remove if not needed. -``` - -### Please paste the results of `npx webpack-cli info` here, and mention other relevant information - -### Expected Behavior - -### Actual Behavior - -### For Bugs; How can we reproduce the behavior? - - - -### For Features; What is the motivation and/or use-case for the feature? diff --git a/.github/ISSUE_TEMPLATE/BUG.md b/.github/ISSUE_TEMPLATE/BUG.md deleted file mode 100644 index c5547b6faa..0000000000 --- a/.github/ISSUE_TEMPLATE/BUG.md +++ /dev/null @@ -1,34 +0,0 @@ ---- -name: 🐛 Bug Report -about: Something went awry and you'd like to tell us about it. ---- - - - - -### Bug report - - - - - - -### Actual Behavior - - - -### Expected Behavior - - - - -### How Do We Reproduce? - - - - - - - - -### Please paste the results of `npx webpack-cli info` here, and mention other relevant information diff --git a/.github/ISSUE_TEMPLATE/DOCS.md b/.github/ISSUE_TEMPLATE/DOCS.md deleted file mode 100644 index a94c0c958c..0000000000 --- a/.github/ISSUE_TEMPLATE/DOCS.md +++ /dev/null @@ -1,25 +0,0 @@ ---- -name: 📚 Documentation -about: Are the docs lacking or missing something? Do they need some new 🔥 hotness? Tell us here. ---- - - - - -Documentation Is: - - - -- [ ] Missing -- [ ] Needed -- [ ] Confusing -- [ ] Not Sure? - -### Please Explain in Detail... - - - - - - -### Your Proposal for Changes diff --git a/.github/ISSUE_TEMPLATE/FEATURE.md b/.github/ISSUE_TEMPLATE/FEATURE.md deleted file mode 100644 index 1e5304e1f6..0000000000 --- a/.github/ISSUE_TEMPLATE/FEATURE.md +++ /dev/null @@ -1,18 +0,0 @@ ---- -name: ✨ Feature Request -about: Suggest an idea for this project ---- - - - - -### Feature Proposal - - - - - - -### Feature Use Case - -### Please paste the results of `npx webpack-cli info` here, and mention other relevant information diff --git a/.github/ISSUE_TEMPLATE/MODIFICATION.md b/.github/ISSUE_TEMPLATE/MODIFICATION.md deleted file mode 100644 index c60a5017a9..0000000000 --- a/.github/ISSUE_TEMPLATE/MODIFICATION.md +++ /dev/null @@ -1,20 +0,0 @@ ---- -name: 🔧 Modification Request -about: Would you like something work differently? Have an alternative approach? This is the template for you. ---- - - - - -### Modification Proposal - - - - - - -### Expected Behavior / Situation - -### Actual Behavior / Situation - -### Please paste the results of `npx webpack-cli info` here, and mention other relevant information diff --git a/.github/ISSUE_TEMPLATE/SUPPORT.md b/.github/ISSUE_TEMPLATE/SUPPORT.md deleted file mode 100644 index 49e1c080c3..0000000000 --- a/.github/ISSUE_TEMPLATE/SUPPORT.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -name: 🆘 Support, Help, and Advice -about: 👉🏽 Need support, help, or advice? Don't open an issue! Head to https://github.com/webpack/webpack/discussions or StackOverflow ---- - -Hey there! If you need support, help, or advice then this is not the place to ask. -Please visit [GitHub Discussions](https://github.com/webpack/webpack/discussions) or [StackOverflow](https://stackoverflow.com/questions/tagged/webpack) instead. diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md deleted file mode 100644 index a5e876276c..0000000000 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ /dev/null @@ -1,39 +0,0 @@ - - -- [ ] This is a **bugfix** -- [ ] This is a **feature** -- [ ] This is a **code refactor** -- [ ] This is a **test update** -- [ ] This is a **docs update** -- [ ] This is a **metadata update** - -### For Bugs and Features; did you add new tests? - - - -### Motivation / Use-Case - - - -### Breaking Changes - - - -### Additional Info diff --git a/.github/workflows/nodejs.yml b/.github/workflows/nodejs.yml index 24289f5388..74945cdeb6 100644 --- a/.github/workflows/nodejs.yml +++ b/.github/workflows/nodejs.yml @@ -3,12 +3,12 @@ name: webpack-dev-server on: push: branches: - - master + - main - next - v4 pull_request: branches: - - master + - main - next - v4 diff --git a/CHANGELOG.md b/CHANGELOG.md index 066cd4a0ce..d314e21886 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,17 @@ All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. +### [5.2.3](https://github.com/webpack/webpack-dev-server/compare/v5.2.2...v5.2.3) (2026-01-12) + + +### Bug Fixes + +* add `cause` for `errorObject` ([#5518](https://github.com/webpack/webpack-dev-server/issues/5518)) ([37b033d](https://github.com/webpack/webpack-dev-server/commit/37b033da2c48335178495a1987c469a26ef3de60)) +* compatibility with event target and universal target and lazy compilation ([574026c](https://github.com/webpack/webpack-dev-server/commit/574026c44b9c51f0bbd2f5a2836c54607289a071)) +* **overlay:** add ESC key to dismiss overlay ([#5598](https://github.com/webpack/webpack-dev-server/issues/5598)) ([f91baa8](https://github.com/webpack/webpack-dev-server/commit/f91baa8831e061e2998849966b8002b40b83fb07)) +* progress indicator styles ([#5557](https://github.com/webpack/webpack-dev-server/issues/5557)) ([41a53a1](https://github.com/webpack/webpack-dev-server/commit/41a53a1accdb0a90785d82cbe8a079794eeed3c8)) +* upgrade selfsigned to v5 + ### [5.2.2](https://github.com/webpack/webpack-dev-server/compare/v5.2.1...v5.2.2) (2025-06-03) @@ -88,7 +99,7 @@ The above changes may make the dev server not work if you relied on such behavio ## [5.0.0](https://github.com/webpack/webpack-dev-server/compare/v4.15.1...v5.0.0) (2024-02-12) -[Migration Guide and Changes](https://github.com/webpack/webpack-dev-server/blob/master/migration-v5.md). +[Migration Guide and Changes](https://github.com/webpack/webpack-dev-server/blob/main/migration-v5.md). ### [4.15.1](https://github.com/webpack/webpack-dev-server/compare/v4.15.0...v4.15.1) (2023-06-09) @@ -324,7 +335,7 @@ The above changes may make the dev server not work if you relied on such behavio ### Features * add `--web-socket-server-type` option for CLI ([#4001](https://github.com/webpack/webpack-dev-server/issues/4001)) ([17c390a](https://github.com/webpack/webpack-dev-server/commit/17c390a04e474a675255eb25132b423e0614253f)) -* show deprecation warning for `https`/`http2` option, [migration guide for `https`](https://github.com/webpack/webpack-dev-server/tree/master/examples/server/https) and [migration guide for `http2`](https://github.com/webpack/webpack-dev-server/tree/master/examples/server/spdy) (because we use [`spdy`](https://github.com/spdy-http2/node-spdy) for http2 due `express` doesn't support http2) ([#4003](https://github.com/webpack/webpack-dev-server/issues/4003)) ([521cf85](https://github.com/webpack/webpack-dev-server/commit/521cf852a81c5913e17cf36c90140c566d4218e5)) +* show deprecation warning for `https`/`http2` option, [migration guide for `https`](https://github.com/webpack/webpack-dev-server/tree/main/examples/server/https) and [migration guide for `http2`](https://github.com/webpack/webpack-dev-server/tree/main/examples/server/spdy) (because we use [`spdy`](https://github.com/spdy-http2/node-spdy) for http2 due `express` doesn't support http2) ([#4003](https://github.com/webpack/webpack-dev-server/issues/4003)) ([521cf85](https://github.com/webpack/webpack-dev-server/commit/521cf852a81c5913e17cf36c90140c566d4218e5)) ### Bug Fixes @@ -441,7 +452,7 @@ module.exports = { ## Notes: -- migration guide from v3 to v4 can be found [here](https://github.com/webpack/webpack-dev-server/blob/master/migration-v4.md) +- migration guide from v3 to v4 can be found [here](https://github.com/webpack/webpack-dev-server/blob/main/migration-v4.md) ### Bug Fixes @@ -453,7 +464,7 @@ module.exports = { ## Notes: -- migration guide from v3 to v4 can be found [here](https://github.com/webpack/webpack-dev-server/blob/master/migration-v4.md) +- migration guide from v3 to v4 can be found [here](https://github.com/webpack/webpack-dev-server/blob/main/migration-v4.md) ### Features @@ -475,7 +486,7 @@ module.exports = { ## Notes: -- migration guide from v3 to v4 can be found [here](https://github.com/webpack/webpack-dev-server/blob/master/migration-v4.md) +- migration guide from v3 to v4 can be found [here](https://github.com/webpack/webpack-dev-server/blob/main/migration-v4.md) ### ⚠ BREAKING CHANGES @@ -575,9 +586,9 @@ module.exports = { module.exports = { entry: { entry: [ - 'whatwg-fetch', - 'core-js/features/promise', - './entry.js' + "whatwg-fetch", + "core-js/features/promise", + "./entry.js" ], }, }; @@ -589,13 +600,13 @@ module.exports = { module.exports = { entry: { entry: [ - 'whatwg-fetch', - 'core-js/features/promise', - './entry.js' + "whatwg-fetch", + "core-js/features/promise", + "./entry.js" ], }, devServer: { - transportMode: 'sockjs', + transportMode: "sockjs", }, }; ``` @@ -693,15 +704,15 @@ module.exports = { // static: false static: [ // Simple example - path.resolve(__dirname, 'static'), + path.resolve(__dirname, "static"), // Complex example { - directory: path.resolve(__dirname, 'static'), + directory: path.resolve(__dirname, "static"), staticOptions: {}, // Don't be confused with `dev.publicPath`, it is `publicPath` for static directory // Can be: // publicPath: ['/static-public-path-one/', '/static-public-path-two/'], - publicPath: '/static-public-path/', + publicPath: "/static-public-path/", // Can be: // serveIndex: {} (options for the `serveIndex` option you can find https://github.com/expressjs/serve-index) serveIndex: true, @@ -721,7 +732,7 @@ module.exports = { // ... devServer: { dev: { - publicPath: '/publicPathForDevServe', + publicPath: "/publicPathForDevServe", }, }, }; @@ -751,7 +762,7 @@ module.exports = { // Only warnings and errors // level: 'none' disable logging // Please read https://webpack.js.org/configuration/other-options/#infrastructurelogginglevel - level: 'warn', + level: "warn", }, }; ``` diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 5a355352d7..7adb34b1e9 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -21,7 +21,7 @@ Following these guidelines helps to communicate that you respect the time of the - It is advised to first create an issue (if there is not one already) before making a pull request. This way the maintainers can first discuss with you if they agree and it also helps with providing some context. -- Run the relevant [examples](https://github.com/webpack/webpack-dev-server/tree/master/examples) to see if all functionality still works. When introducing new functionality, also add an example. This helps the maintainers to understand it and check if it still works. +- Run the relevant [examples](https://github.com/webpack/webpack-dev-server/tree/main/examples) to see if all functionality still works. When introducing new functionality, also add an example. This helps the maintainers to understand it and check if it still works. - Write tests. diff --git a/DOCUMENTATION-v4.md b/DOCUMENTATION-v4.md index 183ca01824..61fd73364e 100644 --- a/DOCUMENTATION-v4.md +++ b/DOCUMENTATION-v4.md @@ -1,6 +1,6 @@ [webpack-dev-server](https://github.com/webpack/webpack-dev-server) can be used to quickly develop an application. See the [development guide](/guides/development/) to get started. -This page describes the options that affect the behavior of webpack-dev-server (short: dev-server) `v4.0.0+`. Migration guide from `v3` to `v4` can be found [here](https://github.com/webpack/webpack-dev-server/blob/master/migration-v4.md). +This page describes the options that affect the behavior of webpack-dev-server (short: dev-server) `v4.0.0+`. Migration guide from `v3` to `v4` can be found [here](https://github.com/webpack/webpack-dev-server/blob/main/migration-v4.md). > **Warning** > @@ -15,10 +15,10 @@ This set of options is picked up by [webpack-dev-server](https://github.com/webp **webpack.config.js** ```javascript -const path = require("path"); +const path = require("node:path"); module.exports = { - //... + // ... devServer: { static: { directory: path.join(__dirname, "public"), @@ -41,7 +41,7 @@ When the server is started, there will be a message prior to the list of resolve that will give some background on where the server is located and what it's serving. -If you're using dev-server through the Node.js API, the options in `devServer` will be ignored. Pass the options as the first parameter instead: `new WebpackDevServer({...}, compiler)`. [See here](https://github.com/webpack/webpack-dev-server/tree/master/examples/api/simple) for an example of how to use webpack-dev-server through the Node.js API. +If you're using dev-server through the Node.js API, the options in `devServer` will be ignored. Pass the options as the first parameter instead: `new WebpackDevServer({...}, compiler)`. [See here](https://github.com/webpack/webpack-dev-server/tree/main/examples/api/simple) for an example of how to use webpack-dev-server through the Node.js API. > **Warning** > @@ -71,7 +71,7 @@ You can invoke webpack-dev-server via CLI by: npx webpack serve ``` -A list of CLI options for `serve` is available [here](https://github.com/webpack/webpack-cli/blob/master/SERVE-OPTIONS-v4.md) +A list of CLI options for `serve` is available [here](https://github.com/webpack/webpack-cli/blob/main/SERVE-OPTIONS-v4.md) ### Usage via API @@ -89,7 +89,7 @@ This option allows you to allowlist services that are allowed to access the dev ```javascript module.exports = { - //... + // ... devServer: { allowedHosts: [ "host.com", @@ -107,7 +107,7 @@ Mimicking Django's `ALLOWED_HOSTS`, a value beginning with `.` can be used as a ```javascript module.exports = { - //... + // ... devServer: { // this achieves the same effect as the first example // with the bonus of not having to update your config @@ -129,7 +129,7 @@ When set to `'all'` this option bypasses host checking. **THIS IS NOT RECOMMENDE ```javascript module.exports = { - //... + // ... devServer: { allowedHosts: "all", }, @@ -148,7 +148,7 @@ When set to `'auto'` this option always allows `localhost`, [`host`](#devserverh ```javascript module.exports = { - //... + // ... devServer: { allowedHosts: "auto", }, @@ -171,7 +171,7 @@ This option broadcasts the server via [ZeroConf](http://www.zeroconf.org/) netwo ```javascript module.exports = { - //... + // ... devServer: { bonjour: true, }, @@ -196,7 +196,7 @@ You can also pass [custom options](https://github.com/watson/bonjour#initializin ```javascript module.exports = { - //... + // ... devServer: { bonjour: { type: "http", @@ -218,7 +218,7 @@ Allows to set log level in the browser, e.g. before reloading, before an error o ```javascript module.exports = { - //... + // ... devServer: { client: { logging: "info", @@ -243,7 +243,7 @@ Shows a full-screen overlay in the browser when there are compiler errors or war ```javascript module.exports = { - //... + // ... devServer: { client: { overlay: true, @@ -280,7 +280,7 @@ For example, to disable compilation warnings, you can provide the following conf ```javascript module.exports = { - //... + // ... devServer: { client: { overlay: { @@ -307,7 +307,7 @@ For example, to ignore errors thrown by [`AbortController.abort()`](https://deve ```javascript module.exports = { - //... + // ... devServer: { client: { overlay: { @@ -337,7 +337,7 @@ Prints compilation progress in percentage in the browser. ```javascript module.exports = { - //... + // ... devServer: { client: { progress: true, @@ -370,7 +370,7 @@ Tells dev-server the number of times it should try to reconnect the client. When ```javascript module.exports = { - //... + // ... devServer: { client: { reconnect: true, @@ -389,7 +389,7 @@ When set to `false` it will not try to reconnect. ```javascript module.exports = { - //... + // ... devServer: { client: { reconnect: false, @@ -408,7 +408,7 @@ You can also specify the exact number of times the client should try to reconnec ```javascript module.exports = { - //... + // ... devServer: { client: { reconnect: 5, @@ -437,7 +437,7 @@ This option allows us either to choose the current `devServer` transport mode fo ```javascript module.exports = { - //... + // ... devServer: { client: { webSocketTransport: "ws", @@ -457,7 +457,7 @@ npx webpack serve --client-web-socket-transport ws --web-socket-server ws > > When providing a custom client and server implementation make sure that they are compatible with one another to communicate successfully. -To create a custom client implementation, create a class that extends [`BaseClient`](https://github.com/webpack/webpack-dev-server/blob/master/client-src/clients/BaseClient.js). +To create a custom client implementation, create a class that extends [`BaseClient`](https://github.com/webpack/webpack-dev-server/blob/main/client-src/clients/BaseClient.js). Using path to `CustomClient.js`, a custom WebSocket client implementation, along with the compatible `'ws'` server: @@ -465,7 +465,7 @@ Using path to `CustomClient.js`, a custom WebSocket client implementation, along ```javascript module.exports = { - //... + // ... devServer: { client: { webSocketTransport: require.resolve("./CustomClient"), @@ -481,7 +481,7 @@ Using custom, compatible WebSocket client and server implementations: ```javascript module.exports = { - //... + // ... devServer: { client: { webSocketTransport: require.resolve("./CustomClient"), @@ -501,7 +501,7 @@ This option allows specifying URL to web socket server (useful when you're proxy ```javascript module.exports = { - //... + // ... devServer: { client: { webSocketURL: "ws://0.0.0.0:8080/ws", @@ -529,7 +529,7 @@ You can also specify an object with the following properties: ```javascript module.exports = { - //... + // ... devServer: { client: { webSocketURL: { @@ -559,7 +559,7 @@ Enable [gzip compression](https://betterexplained.com/articles/how-to-optimize-y ```javascript module.exports = { - //... + // ... devServer: { compress: true, }, @@ -612,7 +612,7 @@ HTTP/2 with a self-signed certificate: ```javascript module.exports = { - //... + // ... devServer: { http2: true, }, @@ -636,10 +636,10 @@ Provide your own certificate using the [https](#devserverhttps) option: **webpack.config.js** ```javascript -const fs = require("fs"); +const fs = require("node:fs"); module.exports = { - //... + // ... devServer: { http2: true, https: { @@ -671,7 +671,7 @@ By default, dev-server will be served over `HTTP`. It can optionally be served o ```javascript module.exports = { - //... + // ... devServer: { https: true, }, @@ -722,8 +722,8 @@ npx webpack serve --https-request-cert --https-key ./path/to/server.key --https- **webpack.config.js** ```javascript -const fs = require("fs"); -const path = require("path"); +const fs = require("node:fs"); +const path = require("node:path"); module.exports = { devServer: { @@ -758,7 +758,7 @@ Adds headers to all responses: ```javascript module.exports = { - //... + // ... devServer: { headers: { "X-Custom-Foo": "bar", @@ -773,7 +773,7 @@ You can also pass an array: ```javascript module.exports = { - //... + // ... devServer: { headers: [ { @@ -793,11 +793,9 @@ You can also pass a function: ```javascript module.exports = { - //... + // ... devServer: { - headers: () => { - return { "X-Bar": ["key1=value1", "key2=value2"] }; - }, + headers: () => ({ "X-Bar": ["key1=value1", "key2=value2"] }), }, }; ``` @@ -812,7 +810,7 @@ When using the [HTML5 History API](https://developer.mozilla.org/en-US/docs/Web/ ```javascript module.exports = { - //... + // ... devServer: { historyApiFallback: true, }, @@ -837,7 +835,7 @@ By providing an object this behavior can be controlled further using options lik ```javascript module.exports = { - //... + // ... devServer: { historyApiFallback: { rewrites: [ @@ -856,7 +854,7 @@ When using dots in your path (common with Angular), you may need to use the `dis ```javascript module.exports = { - //... + // ... devServer: { historyApiFallback: { disableDotRule: true, @@ -877,7 +875,7 @@ Specify a host to use. If you want your server to be accessible externally, spec ```javascript module.exports = { - //... + // ... devServer: { host: "0.0.0.0", }, @@ -930,7 +928,7 @@ Enable webpack's [Hot Module Replacement](/concepts/hot-module-replacement/) fea ```javascript module.exports = { - //... + // ... devServer: { hot: true, }, @@ -955,7 +953,7 @@ To enable Hot Module Replacement without page refresh as a fallback in case of b ```javascript module.exports = { - //... + // ... devServer: { hot: "only", }, @@ -984,7 +982,7 @@ Setting it to `true` will listen to a socket at `/your-os-temp-dir/webpack-dev-s ```javascript module.exports = { - //... + // ... devServer: { ipc: true, }, @@ -1002,10 +1000,10 @@ You can also listen to a different socket with: **webpack.config.js** ```javascript -const path = require("path"); +const path = require("node:path"); module.exports = { - //... + // ... devServer: { ipc: path.join(__dirname, "my-socket.sock"), }, @@ -1022,7 +1020,7 @@ By default, the dev-server will reload/refresh the page when file changes are de ```javascript module.exports = { - //... + // ... devServer: { liveReload: false, }, @@ -1057,7 +1055,7 @@ Tell dev-server to enable/disable magic HTML routes (routes corresponding to you ```javascript module.exports = { - //... + // ... devServer: { magicHtml: true, }, @@ -1087,14 +1085,14 @@ internally within the server. ```javascript module.exports = { - //... + // ... devServer: { - onAfterSetupMiddleware: function (devServer) { + onAfterSetupMiddleware(devServer) { if (!devServer) { throw new Error("webpack-dev-server is not defined"); } - devServer.app.get("/some/path", function (req, res) { + devServer.app.get("/some/path", (req, res) => { res.json({ custom: "response" }); }); }, @@ -1118,14 +1116,14 @@ example: ```javascript module.exports = { - //... + // ... devServer: { - onBeforeSetupMiddleware: function (devServer) { + onBeforeSetupMiddleware(devServer) { if (!devServer) { throw new Error("webpack-dev-server is not defined"); } - devServer.app.get("/some/path", function (req, res) { + devServer.app.get("/some/path", (req, res) => { res.json({ custom: "response" }); }); }, @@ -1147,14 +1145,14 @@ Provides the ability to execute a custom function when webpack-dev-server starts ```javascript module.exports = { - //... + // ... devServer: { - onListening: function (devServer) { + onListening(devServer) { if (!devServer) { throw new Error("webpack-dev-server is not defined"); } - const port = devServer.server.address().port; + const { port } = devServer.server.address(); console.log("Listening on port:", port); }, }, @@ -1171,7 +1169,7 @@ Tells dev-server to open the browser after server had been started. Set it to `t ```javascript module.exports = { - //... + // ... devServer: { open: true, }, @@ -1196,7 +1194,7 @@ To open a specified page in a browser: ```javascript module.exports = { - //... + // ... devServer: { open: ["/my-page"], }, @@ -1215,7 +1213,7 @@ To open multiple specified pages in browser: ```javascript module.exports = { - //... + // ... devServer: { open: ["/my-page", "/another-page"], }, @@ -1234,7 +1232,7 @@ Provide browser name to use instead of the default one: ```javascript module.exports = { - //... + // ... devServer: { open: { app: { @@ -1257,7 +1255,7 @@ The object accepts all [open](https://www.npmjs.com/package/open) options: ```javascript module.exports = { - //... + // ... devServer: { open: { target: ["first.html", "http://localhost:8080/second.html"], @@ -1284,7 +1282,7 @@ Specify a port number to listen for requests on: ```javascript module.exports = { - //... + // ... devServer: { port: 8080, }, @@ -1303,7 +1301,7 @@ npx webpack serve --port 8080 ```javascript module.exports = { - //... + // ... devServer: { port: "auto", }, @@ -1330,7 +1328,7 @@ With a backend on `localhost:3000`, you can use this to enable proxying: ```javascript module.exports = { - //... + // ... devServer: { proxy: { "/api": "http://localhost:3000", @@ -1347,7 +1345,7 @@ If you don't want `/api` to be passed along, we need to rewrite the path: ```javascript module.exports = { - //... + // ... devServer: { proxy: { "/api": { @@ -1365,7 +1363,7 @@ A backend server running on HTTPS with an invalid certificate will not be accept ```javascript module.exports = { - //... + // ... devServer: { proxy: { "/api": { @@ -1391,13 +1389,13 @@ E.g. for a browser request, you want to serve an HTML page, but for an API reque ```javascript module.exports = { - //... + // ... devServer: { proxy: { "/api": { target: "http://localhost:3000", - bypass: function (req, res, proxyOptions) { - if (req.headers.accept.indexOf("html") !== -1) { + bypass(req, res, proxyOptions) { + if (req.headers.accept.includes("html")) { console.log("Skipping proxy for browser request."); return "/index.html"; } @@ -1414,7 +1412,7 @@ If you want to proxy multiple, specific paths to the same target, you can use an ```javascript module.exports = { - //... + // ... devServer: { proxy: [ { @@ -1432,7 +1430,7 @@ Note that requests to root won't be proxied by default. To enable root proxying, ```javascript module.exports = { - //... + // ... devServer: { devMiddleware: { index: false, // specify to enable root proxying @@ -1451,7 +1449,7 @@ The origin of the host header is kept when proxying by default, you can set `cha ```javascript module.exports = { - //... + // ... devServer: { proxy: { "/api": { @@ -1475,7 +1473,7 @@ Allows to set server and options (by default 'http'). ```javascript module.exports = { - //... + // ... devServer: { server: "http", }, @@ -1494,7 +1492,7 @@ To serve over `HTTPS` with a self-signed certificate: ```javascript module.exports = { - //... + // ... devServer: { server: "https", }, @@ -1513,7 +1511,7 @@ To serve over `HTTP/2` using [spdy](https://www.npmjs.com/package/spdy) with a s ```javascript module.exports = { - //... + // ... devServer: { server: "spdy", }, @@ -1536,7 +1534,7 @@ Use the object syntax to provide your own certificate: ```javascript module.exports = { - //... + // ... devServer: { server: { type: "https", @@ -1564,11 +1562,11 @@ It also allows you to set additional [TLS options](https://nodejs.org/api/tls.ht **webpack.config.js** ```javascript -const fs = require("fs"); -const path = require("path"); +const fs = require("node:fs"); +const path = require("node:path"); module.exports = { - //... + // ... devServer: { server: { type: "https", @@ -1600,7 +1598,7 @@ Allows to close dev server and exit the process on `SIGINT` and `SIGTERM` signal ```javascript module.exports = { - //... + // ... devServer: { setupExitSignals: true, }, @@ -1672,7 +1670,7 @@ This option allows configuring options for serving static files from the directo ```javascript module.exports = { - //... + // ... devServer: { static: false, }, @@ -1738,10 +1736,10 @@ Tell the server where to serve the content from. This is only necessary if you w **webpack.config.js** ```javascript -const path = require("path"); +const path = require("node:path"); module.exports = { - //... + // ... devServer: { static: { directory: path.join(__dirname, "public"), @@ -1755,10 +1753,10 @@ Provide an array of objects in case you have multiple static folders: **webpack.config.js** ```javascript -const path = require("path"); +const path = require("node:path"); module.exports = { - //... + // ... devServer: { static: [ { @@ -1786,7 +1784,7 @@ It is possible to configure advanced options for serving static files from [`sta ```javascript module.exports = { - //... + // ... devServer: { static: { staticOptions: { @@ -1806,10 +1804,10 @@ Tell the server at which URL to serve [`static.directory`](#directory) content. **webpack.config.js** ```javascript -const path = require("path"); +const path = require("node:path"); module.exports = { - //... + // ... devServer: { static: { directory: path.join(__dirname, "assets"), @@ -1824,10 +1822,10 @@ Provide an array of objects in case you have multiple static folders: **webpack.config.js** ```javascript -const path = require("path"); +const path = require("node:path"); module.exports = { - //... + // ... devServer: { static: [ { @@ -1854,10 +1852,10 @@ Tell dev-server to use [`serveIndex`](https://github.com/expressjs/serve-index) **webpack.config.js** ```javascript -const path = require("path"); +const path = require("node:path"); module.exports = { - //... + // ... devServer: { static: { directory: path.join(__dirname, "public"), @@ -1888,10 +1886,10 @@ Tell dev-server to watch the files served by the [`static.directory`](#directory **webpack.config.js** ```javascript -const path = require("path"); +const path = require("node:path"); module.exports = { - //... + // ... devServer: { static: { directory: path.join(__dirname, "public"), @@ -1918,10 +1916,10 @@ It is possible to configure advanced options for watching static files from [`st **webpack.config.js** ```javascript -const path = require("path"); +const path = require("node:path"); module.exports = { - //... + // ... devServer: { static: { directory: path.join(__dirname, "public"), @@ -1944,7 +1942,7 @@ This option allows you to configure a list of globs/directories/files to watch f ```javascript module.exports = { - //... + // ... devServer: { watchFiles: ["src/**/*.php", "public/**/*"], }, @@ -1957,7 +1955,7 @@ It is possible to configure advanced options for watching files. See the [`choki ```javascript module.exports = { - //... + // ... devServer: { watchFiles: { paths: ["src/**/*.php", "public/**/*"], @@ -1981,14 +1979,14 @@ The current default mode is `'ws'`. This mode uses [`ws`](https://www.npmjs.com/ ```javascript module.exports = { - //... + // ... devServer: { webSocketServer: "ws", }, }; ``` -To create a custom server implementation, create a class that extends [`BaseServer`](https://github.com/webpack/webpack-dev-server/blob/master/lib/servers/BaseServer.js). +To create a custom server implementation, create a class that extends [`BaseServer`](https://github.com/webpack/webpack-dev-server/blob/main/lib/servers/BaseServer.js). Using path to `CustomServer.js`, a custom WebSocket server implementation, along with the compatible `'ws'` client: @@ -1996,7 +1994,7 @@ Using path to `CustomServer.js`, a custom WebSocket server implementation, along ```javascript module.exports = { - //... + // ... devServer: { client: { webSocketTransport: "ws", @@ -2012,7 +2010,7 @@ Using custom, compatible WebSocket client and server implementations: ```javascript module.exports = { - //... + // ... devServer: { client: { webSocketTransport: require.resolve("./CustomClient"), diff --git a/README.md b/README.md index e8ceea5f5f..ca701218bf 100644 --- a/README.md +++ b/README.md @@ -229,7 +229,7 @@ If you use TypeScript in the webpack config, you'll need to properly type `devSe ```ts /// -import type { Configuration } from "webpack"; +import { type Configuration } from "webpack"; // Your logic ``` @@ -237,8 +237,8 @@ import type { Configuration } from "webpack"; Or you can import the type from `webpack-dev-server`, i.e. ```ts -import type { Configuration as DevServerConfiguration } from "webpack-dev-server"; -import type { Configuration } from "webpack"; +import { type Configuration } from "webpack"; +import { type Configuration as DevServerConfiguration } from "webpack-dev-server"; const devServer: DevServerConfiguration = {}; const config: Configuration = { devServer }; @@ -311,7 +311,7 @@ This project is heavily inspired by [peerigon/nof5](https://github.com/peerigon/ [node-url]: https://nodejs.org [tests]: https://github.com/webpack/webpack-dev-server/workflows/webpack-dev-server/badge.svg [tests-url]: https://github.com/webpack/webpack-dev-server/actions?query=workflow%3Awebpack-dev-server -[cover]: https://codecov.io/gh/webpack/webpack-dev-server/branch/master/graph/badge.svg +[cover]: https://codecov.io/gh/webpack/webpack-dev-server/graph/badge.svg [cover-url]: https://codecov.io/gh/webpack/webpack-dev-server [discussion]: https://img.shields.io/github/discussions/webpack/webpack [discussion-url]: https://github.com/webpack/webpack/discussions diff --git a/bin/webpack-dev-server.js b/bin/webpack-dev-server.js index 7effdca89f..de0cfd3b32 100755 --- a/bin/webpack-dev-server.js +++ b/bin/webpack-dev-server.js @@ -10,7 +10,8 @@ * @returns {Promise} promise */ const runCommand = (command, args) => { - const cp = require("child_process"); + const cp = require("node:child_process"); + return new Promise((resolve, reject) => { const executedCommand = cp.spawn(command, args, { stdio: "inherit", @@ -40,7 +41,7 @@ const isInstalled = (packageName) => { return true; } - const path = require("path"); + const path = require("node:path"); const fs = require("graceful-fs"); let dir = __dirname; @@ -52,20 +53,19 @@ const isInstalled = (packageName) => { ) { return true; } - } catch (_error) { + } catch { // Nothing } - // eslint-disable-next-line no-cond-assign } while (dir !== (dir = path.dirname(dir))); // https://github.com/nodejs/node/blob/v18.9.1/lib/internal/modules/cjs/loader.js#L1274 - // @ts-ignore - for (const internalPath of require("module").globalPaths) { + // @ts-expect-error + for (const internalPath of require("node:module").globalPaths) { try { if (fs.statSync(path.join(internalPath, packageName)).isDirectory()) { return true; } - } catch (_error) { + } catch { // Nothing } } @@ -81,9 +81,11 @@ const runCli = (cli) => { if (cli.preprocess) { cli.preprocess(); } - const path = require("path"); + + const path = require("node:path"); + const pkgPath = require.resolve(`${cli.package}/package.json`); - // eslint-disable-next-line import/no-dynamic-require + const pkg = require(pkgPath); if (pkg.type === "module" || /\.mjs/i.test(pkg.bin[cli.binName])) { @@ -94,19 +96,18 @@ const runCli = (cli) => { }, ); } else { - // eslint-disable-next-line import/no-dynamic-require require(path.resolve(path.dirname(pkgPath), pkg.bin[cli.binName])); } }; /** - * @typedef {Object} CliOption + * @typedef {object} CliOption * @property {string} name display name * @property {string} package npm package name * @property {string} binName name of the executable file * @property {boolean} installed currently installed? * @property {string} url homepage - * @property {function} preprocess preprocessor + * @property {() => void} preprocess preprocessor */ /** @type {CliOption} */ @@ -122,9 +123,9 @@ const cli = { }; if (!cli.installed) { - const path = require("path"); + const path = require("node:path"); const fs = require("graceful-fs"); - const readLine = require("readline"); + const readLine = require("node:readline"); const notify = `CLI for webpack must be installed.\n ${cli.name} (${cli.url})\n`; @@ -151,7 +152,7 @@ if (!cli.installed) { )} ${cli.package}".`, ); - const question = `Do you want to install 'webpack-cli' (yes/no): `; + const question = "Do you want to install 'webpack-cli' (yes/no): "; const questionInterface = readLine.createInterface({ input: process.stdin, @@ -185,7 +186,7 @@ if (!cli.installed) { }')...`, ); - runCommand(packageManager, installOptions.concat(cli.package)) + runCommand(packageManager, [...installOptions, cli.package]) .then(() => { runCli(cli); }) diff --git a/client-src/clients/SockJSClient.js b/client-src/clients/SockJSClient.js index 4efcafd0c4..cd9d67ad48 100644 --- a/client-src/clients/SockJSClient.js +++ b/client-src/clients/SockJSClient.js @@ -1,49 +1,46 @@ import SockJS from "../modules/sockjs-client/index.js"; import { log } from "../utils/log.js"; +/** @typedef {import("../index").EXPECTED_ANY} EXPECTED_ANY */ + +/** + * @implements {CommunicationClient} + */ export default class SockJSClient { /** - * @param {string} url + * @param {string} url url */ constructor(url) { // SockJS requires `http` and `https` protocols this.sock = new SockJS( url.replace(/^ws:/i, "http:").replace(/^wss:/i, "https:"), ); - this.sock.onerror = - /** - * @param {Error} error - */ - (error) => { - log.error(error); - }; + this.sock.onerror = (error) => { + log.error(error); + }; } /** - * @param {(...args: any[]) => void} f + * @param {(...args: EXPECTED_ANY[]) => void} fn function */ - onOpen(f) { - this.sock.onopen = f; + onOpen(fn) { + this.sock.onopen = fn; } /** - * @param {(...args: any[]) => void} f + * @param {(...args: EXPECTED_ANY[]) => void} fn function */ - onClose(f) { - this.sock.onclose = f; + onClose(fn) { + this.sock.onclose = fn; } // call f with the message string as the first argument /** - * @param {(...args: any[]) => void} f + * @param {(...args: EXPECTED_ANY[]) => void} fn function */ - onMessage(f) { - this.sock.onmessage = - /** - * @param {Error & { data: string }} e - */ - (e) => { - f(e.data); - }; + onMessage(fn) { + this.sock.onmessage = (err) => { + fn(err.data); + }; } } diff --git a/client-src/clients/WebSocketClient.js b/client-src/clients/WebSocketClient.js index cdbd94f360..de7e0ea6a1 100644 --- a/client-src/clients/WebSocketClient.js +++ b/client-src/clients/WebSocketClient.js @@ -1,8 +1,13 @@ import { log } from "../utils/log.js"; +/** @typedef {import("../index").EXPECTED_ANY} EXPECTED_ANY */ + +/** + * @implements {CommunicationClient} + */ export default class WebSocketClient { /** - * @param {string} url + * @param {string} url url to connect */ constructor(url) { this.client = new WebSocket(url); @@ -12,26 +17,26 @@ export default class WebSocketClient { } /** - * @param {(...args: any[]) => void} f + * @param {(...args: EXPECTED_ANY[]) => void} fn function */ - onOpen(f) { - this.client.onopen = f; + onOpen(fn) { + this.client.onopen = fn; } /** - * @param {(...args: any[]) => void} f + * @param {(...args: EXPECTED_ANY[]) => void} fn function */ - onClose(f) { - this.client.onclose = f; + onClose(fn) { + this.client.onclose = fn; } // call f with the message string as the first argument /** - * @param {(...args: any[]) => void} f + * @param {(...args: EXPECTED_ANY[]) => void} fn function */ - onMessage(f) { - this.client.onmessage = (e) => { - f(e.data); + onMessage(fn) { + this.client.onmessage = (err) => { + fn(err.data); }; } } diff --git a/client-src/globals.d.ts b/client-src/globals.d.ts new file mode 100644 index 0000000000..a6aeff9c99 --- /dev/null +++ b/client-src/globals.d.ts @@ -0,0 +1,24 @@ +declare interface CommunicationClient { + onOpen(fn: (...args: any[]) => void): void; + onClose(fn: (...args: any[]) => void): void; + onMessage(fn: (...args: any[]) => void): void; +} + +declare interface CommunicationClientConstructor { + new (url: string): CommunicationClient; // Defines a constructor that takes a string and returns a GreeterInstance +} + +declare const __webpack_dev_server_client__: + | CommunicationClientConstructor + | { default: CommunicationClientConstructor } + | undefined; + +declare module "ansi-html-community" { + function ansiHtmlCommunity(str: string): string; + + namespace ansiHtmlCommunity { + function setColors(colors: Record): void; + } + + export = ansiHtmlCommunity; +} diff --git a/client-src/index.js b/client-src/index.js index c9ea5d1233..60527ef029 100644 --- a/client-src/index.js +++ b/client-src/index.js @@ -1,57 +1,80 @@ /* global __resourceQuery, __webpack_hash__ */ -/// -import webpackHotLog from "webpack/hot/log.js"; +// @ts-expect-error import hotEmitter from "webpack/hot/emitter.js"; +// @ts-expect-error +import webpackHotLog from "webpack/hot/log.js"; +import { createOverlay, formatProblem } from "./overlay.js"; +import { defineProgressElement, isProgressSupported } from "./progress.js"; import socket from "./socket.js"; -import { formatProblem, createOverlay } from "./overlay.js"; import { log, setLogLevel } from "./utils/log.js"; import sendMessage from "./utils/sendMessage.js"; -import { isProgressSupported, defineProgressElement } from "./progress.js"; + +// eslint-disable-next-line jsdoc/no-restricted-syntax +/** @typedef {any} EXPECTED_ANY */ /** - * @typedef {Object} OverlayOptions - * @property {boolean | (error: Error) => boolean} [warnings] - * @property {boolean | (error: Error) => boolean} [errors] - * @property {boolean | (error: Error) => boolean} [runtimeErrors] - * @property {string} [trustedTypesPolicyName] + * @typedef {object} RawOverlayOptions + * @property {string=} warnings warnings + * @property {string=} errors errors + * @property {string=} runtimeErrors runtime errors + * @property {string=} trustedTypesPolicyName trusted types policy name */ /** - * @typedef {Object} Options - * @property {boolean} hot - * @property {boolean} liveReload - * @property {boolean} progress - * @property {boolean | OverlayOptions} overlay - * @property {string} [logging] - * @property {number} [reconnect] + * @typedef {object} OverlayOptions + * @property {(boolean | ((error: Error) => boolean))=} warnings warnings + * @property {(boolean | ((error: Error) => boolean))=} errors errors + * @property {(boolean | ((error: Error) => boolean))=} runtimeErrors runtime errors + * @property {string=} trustedTypesPolicyName trusted types policy name */ +/** @typedef {false | true | "none" | "error" | "warn" | "info" | "log" | "verbose"} LogLevel */ + /** - * @typedef {Object} Status - * @property {boolean} isUnloading - * @property {string} currentHash - * @property {string} [previousHash] + * @typedef {object} Options + * @property {boolean} hot true when hot enabled, otherwise false + * @property {boolean} liveReload true when live reload enabled, otherwise false + * @property {boolean} progress true when need to show progress, otherwise false + * @property {boolean | OverlayOptions} overlay overlay options + * @property {LogLevel=} logging logging level + * @property {number=} reconnect count of allowed reconnection */ /** - * @param {boolean | { warnings?: boolean | string; errors?: boolean | string; runtimeErrors?: boolean | string; }} overlayOptions + * @typedef {object} Status + * @property {boolean} isUnloading true when unloaded, otherwise false + * @property {string} currentHash current hash + * @property {string=} previousHash previous hash + */ + +/** + * @param {boolean | RawOverlayOptions | OverlayOptions} overlayOptions overlay options */ const decodeOverlayOptions = (overlayOptions) => { if (typeof overlayOptions === "object") { - ["warnings", "errors", "runtimeErrors"].forEach((property) => { + const requiredOptions = ["warnings", "errors", "runtimeErrors"]; + + for (let i = 0; i < requiredOptions.length; i++) { + const property = + /** @type {keyof Omit} */ + (requiredOptions[i]); + if (typeof overlayOptions[property] === "string") { const overlayFilterFunctionString = decodeURIComponent( overlayOptions[property], ); - // eslint-disable-next-line no-new-func - overlayOptions[property] = new Function( - "message", - `var callback = ${overlayFilterFunctionString} + /** @type {OverlayOptions} */ + (overlayOptions)[property] = /** @type {(error: Error) => boolean} */ ( + // eslint-disable-next-line no-new-func + new Function( + "message", + `var callback = ${overlayFilterFunctionString} return callback(message)`, + ) ); } - }); + } } }; @@ -60,18 +83,17 @@ const decodeOverlayOptions = (overlayOptions) => { */ const status = { isUnloading: false, - // eslint-disable-next-line camelcase currentHash: __webpack_hash__, }; /** - * @returns {string} + * @returns {string} current script source */ const getCurrentScriptSource = () => { // `document.currentScript` is the most accurate way to find the current script, // but is not supported in all browsers. if (document.currentScript) { - return document.currentScript.getAttribute("src"); + return /** @type {string} */ (document.currentScript.getAttribute("src")); } // Fallback to getting all scripts running in the document. @@ -92,12 +114,15 @@ const getCurrentScriptSource = () => { throw new Error("[webpack-dev-server] Failed to get current script source."); }; +/** @typedef {{ hot?: string, ["live-reload"]?: string, progress?: string, reconnect?: string, logging?: LogLevel, overlay?: string, fromCurrentScript?: boolean }} AdditionalParsedURL */ +/** @typedef {Partial & AdditionalParsedURL} ParsedURL */ + /** - * @param {string} resourceQuery - * @returns {{ [key: string]: string | boolean }} + * @param {string} resourceQuery resource query + * @returns {ParsedURL} parsed URL */ const parseURL = (resourceQuery) => { - /** @type {{ [key: string]: string }} */ + /** @type {ParsedURL} */ let result = {}; if (typeof resourceQuery === "string" && resourceQuery !== "") { @@ -106,7 +131,8 @@ const parseURL = (resourceQuery) => { for (let i = 0; i < searchParams.length; i++) { const pair = searchParams[i].split("="); - result[pair[0]] = decodeURIComponent(pair[1]); + /** @type {EXPECTED_ANY} */ + (result)[pair[0]] = decodeURIComponent(pair[1]); } } else { // Else, get the url from the ', - ), - ).toBe(true); + expect(text).toContain( + '', + ); expect(consoleMessages.map((message) => message.text())).toEqual([ "[webpack-dev-server] Server started: Hot Module Replacement enabled, Live Reloading enabled, Progress disabled, Overlay enabled.", "[HMR] Waiting for update signal from WDS...", diff --git a/test/e2e/bonjour.test.js b/test/e2e/bonjour.test.js index e0911f14b5..5f2bc90aab 100644 --- a/test/e2e/bonjour.test.js +++ b/test/e2e/bonjour.test.js @@ -1,6 +1,6 @@ "use strict"; -const os = require("os"); +const os = require("node:os"); const webpack = require("webpack"); const Server = require("../../lib/Server"); const config = require("../fixtures/simple-config/webpack.config"); @@ -29,17 +29,13 @@ describe("bonjour option", () => { let consoleMessages; beforeEach(async () => { - jest.mock("bonjour-service", () => { - return { - Bonjour: jest.fn().mockImplementation(() => { - return { - publish: mockPublish, - unpublishAll: mockUnpublishAll, - destroy: mockDestroy, - }; - }), - }; - }); + jest.mock("bonjour-service", () => ({ + Bonjour: jest.fn().mockImplementation(() => ({ + publish: mockPublish, + unpublishAll: mockUnpublishAll, + destroy: mockDestroy, + })), + })); compiler = webpack(config); @@ -106,17 +102,13 @@ describe("bonjour option", () => { let consoleMessages; beforeEach(async () => { - jest.mock("bonjour-service", () => { - return { - Bonjour: jest.fn().mockImplementation(() => { - return { - publish: mockPublish, - unpublishAll: mockUnpublishAll, - destroy: mockDestroy, - }; - }), - }; - }); + jest.mock("bonjour-service", () => ({ + Bonjour: jest.fn().mockImplementation(() => ({ + publish: mockPublish, + unpublishAll: mockUnpublishAll, + destroy: mockDestroy, + })), + })); compiler = webpack(config); @@ -179,17 +171,13 @@ describe("bonjour option", () => { let consoleMessages; beforeEach(async () => { - jest.mock("bonjour-service", () => { - return { - Bonjour: jest.fn().mockImplementation(() => { - return { - publish: mockPublish, - unpublishAll: mockUnpublishAll, - destroy: mockDestroy, - }; - }), - }; - }); + jest.mock("bonjour-service", () => ({ + Bonjour: jest.fn().mockImplementation(() => ({ + publish: mockPublish, + unpublishAll: mockUnpublishAll, + destroy: mockDestroy, + })), + })); compiler = webpack(config); @@ -262,17 +250,13 @@ describe("bonjour option", () => { let consoleMessages; beforeEach(async () => { - jest.mock("bonjour-service", () => { - return { - Bonjour: jest.fn().mockImplementation(() => { - return { - publish: mockPublish, - unpublishAll: mockUnpublishAll, - destroy: mockDestroy, - }; - }), - }; - }); + jest.mock("bonjour-service", () => ({ + Bonjour: jest.fn().mockImplementation(() => ({ + publish: mockPublish, + unpublishAll: mockUnpublishAll, + destroy: mockDestroy, + })), + })); compiler = webpack(config); diff --git a/test/e2e/built-in-routes.test.js b/test/e2e/built-in-routes.test.js index d5dd08f212..faab99f224 100644 --- a/test/e2e/built-in-routes.test.js +++ b/test/e2e/built-in-routes.test.js @@ -112,7 +112,7 @@ describe("Built in routes", () => { }, ); - expect(response.headers()["content-type"]).not.toEqual("text/html"); + expect(response.headers()["content-type"]).not.toBe("text/html"); expect(response.status()).toMatchSnapshot("response status"); diff --git a/test/e2e/client-reconnect.test.js b/test/e2e/client-reconnect.test.js index 1269743c74..eff831783d 100644 --- a/test/e2e/client-reconnect.test.js +++ b/test/e2e/client-reconnect.test.js @@ -47,8 +47,6 @@ describe("client.reconnect option", () => { try { expect(response.status()).toMatchSnapshot("response status"); - } catch (error) { - throw error; } finally { await server.stop(); } @@ -113,22 +111,19 @@ describe("client.reconnect option", () => { try { expect(response.status()).toMatchSnapshot("response status"); - } catch (error) { - throw error; } finally { await server.stop(); } // Can't wait to check for unlimited times so wait only for couple retries - await new Promise((resolve) => + await new Promise((resolve) => { setTimeout( () => { resolve(); }, - // eslint-disable-next-line no-restricted-properties - 1000 * Math.pow(2, 3), - ), - ); + 1000 * 2 ** 3, + ); + }); expect(consoleMessages.map((message) => message.text())).toMatchSnapshot( "console messages", @@ -178,22 +173,19 @@ describe("client.reconnect option", () => { try { expect(response.status()).toMatchSnapshot("response status"); - } catch (error) { - throw error; } finally { await server.stop(); } // Can't wait to check for unlimited times so wait only for couple retries - await new Promise((resolve) => + await new Promise((resolve) => { setTimeout( () => { resolve(); }, - // eslint-disable-next-line no-restricted-properties - 1000 * Math.pow(2, 3), - ), - ); + 1000 * 2 ** 3, + ); + }); expect(consoleMessages.map((message) => message.text())).toMatchSnapshot( "console messages", diff --git a/test/e2e/client.test.js b/test/e2e/client.test.js index bd8b24e4b4..335ca39648 100644 --- a/test/e2e/client.test.js +++ b/test/e2e/client.test.js @@ -200,13 +200,12 @@ describe("client option", () => { let browser; class OverrideServer extends Server { - // eslint-disable-next-line class-methods-use-this getClientEntry() { return require.resolve( "../fixtures/custom-client/CustomClientEntry.js", ); } - // eslint-disable-next-line class-methods-use-this + getClientHotEntry() { return require.resolve( "../fixtures/custom-client/CustomClientHotEntry.js", @@ -304,7 +303,7 @@ describe("client option", () => { ]; describe("passed to server", () => { - clientModes.forEach((data) => { + for (const data of clientModes) { it(`${data.title} ${ data.shouldThrow ? "should throw" : "should not throw" }`, async () => { @@ -334,7 +333,7 @@ describe("client option", () => { await server.stop(); }); - }); + } }); }); }); diff --git a/test/e2e/cross-origin-request.test.js b/test/e2e/cross-origin-request.test.js index 65de9cf3f2..d003024928 100644 --- a/test/e2e/cross-origin-request.test.js +++ b/test/e2e/cross-origin-request.test.js @@ -22,7 +22,8 @@ describe("cross-origin requests", () => { await server.start(); // Start a separate server for serving the HTML file - const http = require("http"); + const http = require("node:http"); + const htmlServer = http.createServer((req, res) => { res.writeHead(200, { "Content-Type": "text/html" }); res.end(` @@ -54,8 +55,6 @@ describe("cross-origin requests", () => { const response = await scriptTagRequest; expect(response.status()).toBe(403); - } catch (error) { - throw error; } finally { await browser.close(); await server.stop(); @@ -77,7 +76,8 @@ describe("cross-origin requests", () => { await server.start(); // Start a separate server for serving the HTML file - const http = require("http"); + const http = require("node:http"); + const htmlServer = http.createServer((req, res) => { res.writeHead(200, { "Content-Type": "text/html" }); res.end(` @@ -109,8 +109,6 @@ describe("cross-origin requests", () => { const response = await scriptTagRequest; expect(response.status()).toBe(200); - } catch (error) { - throw error; } finally { await browser.close(); await server.stop(); @@ -129,7 +127,8 @@ describe("cross-origin requests", () => { await server.start(); // Start a separate server for serving the HTML file - const http = require("http"); + const http = require("node:http"); + const htmlServer = http.createServer((req, res) => { res.writeHead(200, { "Content-Type": "text/html" }); res.end(` @@ -161,8 +160,6 @@ describe("cross-origin requests", () => { const response = await scriptTagRequest; expect(response.status()).toBe(200); - } catch (error) { - throw error; } finally { await browser.close(); await server.stop(); @@ -181,7 +178,8 @@ describe("cross-origin requests", () => { await server.start(); // Start a separate server for serving the HTML file - const http = require("http"); + const http = require("node:http"); + const htmlServer = http.createServer((req, res) => { res.writeHead(200, { "Content-Type": "text/html" }); res.end(` @@ -213,8 +211,6 @@ describe("cross-origin requests", () => { const response = await scriptTagRequest; expect(response.status()).toBe(200); - } catch (error) { - throw error; } finally { await browser.close(); await server.stop(); diff --git a/test/e2e/entry.test.js b/test/e2e/entry.test.js index ff07fbc01a..311d87c333 100644 --- a/test/e2e/entry.test.js +++ b/test/e2e/entry.test.js @@ -1,6 +1,6 @@ "use strict"; -const path = require("path"); +const path = require("node:path"); const webpack = require("webpack"); const Server = require("../../lib/Server"); const config = require("../fixtures/client-config/webpack.config"); @@ -63,8 +63,6 @@ describe("entry", () => { "console messages", ); expect(pageErrors).toMatchSnapshot("page errors"); - } catch (error) { - throw error; } finally { await browser.close(); await server.stop(); @@ -102,8 +100,6 @@ describe("entry", () => { "console messages", ); expect(pageErrors).toMatchSnapshot("page errors"); - } catch (error) { - throw error; } finally { await browser.close(); await server.stop(); @@ -146,8 +142,6 @@ describe("entry", () => { "console messages", ); expect(pageErrors).toMatchSnapshot("page errors"); - } catch (error) { - throw error; } finally { await browser.close(); await server.stop(); @@ -185,8 +179,6 @@ describe("entry", () => { "console messages", ); expect(pageErrors).toMatchSnapshot("page errors"); - } catch (error) { - throw error; } finally { await browser.close(); await server.stop(); @@ -196,7 +188,10 @@ describe("entry", () => { it("should work with dynamic async entry", async () => { const compiler = webpack({ ...config, - entry: () => new Promise((resolve) => resolve([entryFirst])), + entry: () => + new Promise((resolve) => { + resolve([entryFirst]); + }), }); const devServerOptions = { port, @@ -227,8 +222,6 @@ describe("entry", () => { "console messages", ); expect(pageErrors).toMatchSnapshot("page errors"); - } catch (error) { - throw error; } finally { await browser.close(); await server.stop(); @@ -278,8 +271,6 @@ describe("entry", () => { expect(consoleMessages).toMatchSnapshot("console messages"); expect(pageErrors).toMatchSnapshot("page errors"); - } catch (error) { - throw error; } finally { await browser.close(); await server.stop(); @@ -329,8 +320,6 @@ describe("entry", () => { expect(consoleMessages).toMatchSnapshot("console messages"); expect(pageErrors).toMatchSnapshot("page errors"); - } catch (error) { - throw error; } finally { await browser.close(); await server.stop(); @@ -378,8 +367,6 @@ describe("entry", () => { expect(consoleMessages).toMatchSnapshot("console messages"); expect(pageErrors).toMatchSnapshot("page errors"); - } catch (error) { - throw error; } finally { await browser.close(); await server.stop(); @@ -425,8 +412,6 @@ describe("entry", () => { "console messages", ); expect(pageErrors).toMatchSnapshot("page errors"); - } catch (error) { - throw error; } finally { await browser.close(); await server.stop(); diff --git a/test/e2e/headers.test.js b/test/e2e/headers.test.js index d176cc7730..efaddab452 100644 --- a/test/e2e/headers.test.js +++ b/test/e2e/headers.test.js @@ -1,7 +1,7 @@ "use strict"; -const webpack = require("webpack"); const request = require("supertest"); +const webpack = require("webpack"); const Server = require("../../lib/Server"); const config = require("../fixtures/simple-config/webpack.config"); const runBrowser = require("../helpers/run-browser"); @@ -211,9 +211,7 @@ describe("headers option", () => { server = new Server( { - headers: () => { - return { "X-Bar": ["key1=value1", "key2=value2"] }; - }, + headers: () => ({ "X-Bar": ["key1=value1", "key2=value2"] }), port, }, compiler, @@ -450,7 +448,7 @@ describe("headers option", () => { ); expect(pageErrors).toMatchSnapshot("page errors"); - const responseForHead = await req.get(`/`); + const responseForHead = await req.get("/"); expect(responseForHead.headers["x-foo"]).toBe("dev-server headers"); }); diff --git a/test/e2e/history-api-fallback.test.js b/test/e2e/history-api-fallback.test.js index cf8874189d..b6506e85af 100644 --- a/test/e2e/history-api-fallback.test.js +++ b/test/e2e/history-api-fallback.test.js @@ -1,11 +1,11 @@ "use strict"; -const path = require("path"); +const path = require("node:path"); const webpack = require("webpack"); const Server = require("../../lib/Server"); -const config = require("../fixtures/historyapifallback-config/webpack.config"); const config2 = require("../fixtures/historyapifallback-2-config/webpack.config"); const config3 = require("../fixtures/historyapifallback-3-config/webpack.config"); +const config = require("../fixtures/historyapifallback-config/webpack.config"); const runBrowser = require("../helpers/run-browser"); const port = require("../ports-map")["history-api-fallback-option"]; @@ -438,7 +438,7 @@ describe("historyApiFallback option", () => { let consoleSpy; beforeEach(async () => { - consoleSpy = jest.spyOn(global.console, "log"); + consoleSpy = jest.spyOn(globalThis.console, "log"); compiler = webpack(config); @@ -514,7 +514,7 @@ describe("historyApiFallback option", () => { let consoleSpy; beforeEach(async () => { - consoleSpy = jest.spyOn(global.console, "log"); + consoleSpy = jest.spyOn(globalThis.console, "log"); compiler = webpack(config); diff --git a/test/e2e/host.test.js b/test/e2e/host.test.js index 227e298b37..fe79392ca4 100644 --- a/test/e2e/host.test.js +++ b/test/e2e/host.test.js @@ -1,6 +1,6 @@ "use strict"; -const http = require("http"); +const http = require("node:http"); const webpack = require("webpack"); const Server = require("../../lib/Server"); const config = require("../fixtures/client-config/webpack.config"); @@ -58,7 +58,7 @@ async function getAddress(host, hostname) { describe("host", () => { const hosts = [ "", - // eslint-disable-next-line no-undefined + undefined, "0.0.0.0", "::", @@ -139,8 +139,6 @@ describe("host", () => { ).toMatchSnapshot("console messages"); expect(pageErrors).toMatchSnapshot("page errors"); - } catch (error) { - throw error; } finally { await browser.close(); await server.stop(); @@ -215,8 +213,6 @@ describe("host", () => { ).toMatchSnapshot("console messages"); expect(pageErrors).toMatchSnapshot("page errors"); - } catch (error) { - throw error; } finally { await browser.close(); await server.stop(); @@ -295,8 +291,6 @@ describe("host", () => { ).toMatchSnapshot("console messages"); expect(pageErrors).toMatchSnapshot("page errors"); - } catch (error) { - throw error; } finally { delete process.env.WEBPACK_DEV_SERVER_BASE_PORT; @@ -307,6 +301,7 @@ describe("host", () => { } // TODO need test on error + // eslint-disable-next-line jest/no-commented-out-tests // it(`should throw an error on invalid host`, async () => { // const compiler = webpack(config); // const server = new Server({ port, host: "unknown.unknown" }, compiler); diff --git a/test/e2e/hot-and-live-reload.test.js b/test/e2e/hot-and-live-reload.test.js index c53694e60b..32e1f9dcb3 100644 --- a/test/e2e/hot-and-live-reload.test.js +++ b/test/e2e/hot-and-live-reload.test.js @@ -4,18 +4,18 @@ "use strict"; -const path = require("path"); -const WebSocket = require("ws"); +const path = require("node:path"); +const fs = require("graceful-fs"); const SockJS = require("sockjs-client"); const webpack = require("webpack"); -const fs = require("graceful-fs"); +const WebSocket = require("ws"); const Server = require("../../lib/Server"); -const HTMLGeneratorPlugin = require("../helpers/html-generator-plugin"); +const config = require("../fixtures/client-config/webpack.config"); +const multiCompilerConfig = require("../fixtures/multi-compiler-one-configuration/webpack.config"); const reloadConfig = require("../fixtures/reload-config/webpack.config"); +const HTMLGeneratorPlugin = require("../helpers/html-generator-plugin"); const runBrowser = require("../helpers/run-browser"); const port = require("../ports-map")["hot-and-live-reload"]; -const config = require("../fixtures/client-config/webpack.config"); -const multiCompilerConfig = require("../fixtures/multi-compiler-one-configuration/webpack.config"); const cssFilePath = path.resolve( __dirname, @@ -326,12 +326,13 @@ describe("hot and live reload", () => { fs.unlinkSync(cssFilePath); }); - modes.forEach((mode) => { + for (const mode of modes) { const webSocketServerTitle = mode.options && mode.options.webSocketServer ? mode.options.webSocketServer : "default"; + // eslint-disable-next-line no-loop-func it(`${mode.title} (${webSocketServerTitle})`, async () => { const webpackOptions = { ...reloadConfig, ...mode.webpackOptions }; const compiler = webpack(webpackOptions); @@ -367,12 +368,8 @@ describe("hot and live reload", () => { let received = false; let errored = false; - ws.on("error", (error) => { - if (!webSocketServerLaunched && /404/.test(error)) { - errored = true; - } else { - errored = true; - } + ws.on("error", (_error) => { + errored = true; ws.close(); }); @@ -439,7 +436,7 @@ describe("hot and live reload", () => { ({ browser } = launched); - const page = launched.page; + const { page } = launched; const consoleMessages = []; const pageErrors = []; @@ -470,12 +467,12 @@ describe("hot and live reload", () => { }); const backgroundColorBefore = await page.evaluate(() => { - const body = document.body; + const { body } = document; return getComputedStyle(body)["background-color"]; }); - expect(backgroundColorBefore).toEqual("rgb(0, 0, 255)"); + expect(backgroundColorBefore).toBe("rgb(0, 0, 255)"); fs.writeFileSync( cssFilePath, @@ -555,21 +552,21 @@ describe("hot and live reload", () => { } const backgroundColorAfter = await page.evaluate(() => { - const body = document.body; + const { body } = document; return getComputedStyle(body)["background-color"]; }); if (!waitHot && !waitLiveReload) { - expect(backgroundColorAfter).toEqual("rgb(0, 0, 255)"); + expect(backgroundColorAfter).toBe("rgb(0, 0, 255)"); } else { - expect(backgroundColorAfter).toEqual("rgb(255, 0, 0)"); + expect(backgroundColorAfter).toBe("rgb(255, 0, 0)"); } expect(consoleMessages).toMatchSnapshot("console messages"); expect(pageErrors).toMatchSnapshot("page errors"); }); - }); + } }); // the following cases check to make sure that the HMR @@ -722,13 +719,11 @@ describe("simple config with already added HMR plugin", () => { getInfrastructureLoggerSpy = jest .spyOn(compiler, "getInfrastructureLogger") - .mockImplementation(() => { - return { - warn: loggerWarnSpy, - info: () => {}, - log: () => {}, - }; - }); + .mockImplementation(() => ({ + warn: loggerWarnSpy, + info: () => {}, + log: () => {}, + })); }); afterEach(() => { @@ -742,31 +737,31 @@ describe("simple config with already added HMR plugin", () => { await server.start(); expect(loggerWarnSpy).toHaveBeenCalledWith( - `"hot: true" automatically applies HMR plugin, you don't have to add it manually to your webpack configuration.`, + '"hot: true" automatically applies HMR plugin, you don\'t have to add it manually to your webpack configuration.', ); await server.stop(); }); - it(`should show warning with "hot: true"`, async () => { + it('should show warning with "hot: true"', async () => { server = new Server({ port, hot: true }, compiler); await server.start(); expect(loggerWarnSpy).toHaveBeenCalledWith( - `"hot: true" automatically applies HMR plugin, you don't have to add it manually to your webpack configuration.`, + '"hot: true" automatically applies HMR plugin, you don\'t have to add it manually to your webpack configuration.', ); await server.stop(); }); - it(`should not show warning with "hot: false"`, async () => { + it('should not show warning with "hot: false"', async () => { server = new Server({ port, hot: false }, compiler); await server.start(); expect(loggerWarnSpy).not.toHaveBeenCalledWith( - `"hot: true" automatically applies HMR plugin, you don't have to add it manually to your webpack configuration.`, + '"hot: true" automatically applies HMR plugin, you don\'t have to add it manually to your webpack configuration.', ); await server.stop(); diff --git a/test/e2e/ipc.test.js b/test/e2e/ipc.test.js index a29f7acf2e..735b0e652f 100644 --- a/test/e2e/ipc.test.js +++ b/test/e2e/ipc.test.js @@ -1,11 +1,11 @@ "use strict"; -const os = require("os"); -const net = require("net"); -const path = require("path"); -const http = require("http"); -const webpack = require("webpack"); +const http = require("node:http"); +const net = require("node:net"); +const os = require("node:os"); +const path = require("node:path"); const httpProxy = require("http-proxy"); +const webpack = require("webpack"); const Server = require("../../lib/Server"); const config = require("../fixtures/client-config/webpack.config"); const runBrowser = require("../helpers/run-browser"); @@ -98,7 +98,7 @@ describe("web socket server URL", () => { waitUntil: "networkidle0", }); - const webSocketRequest = webSocketRequests[0]; + const [webSocketRequest] = webSocketRequests; expect(webSocketRequest.url).toContain( `${websocketURLProtocol}://${devServerHost}:${proxyPort}/ws`, @@ -107,8 +107,6 @@ describe("web socket server URL", () => { consoleMessages.map((message) => message.text()), ).toMatchSnapshot("console messages"); expect(pageErrors).toMatchSnapshot("page errors"); - } catch (error) { - throw error; } finally { proxy.close(); @@ -202,7 +200,7 @@ describe("web socket server URL", () => { waitUntil: "networkidle0", }); - const webSocketRequest = webSocketRequests[0]; + const [webSocketRequest] = webSocketRequests; expect(webSocketRequest.url).toContain( `${websocketURLProtocol}://${devServerHost}:${proxyPort}/ws`, @@ -211,8 +209,6 @@ describe("web socket server URL", () => { consoleMessages.map((message) => message.text()), ).toMatchSnapshot("console messages"); expect(pageErrors).toMatchSnapshot("page errors"); - } catch (error) { - throw error; } finally { proxy.close(); @@ -222,6 +218,7 @@ describe("web socket server URL", () => { }); // TODO un skip after implement new API + // eslint-disable-next-line jest/no-disabled-tests it.skip(`should work with the "ipc" option using "string" value and remove old ("${webSocketServer}")`, async () => { const isWindows = process.platform === "win32"; const localRelative = path.relative(process.cwd(), `${os.tmpdir()}/`); @@ -230,12 +227,14 @@ describe("web socket server URL", () => { const ipc = path.join(pipePrefix, pipeName); const ipcServer = await new Promise((resolve, reject) => { + // eslint-disable-next-line new-cap const server = net.Server(); server.on("error", (error) => { reject(error); }); + // eslint-disable-next-line no-promise-executor-return return server.listen(ipc, () => { resolve(); }); @@ -321,7 +320,7 @@ describe("web socket server URL", () => { waitUntil: "networkidle0", }); - const webSocketRequest = webSocketRequests[0]; + const [webSocketRequest] = webSocketRequests; expect(webSocketRequest.url).toContain( `${websocketURLProtocol}://${devServerHost}:${proxyPort}/ws`, @@ -330,8 +329,6 @@ describe("web socket server URL", () => { consoleMessages.map((message) => message.text()), ).toMatchSnapshot("console messages"); expect(pageErrors).toMatchSnapshot("page errors"); - } catch (error) { - throw error; } finally { proxy.close(); diff --git a/test/e2e/lazy-compilation.test.js b/test/e2e/lazy-compilation.test.js index e3c2db45f9..8bb5390fa5 100644 --- a/test/e2e/lazy-compilation.test.js +++ b/test/e2e/lazy-compilation.test.js @@ -2,14 +2,15 @@ const webpack = require("webpack"); const Server = require("../../lib/Server"); -const lazyCompilationSingleEntryConfig = require("../fixtures/lazy-compilation-single-entry/webpack.config"); const lazyCompilationMultipleEntriesConfig = require("../fixtures/lazy-compilation-multiple-entries/webpack.config"); +const lazyCompilationSingleEntryConfig = require("../fixtures/lazy-compilation-single-entry/webpack.config"); const runBrowser = require("../helpers/run-browser"); const port = require("../ports-map")["lazy-compilation"]; +/* eslint-disable jest/no-disabled-tests */ describe("lazy compilation", () => { // TODO jest freeze due webpack do not close `eventsource`, we should uncomment this after fix it on webpack side - it.skip(`should work with single entry`, async () => { + it.skip("should work with single entry", async () => { const compiler = webpack(lazyCompilationSingleEntryConfig); const server = new Server({ port }, compiler); @@ -44,15 +45,13 @@ describe("lazy compilation", () => { expect(consoleMessages).toMatchSnapshot("console messages"); expect(pageErrors).toMatchSnapshot("page errors"); - } catch (error) { - throw error; } finally { await browser.close(); await server.stop(); } }); - it.skip(`should work with multiple entries`, async () => { + it.skip("should work with multiple entries", async () => { const compiler = webpack(lazyCompilationMultipleEntriesConfig); const server = new Server({ port }, compiler); @@ -102,8 +101,6 @@ describe("lazy compilation", () => { expect(consoleMessages).toMatchSnapshot("console messages"); expect(pageErrors).toMatchSnapshot("page errors"); - } catch (error) { - throw error; } finally { await browser.close(); await server.stop(); diff --git a/test/e2e/logging.test.js b/test/e2e/logging.test.js index 7a709c1da8..b00d2fa783 100644 --- a/test/e2e/logging.test.js +++ b/test/e2e/logging.test.js @@ -1,11 +1,11 @@ "use strict"; -const path = require("path"); +const path = require("node:path"); const fs = require("graceful-fs"); const webpack = require("webpack"); const Server = require("../../lib/Server"); -const HTMLGeneratorPlugin = require("../helpers/html-generator-plugin"); const config = require("../fixtures/client-config/webpack.config"); +const HTMLGeneratorPlugin = require("../helpers/html-generator-plugin"); const runBrowser = require("../helpers/run-browser"); const port = require("../ports-map").logging; @@ -188,8 +188,8 @@ describe("logging", () => { }, ]; - webSocketServers.forEach((webSocketServer) => { - cases.forEach((testCase) => { + for (const webSocketServer of webSocketServers) { + for (const testCase of cases) { it(`${testCase.title} (${ webSocketServer.webSocketServer || "default" })`, async () => { @@ -230,20 +230,18 @@ describe("logging", () => { consoleMessages.map((message) => message .text() - .replace(/\\/g, "/") - .replace( - new RegExp(process.cwd().replace(/\\/g, "/"), "g"), + .replaceAll("\\", "/") + .replaceAll( + new RegExp(process.cwd().replaceAll("\\", "/"), "g"), "", ), ), ).toMatchSnapshot(); - } catch (error) { - throw error; } finally { await browser.close(); await server.stop(); } }); - }); - }); + } + } }); diff --git a/test/e2e/module-federation.test.js b/test/e2e/module-federation.test.js index 3bbf7a9e4a..f1fa63144f 100644 --- a/test/e2e/module-federation.test.js +++ b/test/e2e/module-federation.test.js @@ -1,14 +1,14 @@ "use strict"; -const webpack = require("webpack"); const requireFromString = require("require-from-string"); +const webpack = require("webpack"); const Server = require("../../lib/Server"); const simpleConfig = require("../fixtures/module-federation-config/webpack.config"); -const objectEntryConfig = require("../fixtures/module-federation-config/webpack.object-entry.config"); const multiConfig = require("../fixtures/module-federation-config/webpack.multi.config"); +const objectEntryConfig = require("../fixtures/module-federation-config/webpack.object-entry.config"); +const pluginConfig = require("../fixtures/module-federation-config/webpack.plugin"); const runBrowser = require("../helpers/run-browser"); const port = require("../ports-map")["module-federation"]; -const pluginConfig = require("../fixtures/module-federation-config/webpack.plugin"); describe("Module federation", () => { describe("should work with simple multi-entry config", () => { @@ -59,7 +59,7 @@ describe("Module federation", () => { exports = requireFromString(textContent); }).not.toThrow(); - expect(exports).toEqual("entry2"); + expect(exports).toBe("entry2"); expect(consoleMessages.map((message) => message.text())).toMatchSnapshot( "console messages", @@ -117,7 +117,7 @@ describe("Module federation", () => { exports = requireFromString(textContent); }).not.toThrow(); - expect(exports).toEqual("entry2"); + expect(exports).toBe("entry2"); expect(consoleMessages.map((message) => message.text())).toMatchSnapshot( "console messages", @@ -149,7 +149,7 @@ describe("Module federation", () => { exports = requireFromString(textContent); }).not.toThrow(); - expect(exports).toEqual("entry1"); + expect(exports).toBe("entry1"); expect(consoleMessages.map((message) => message.text())).toMatchSnapshot( "console messages", @@ -207,7 +207,7 @@ describe("Module federation", () => { exports = requireFromString(textContent); }).not.toThrow(); - expect(exports).toEqual("entry2"); + expect(exports).toBe("entry2"); expect(consoleMessages.map((message) => message.text())).toMatchSnapshot( "console messages", diff --git a/test/e2e/multi-compiler.test.js b/test/e2e/multi-compiler.test.js index 6142094f93..73879d5323 100644 --- a/test/e2e/multi-compiler.test.js +++ b/test/e2e/multi-compiler.test.js @@ -1,6 +1,6 @@ "use strict"; -const path = require("path"); +const path = require("node:path"); const fs = require("graceful-fs"); const webpack = require("webpack"); const Server = require("../../lib/Server"); @@ -11,7 +11,7 @@ const runBrowser = require("../helpers/run-browser"); const port = require("../ports-map")["multi-compiler"]; describe("multi compiler", () => { - it(`should work with one web target configuration and do nothing`, async () => { + it("should work with one web target configuration and do nothing", async () => { const compiler = webpack(oneWebTargetConfiguration); const devServerOptions = { port, @@ -40,15 +40,13 @@ describe("multi compiler", () => { expect(consoleMessages).toMatchSnapshot("console messages"); expect(pageErrors).toMatchSnapshot("page errors"); - } catch (error) { - throw error; } finally { await browser.close(); await server.stop(); } }); - it(`should work with web target configurations and do nothing`, async () => { + it("should work with web target configurations and do nothing", async () => { const compiler = webpack(twoWebTargetConfiguration); const devServerOptions = { port, @@ -88,15 +86,13 @@ describe("multi compiler", () => { expect(consoleMessages).toMatchSnapshot("console messages"); expect(pageErrors).toMatchSnapshot("page errors"); - } catch (error) { - throw error; } finally { await browser.close(); await server.stop(); } }); - it(`should work with web target configurations when hot and live reloads are enabled, and do hot reload by default when changing own entries`, async () => { + it("should work with web target configurations when hot and live reloads are enabled, and do hot reload by default when changing own entries", async () => { const compiler = webpack(twoWebTargetConfiguration); const devServerOptions = { port, @@ -164,8 +160,6 @@ describe("multi compiler", () => { expect(consoleMessages).toMatchSnapshot("console messages"); expect(pageErrors).toMatchSnapshot("page errors"); - } catch (error) { - throw error; } finally { await browser.close(); await server.stop(); @@ -175,7 +169,7 @@ describe("multi compiler", () => { } }); - it(`should work with web target configurations when only hot reload is enabled, and do hot reload when changing own entries`, async () => { + it("should work with web target configurations when only hot reload is enabled, and do hot reload when changing own entries", async () => { const compiler = webpack(twoWebTargetConfiguration); const devServerOptions = { port, @@ -243,8 +237,6 @@ describe("multi compiler", () => { expect(consoleMessages).toMatchSnapshot("console messages"); expect(pageErrors).toMatchSnapshot("page errors"); - } catch (error) { - throw error; } finally { await browser.close(); await server.stop(); @@ -254,7 +246,7 @@ describe("multi compiler", () => { } }); - it(`should work with web target configurations when only live reload is enabled, and do live reload when changing own entries`, async () => { + it("should work with web target configurations when only live reload is enabled, and do live reload when changing own entries", async () => { const compiler = webpack(twoWebTargetConfiguration); const devServerOptions = { port, @@ -314,8 +306,6 @@ describe("multi compiler", () => { expect(consoleMessages).toMatchSnapshot("console messages"); expect(pageErrors).toMatchSnapshot("page errors"); - } catch (error) { - throw error; } finally { await browser.close(); await server.stop(); @@ -325,7 +315,7 @@ describe("multi compiler", () => { } }); - it(`should work with web target configurations when only live reload is enabled and do live reload when changing other entries`, async () => { + it("should work with web target configurations when only live reload is enabled and do live reload when changing other entries", async () => { const compiler = webpack(twoWebTargetConfiguration); const devServerOptions = { port, @@ -385,8 +375,6 @@ describe("multi compiler", () => { expect(consoleMessages).toMatchSnapshot("console messages"); expect(pageErrors).toMatchSnapshot("page errors"); - } catch (error) { - throw error; } finally { await browser.close(); await server.stop(); @@ -433,8 +421,6 @@ describe("multi compiler", () => { await page.goto(`http://localhost:${port}/browser.html`, { waitUntil: "networkidle0", }); - } catch (error) { - throw error; } finally { await browser.close(); await server.stop(); @@ -444,7 +430,7 @@ describe("multi compiler", () => { expect(pageErrors).toMatchSnapshot("page errors"); }); - it(`should work with universal configuration when hot and live reloads are enabled, and do hot reload for browser compiler by default when browser entry changed`, async () => { + it("should work with universal configuration when hot and live reloads are enabled, and do hot reload for browser compiler by default when browser entry changed", async () => { const compiler = webpack(universalConfiguration); const devServerOptions = { port, @@ -513,8 +499,6 @@ describe("multi compiler", () => { expect(consoleMessages).toMatchSnapshot("console messages"); expect(pageErrors).toMatchSnapshot("page errors"); - } catch (error) { - throw error; } finally { await browser.close(); await server.stop(); @@ -524,7 +508,7 @@ describe("multi compiler", () => { } }); - it(`should work with universal configuration when only hot reload is enabled, and do hot reload for browser compiler when browser entry changed`, async () => { + it("should work with universal configuration when only hot reload is enabled, and do hot reload for browser compiler when browser entry changed", async () => { const compiler = webpack(universalConfiguration); const devServerOptions = { port, @@ -588,8 +572,6 @@ describe("multi compiler", () => { expect(consoleMessages).toMatchSnapshot("console messages"); expect(pageErrors).toMatchSnapshot("page errors"); - } catch (error) { - throw error; } finally { await browser.close(); await server.stop(); @@ -598,7 +580,7 @@ describe("multi compiler", () => { } }); - it(`should work with universal configuration when only live reload is enabled, and do live reload for browser compiler when changing browser and server entries`, async () => { + it("should work with universal configuration when only live reload is enabled, and do live reload for browser compiler when changing browser and server entries", async () => { const compiler = webpack(universalConfiguration); const devServerOptions = { port, @@ -676,8 +658,6 @@ describe("multi compiler", () => { expect(consoleMessages).toMatchSnapshot("console messages"); expect(pageErrors).toMatchSnapshot("page errors"); - } catch (error) { - throw error; } finally { await browser.close(); await server.stop(); @@ -687,7 +667,7 @@ describe("multi compiler", () => { } }); - it(`should work with universal configuration when only live reload is enabled, and do live reload for browser compiler when changing server and browser entries`, async () => { + it("should work with universal configuration when only live reload is enabled, and do live reload for browser compiler when changing server and browser entries", async () => { const compiler = webpack(universalConfiguration); const devServerOptions = { port, @@ -765,8 +745,6 @@ describe("multi compiler", () => { expect(consoleMessages).toMatchSnapshot("console messages"); expect(pageErrors).toMatchSnapshot("page errors"); - } catch (error) { - throw error; } finally { await browser.close(); await server.stop(); diff --git a/test/e2e/options-middleware.test.js b/test/e2e/options-middleware.test.js index 9f8f2cef2f..1bc05cd64b 100644 --- a/test/e2e/options-middleware.test.js +++ b/test/e2e/options-middleware.test.js @@ -1,7 +1,7 @@ "use strict"; -const webpack = require("webpack"); const Express = require("express"); +const webpack = require("webpack"); const Server = require("../../lib/Server"); const config = require("../fixtures/client-config/webpack.config"); const runBrowser = require("../helpers/run-browser"); @@ -84,7 +84,7 @@ describe("handle options-request correctly", () => { await page.evaluate( (url) => - window.fetch(url, { + globalThis.fetch(url, { headers: { "another-header": "1", }, @@ -93,8 +93,6 @@ describe("handle options-request correctly", () => { ); expect(responseStatus.sort()).toEqual([200, 204]); - } catch (error) { - throw error; } finally { await browser.close(); await server.stop(); diff --git a/test/e2e/overlay.test.js b/test/e2e/overlay.test.js index 023b9a331a..be3c059233 100644 --- a/test/e2e/overlay.test.js +++ b/test/e2e/overlay.test.js @@ -1,12 +1,12 @@ "use strict"; -const path = require("path"); +const path = require("node:path"); const fs = require("graceful-fs"); -const webpack = require("webpack"); const waitForExpect = require("wait-for-expect"); +const webpack = require("webpack"); const Server = require("../../lib/Server"); -const config = require("../fixtures/overlay-config/webpack.config"); const trustedTypesConfig = require("../fixtures/overlay-config/trusted-types.webpack.config"); +const config = require("../fixtures/overlay-config/webpack.config"); const runBrowser = require("../helpers/run-browser"); const port = require("../ports-map").overlay; @@ -63,7 +63,10 @@ class WarningPlugin { } } -const delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms)); +const delay = (ms) => + new Promise((resolve) => { + setTimeout(resolve, ms); + }); let prettier; let prettierHTML; @@ -119,8 +122,6 @@ describe("overlay", () => { plugins: [prettierHTML, prettierCSS], }), ).toMatchSnapshot("overlay html"); - } catch (error) { - throw error; } finally { await browser.close(); await server.stop(); @@ -168,8 +169,6 @@ describe("overlay", () => { plugins: [prettierHTML, prettierCSS], }), ).toMatchSnapshot("overlay html"); - } catch (error) { - throw error; } finally { await browser.close(); await server.stop(); @@ -221,8 +220,6 @@ describe("overlay", () => { plugins: [prettierHTML, prettierCSS], }), ).toMatchSnapshot("overlay html"); - } catch (error) { - throw error; } finally { await browser.close(); await server.stop(); @@ -272,8 +269,6 @@ describe("overlay", () => { plugins: [prettierHTML, prettierCSS], }), ).toMatchSnapshot("overlay html"); - } catch (error) { - throw error; } finally { await browser.close(); await server.stop(); @@ -322,8 +317,6 @@ describe("overlay", () => { plugins: [prettierHTML, prettierCSS], }), ).toMatchSnapshot("overlay html"); - } catch (error) { - throw error; } finally { await browser.close(); await server.stop(); @@ -349,7 +342,7 @@ describe("overlay", () => { let pageHtml = await page.evaluate(() => document.body.outerHTML); let overlayHandle = await page.$("#webpack-dev-server-client-overlay"); - expect(overlayHandle).toBe(null); + expect(overlayHandle).toBeNull(); expect( await prettier.format(pageHtml, { parser: "html", @@ -397,15 +390,13 @@ describe("overlay", () => { pageHtml = await page.evaluate(() => document.body.outerHTML); overlayHandle = await page.$("#webpack-dev-server-client-overlay"); - expect(overlayHandle).toBe(null); + expect(overlayHandle).toBeNull(); expect( await prettier.format(pageHtml, { parser: "html", plugins: [prettierHTML, prettierCSS], }), ).toMatchSnapshot("page html after fix error"); - } catch (error) { - throw error; } finally { await browser.close(); await server.stop(); @@ -431,7 +422,7 @@ describe("overlay", () => { let pageHtml = await page.evaluate(() => document.body.outerHTML); let overlayHandle = await page.$("#webpack-dev-server-client-overlay"); - expect(overlayHandle).toBe(null); + expect(overlayHandle).toBeNull(); expect( await prettier.format(pageHtml, { parser: "html", @@ -505,15 +496,13 @@ describe("overlay", () => { pageHtml = await page.evaluate(() => document.body.outerHTML); overlayHandle = await page.$("#webpack-dev-server-client-overlay"); - expect(overlayHandle).toBe(null); + expect(overlayHandle).toBeNull(); expect( await prettier.format(pageHtml, { parser: "html", plugins: [prettierHTML, prettierCSS], }), ).toMatchSnapshot("page html after fix error"); - } catch (error) { - throw error; } finally { await browser.close(); await server.stop(); @@ -539,7 +528,7 @@ describe("overlay", () => { let pageHtml = await page.evaluate(() => document.body.outerHTML); let overlayHandle = await page.$("#webpack-dev-server-client-overlay"); - expect(overlayHandle).toBe(null); + expect(overlayHandle).toBeNull(); expect( await prettier.format(pageHtml, { parser: "html", @@ -593,7 +582,7 @@ describe("overlay", () => { pageHtml = await page.evaluate(() => document.body.outerHTML); overlayHandle = await page.$("#webpack-dev-server-client-overlay"); - expect(overlayHandle).toBe(null); + expect(overlayHandle).toBeNull(); expect( await prettier.format(pageHtml, { parser: "html", @@ -602,8 +591,6 @@ describe("overlay", () => { ).toMatchSnapshot("page html after close"); fs.writeFileSync(pathToFile, originalCode); - } catch (error) { - throw error; } finally { await browser.close(); await server.stop(); @@ -652,8 +639,6 @@ describe("overlay", () => { }); fs.writeFileSync(pathToFile, originalCode); - } catch (error) { - throw error; } finally { await browser.close(); await server.stop(); @@ -688,15 +673,13 @@ describe("overlay", () => { const pageHtml = await page.evaluate(() => document.body.outerHTML); const overlayHandle = await page.$("#webpack-dev-server-client-overlay"); - expect(overlayHandle).toBe(null); + expect(overlayHandle).toBeNull(); expect( await prettier.format(pageHtml, { parser: "html", plugins: [prettierHTML, prettierCSS], }), ).toMatchSnapshot("page html"); - } catch (error) { - throw error; } finally { await browser.close(); await server.stop(); @@ -733,15 +716,13 @@ describe("overlay", () => { const pageHtml = await page.evaluate(() => document.body.outerHTML); const overlayHandle = await page.$("#webpack-dev-server-client-overlay"); - expect(overlayHandle).toBe(null); + expect(overlayHandle).toBeNull(); expect( await prettier.format(pageHtml, { parser: "html", plugins: [prettierHTML, prettierCSS], }), ).toMatchSnapshot("page html"); - } catch (error) { - throw error; } finally { await browser.close(); await server.stop(); @@ -783,9 +764,7 @@ describe("overlay", () => { const overlayHandle = await page.$("#webpack-dev-server-client-overlay"); - expect(overlayHandle).toBe(null); - } catch (error) { - throw error; + expect(overlayHandle).toBeNull(); } finally { await browser.close(); await server.stop(); @@ -840,8 +819,6 @@ describe("overlay", () => { plugins: [prettierHTML, prettierCSS], }), ).toMatchSnapshot("overlay html"); - } catch (error) { - throw error; } finally { await browser.close(); await server.stop(); @@ -892,8 +869,6 @@ describe("overlay", () => { plugins: [prettierHTML, prettierCSS], }), ).toMatchSnapshot("overlay html"); - } catch (error) { - throw error; } finally { await browser.close(); await server.stop(); @@ -946,8 +921,6 @@ describe("overlay", () => { plugins: [prettierHTML, prettierCSS], }), ).toMatchSnapshot("overlay html"); - } catch (error) { - throw error; } finally { await browser.close(); await server.stop(); @@ -1000,8 +973,6 @@ describe("overlay", () => { plugins: [prettierHTML, prettierCSS], }), ).toMatchSnapshot("overlay html"); - } catch (error) { - throw error; } finally { await browser.close(); await server.stop(); @@ -1036,15 +1007,13 @@ describe("overlay", () => { const pageHtml = await page.evaluate(() => document.body.outerHTML); const overlayHandle = await page.$("#webpack-dev-server-client-overlay"); - expect(overlayHandle).toBe(null); + expect(overlayHandle).toBeNull(); expect( await prettier.format(pageHtml, { parser: "html", plugins: [prettierHTML, prettierCSS], }), ).toMatchSnapshot("page html"); - } catch (error) { - throw error; } finally { await browser.close(); await server.stop(); @@ -1081,15 +1050,13 @@ describe("overlay", () => { const pageHtml = await page.evaluate(() => document.body.outerHTML); const overlayHandle = await page.$("#webpack-dev-server-client-overlay"); - expect(overlayHandle).toBe(null); + expect(overlayHandle).toBeNull(); expect( await prettier.format(pageHtml, { parser: "html", plugins: [prettierHTML, prettierCSS], }), ).toMatchSnapshot("page html"); - } catch (error) { - throw error; } finally { await browser.close(); await server.stop(); @@ -1132,9 +1099,7 @@ describe("overlay", () => { const overlayHandle = await page.$("#webpack-dev-server-client-overlay"); - expect(overlayHandle).toBe(null); - } catch (error) { - throw error; + expect(overlayHandle).toBeNull(); } finally { await browser.close(); await server.stop(); @@ -1189,8 +1154,6 @@ describe("overlay", () => { plugins: [prettierHTML, prettierCSS], }), ).toMatchSnapshot("overlay html"); - } catch (error) { - throw error; } finally { await browser.close(); await server.stop(); @@ -1241,8 +1204,6 @@ describe("overlay", () => { plugins: [prettierHTML, prettierCSS], }), ).toMatchSnapshot("overlay html"); - } catch (error) { - throw error; } finally { await browser.close(); await server.stop(); @@ -1306,8 +1267,6 @@ describe("overlay", () => { plugins: [prettierHTML, prettierCSS], }), ).toMatchSnapshot("overlay html"); - } catch (error) { - throw error; } finally { await browser.close(); await server.stop(); @@ -1381,8 +1340,6 @@ describe("overlay", () => { plugins: [prettierHTML, prettierCSS], }), ).toMatchSnapshot("overlay html"); - } catch (error) { - throw error; } finally { await browser.close(); await server.stop(); @@ -1418,15 +1375,13 @@ describe("overlay", () => { const pageHtml = await page.evaluate(() => document.body.outerHTML); const overlayHandle = await page.$("#webpack-dev-server-client-overlay"); - expect(overlayHandle).toBe(null); + expect(overlayHandle).toBeNull(); expect( await prettier.format(pageHtml, { parser: "html", plugins: [prettierHTML, prettierCSS], }), ).toMatchSnapshot("page html"); - } catch (error) { - throw error; } finally { await browser.close(); await server.stop(); @@ -1479,8 +1434,6 @@ describe("overlay", () => { plugins: [prettierHTML, prettierCSS], }), ).toMatchSnapshot("overlay html"); - } catch (error) { - throw error; } finally { await browser.close(); await server.stop(); @@ -1533,8 +1486,6 @@ describe("overlay", () => { plugins: [prettierHTML, prettierCSS], }), ).toMatchSnapshot("overlay html"); - } catch (error) { - throw error; } finally { await browser.close(); await server.stop(); @@ -1609,8 +1560,6 @@ describe("overlay", () => { plugins: [prettierHTML, prettierCSS], }), ).toMatchSnapshot("page html"); - } catch (error) { - throw error; } finally { await browser.close(); } @@ -1671,8 +1620,6 @@ describe("overlay", () => { plugins: [prettierHTML, prettierCSS], }), ).toMatchSnapshot("overlay html"); - } catch (error) { - throw error; } finally { await browser.close(); await server.stop(); @@ -1734,8 +1681,6 @@ describe("overlay", () => { plugins: [prettierHTML, prettierCSS], }), ).toMatchSnapshot("overlay html"); - } catch (error) { - throw error; } finally { await browser.close(); await server.stop(); @@ -1782,8 +1727,6 @@ describe("overlay", () => { plugins: [prettierHTML, prettierCSS], }), ).toMatchSnapshot("overlay html"); - } catch (error) { - throw error; } finally { await browser.close(); await server.stop(); @@ -1825,9 +1768,7 @@ describe("overlay", () => { const overlayHandle = await page.$("#webpack-dev-server-client-overlay"); - expect(overlayHandle).toBe(null); - } catch (error) { - throw error; + expect(overlayHandle).toBeNull(); } finally { await browser.close(); await server.stop(); @@ -1876,8 +1817,6 @@ describe("overlay", () => { plugins: [prettierHTML, prettierCSS], }), ).toMatchSnapshot("overlay html"); - } catch (error) { - throw error; } finally { await browser.close(); await server.stop(); @@ -1921,9 +1860,52 @@ describe("overlay", () => { const overlayHandle = await page.$("#webpack-dev-server-client-overlay"); - expect(overlayHandle).toBe(null); - } catch (error) { - throw error; + expect(overlayHandle).toBeNull(); + } finally { + await browser.close(); + await server.stop(); + } + }); + + it("should not show filtered promise rejection with specific error cause", async () => { + const compiler = webpack(config); + + const server = new Server( + { + port, + client: { + overlay: { + runtimeErrors: (error) => + !/Injected/.test(error.cause.error.message), + }, + }, + }, + compiler, + ); + + await server.start(); + + const { page, browser } = await runBrowser(); + + try { + await page.goto(`http://localhost:${port}/`, { + waitUntil: "networkidle0", + }); + + await page.addScriptTag({ + content: `(function throwError() { + setTimeout(function () { + Promise.reject({ error: new Error('Injected async error') }); + }, 0); + })();`, + }); + + // Delay for the overlay to appear + await delay(1000); + + const overlayHandle = await page.$("#webpack-dev-server-client-overlay"); + + expect(overlayHandle).toBeNull(); } finally { await browser.close(); await server.stop(); @@ -1989,8 +1971,6 @@ describe("overlay", () => { }, ), ).toMatchSnapshot("overlay html"); - } catch (error) { - throw error; } finally { await browser.close(); await server.stop(); diff --git a/test/e2e/port.test.js b/test/e2e/port.test.js index 9939a870aa..b7824a49e9 100644 --- a/test/e2e/port.test.js +++ b/test/e2e/port.test.js @@ -4,12 +4,12 @@ const webpack = require("webpack"); const Server = require("../../lib/Server"); const config = require("../fixtures/client-config/webpack.config"); const runBrowser = require("../helpers/run-browser"); -const port = require("../ports-map").port; +const { port } = require("../ports-map"); describe("port", () => { const ports = [ "", - // eslint-disable-next-line no-undefined + undefined, "auto", port, @@ -52,14 +52,10 @@ describe("port", () => { } if (testedPort === "-1" || testedPort === "99999") { - const errorMessageRegExp = new RegExp( - `options.port should be >= 0 and < 65536`, - ); + const errorMessageRegExp = /options.port should be >= 0 and < 65536/; try { expect(errored.message).toMatch(errorMessageRegExp); - } catch (error) { - throw error; } finally { await server.stop(); } @@ -97,8 +93,6 @@ describe("port", () => { consoleMessages.map((message) => message.text()), ).toMatchSnapshot("console messages"); expect(pageErrors).toMatchSnapshot("page errors"); - } catch (error) { - throw error; } finally { await browser.close(); await server.stop(); diff --git a/test/e2e/progress.test.js b/test/e2e/progress.test.js index 2aedf72bbf..3f922d98c0 100644 --- a/test/e2e/progress.test.js +++ b/test/e2e/progress.test.js @@ -1,6 +1,6 @@ "use strict"; -const path = require("path"); +const path = require("node:path"); const fs = require("graceful-fs"); const webpack = require("webpack"); const Server = require("../../lib/Server"); @@ -66,8 +66,6 @@ describe("progress", () => { } }, 100); }); - } catch (error) { - throw error; } finally { await browser.close(); } @@ -78,9 +76,7 @@ describe("progress", () => { ), ); - expect(progressConsoleMessage.length > 0).toBe(true); - } catch (error) { - throw error; + expect(progressConsoleMessage.length).toBeGreaterThan(0); } finally { fs.unlinkSync(cssFilePath); diff --git a/test/e2e/range-header.test.js b/test/e2e/range-header.test.js index 298d472be7..a1237b583b 100644 --- a/test/e2e/range-header.test.js +++ b/test/e2e/range-header.test.js @@ -27,7 +27,7 @@ describe("'Range' header", () => { expect(response.status).toBe(200); expect(response.headers["content-type"]).toBe( - "application/javascript; charset=utf-8", + "text/javascript; charset=utf-8", ); expect(response.headers["accept-ranges"]).toBe("bytes"); @@ -38,12 +38,12 @@ describe("'Range' header", () => { expect(responseRange.status).toBe(206); expect(responseRange.headers["content-type"]).toBe( - "application/javascript; charset=utf-8", + "text/javascript; charset=utf-8", ); expect(responseRange.headers["content-length"]).toBe("500"); expect(responseRange.headers["content-range"]).toMatch(/^bytes 0-499\//); expect(responseRange.text).toBe(responseContent.slice(0, 500)); - expect(responseRange.text.length).toBe(500); + expect(responseRange.text).toHaveLength(500); }); it('should work with "Range" header using "HEAD" method', async () => { @@ -51,7 +51,7 @@ describe("'Range' header", () => { expect(response.status).toBe(200); expect(response.headers["content-type"]).toBe( - "application/javascript; charset=utf-8", + "text/javascript; charset=utf-8", ); expect(response.headers["accept-ranges"]).toBe("bytes"); @@ -61,7 +61,7 @@ describe("'Range' header", () => { expect(responseRange.status).toBe(206); expect(responseRange.headers["content-type"]).toBe( - "application/javascript; charset=utf-8", + "text/javascript; charset=utf-8", ); expect(responseRange.headers["content-length"]).toBe("500"); expect(responseRange.headers["content-range"]).toMatch(/^bytes 0-499\//); @@ -72,7 +72,7 @@ describe("'Range' header", () => { expect(response.status).toBe(200); expect(response.headers["content-type"]).toBe( - "application/javascript; charset=utf-8", + "text/javascript; charset=utf-8", ); expect(response.headers["accept-ranges"]).toBe("bytes"); @@ -92,7 +92,7 @@ describe("'Range' header", () => { expect(response.status).toBe(200); expect(response.headers["content-type"]).toBe( - "application/javascript; charset=utf-8", + "text/javascript; charset=utf-8", ); expect(response.headers["accept-ranges"]).toBe("bytes"); @@ -103,9 +103,9 @@ describe("'Range' header", () => { expect(responseRange.status).toBe(200); expect(responseRange.headers["content-type"]).toBe( - "application/javascript; charset=utf-8", + "text/javascript; charset=utf-8", ); expect(responseRange.text).toBe(responseContent); - expect(responseRange.text.length).toBe(responseContent.length); + expect(responseRange.text).toHaveLength(responseContent.length); }); }); diff --git a/test/e2e/server-and-client-transport.test.js b/test/e2e/server-and-client-transport.test.js index e00e0a272a..763a4be353 100644 --- a/test/e2e/server-and-client-transport.test.js +++ b/test/e2e/server-and-client-transport.test.js @@ -3,10 +3,10 @@ const webpack = require("webpack"); const Server = require("../../lib/Server"); const WebsocketServer = require("../../lib/servers/WebsocketServer"); +const customConfig = require("../fixtures/provide-plugin-custom/webpack.config"); const defaultConfig = require("../fixtures/provide-plugin-default/webpack.config"); const sockjsConfig = require("../fixtures/provide-plugin-sockjs-config/webpack.config"); const wsConfig = require("../fixtures/provide-plugin-ws-config/webpack.config"); -const customConfig = require("../fixtures/provide-plugin-custom/webpack.config"); const runBrowser = require("../helpers/run-browser"); const port = require("../ports-map")["server-and-client-transport"]; @@ -34,15 +34,13 @@ describe("server and client transport", () => { }); const isCorrectTransport = await page.evaluate( - () => window.injectedClient === window.expectedClient, + () => globalThis.injectedClient === globalThis.expectedClient, ); expect(isCorrectTransport).toBe(true); expect( consoleMessages.map((message) => message.text()), ).toMatchSnapshot(); - } catch (error) { - throw error; } finally { await browser.close(); await server.stop(); @@ -73,15 +71,13 @@ describe("server and client transport", () => { }); const isCorrectTransport = await page.evaluate( - () => window.injectedClient === window.expectedClient, + () => globalThis.injectedClient === globalThis.expectedClient, ); expect(isCorrectTransport).toBe(true); expect( consoleMessages.map((message) => message.text()), ).toMatchSnapshot(); - } catch (error) { - throw error; } finally { await browser.close(); await server.stop(); @@ -114,15 +110,13 @@ describe("server and client transport", () => { }); const isCorrectTransport = await page.evaluate( - () => window.injectedClient === window.expectedClient, + () => globalThis.injectedClient === globalThis.expectedClient, ); expect(isCorrectTransport).toBe(true); expect( consoleMessages.map((message) => message.text()), ).toMatchSnapshot(); - } catch (error) { - throw error; } finally { await browser.close(); await server.stop(); @@ -153,15 +147,13 @@ describe("server and client transport", () => { }); const isCorrectTransport = await page.evaluate( - () => window.injectedClient === window.expectedClient, + () => globalThis.injectedClient === globalThis.expectedClient, ); expect(isCorrectTransport).toBe(true); expect( consoleMessages.map((message) => message.text()), ).toMatchSnapshot(); - } catch (error) { - throw error; } finally { await browser.close(); await server.stop(); @@ -194,15 +186,13 @@ describe("server and client transport", () => { }); const isCorrectTransport = await page.evaluate( - () => window.injectedClient === window.expectedClient, + () => globalThis.injectedClient === globalThis.expectedClient, ); expect(isCorrectTransport).toBe(true); expect( consoleMessages.map((message) => message.text()), ).toMatchSnapshot(); - } catch (error) { - throw error; } finally { await browser.close(); await server.stop(); @@ -236,15 +226,13 @@ describe("server and client transport", () => { }); const isCorrectTransport = await page.evaluate( - () => window.injectedClient === window.expectedClient, + () => globalThis.injectedClient === globalThis.expectedClient, ); expect(isCorrectTransport).toBe(true); expect( consoleMessages.map((message) => message.text()), ).toMatchSnapshot(); - } catch (error) { - throw error; } finally { await browser.close(); await server.stop(); @@ -280,15 +268,13 @@ describe("server and client transport", () => { }); const isCorrectTransport = await page.evaluate( - () => window.injectedClient === window.expectedClient, + () => globalThis.injectedClient === globalThis.expectedClient, ); expect(isCorrectTransport).toBe(true); expect( consoleMessages.map((message) => message.text()), ).toMatchSnapshot(); - } catch (error) { - throw error; } finally { await browser.close(); await server.stop(); @@ -322,15 +308,13 @@ describe("server and client transport", () => { }); const isCorrectTransport = await page.evaluate( - () => window.injectedClient === window.expectedClient, + () => globalThis.injectedClient === globalThis.expectedClient, ); expect(isCorrectTransport).toBe(true); expect( consoleMessages.map((message) => message.text()), ).toMatchSnapshot(); - } catch (error) { - throw error; } finally { await browser.close(); await server.stop(); @@ -366,15 +350,13 @@ describe("server and client transport", () => { }); const isCorrectTransport = await page.evaluate( - () => window.injectedClient === window.expectedClient, + () => globalThis.injectedClient === globalThis.expectedClient, ); expect(isCorrectTransport).toBe(true); expect( consoleMessages.map((message) => message.text()), ).toMatchSnapshot(); - } catch (error) { - throw error; } finally { await browser.close(); await server.stop(); @@ -428,15 +410,13 @@ describe("server and client transport", () => { }); const isCorrectTransport = await page.evaluate( - () => window.injectedClient === window.expectedClient, + () => globalThis.injectedClient === globalThis.expectedClient, ); expect(isCorrectTransport).toBe(true); expect( consoleMessages.map((message) => message.text()), ).toMatchSnapshot(); - } catch (error) { - throw error; } finally { await browser.close(); await server.stop(); @@ -469,15 +449,13 @@ describe("server and client transport", () => { }); const isCorrectTransport = await page.evaluate( - () => window.injectedClient === window.expectedClient, + () => globalThis.injectedClient === globalThis.expectedClient, ); expect(isCorrectTransport).toBe(true); expect( consoleMessages.map((message) => message.text()), ).toMatchSnapshot(); - } catch (error) { - throw error; } finally { await browser.close(); await server.stop(); @@ -511,15 +489,13 @@ describe("server and client transport", () => { }); const isCorrectTransport = await page.evaluate( - () => window.injectedClient === window.expectedClient, + () => globalThis.injectedClient === globalThis.expectedClient, ); expect(isCorrectTransport).toBe(true); expect( consoleMessages.map((message) => message.text()), ).toMatchSnapshot(); - } catch (error) { - throw error; } finally { await browser.close(); await server.stop(); @@ -553,15 +529,13 @@ describe("server and client transport", () => { }); const isCorrectTransport = await page.evaluate( - () => window.injectedClient === window.expectedClient, + () => globalThis.injectedClient === globalThis.expectedClient, ); expect(isCorrectTransport).toBe(true); expect( consoleMessages.map((message) => message.text()), ).toMatchSnapshot(); - } catch (error) { - throw error; } finally { await browser.close(); await server.stop(); @@ -597,15 +571,13 @@ describe("server and client transport", () => { }); const isCorrectTransport = await page.evaluate( - () => window.injectedClient === window.expectedClient, + () => globalThis.injectedClient === globalThis.expectedClient, ); expect(isCorrectTransport).toBe(true); expect( consoleMessages.map((message) => message.text()), ).toMatchSnapshot(); - } catch (error) { - throw error; } finally { await browser.close(); await server.stop(); diff --git a/test/e2e/server.test.js b/test/e2e/server.test.js index f17f0e5627..582e531873 100644 --- a/test/e2e/server.test.js +++ b/test/e2e/server.test.js @@ -1,16 +1,16 @@ "use strict"; -const https = require("https"); -const path = require("path"); +const https = require("node:https"); +const path = require("node:path"); const fs = require("graceful-fs"); const request = require("supertest"); const webpack = require("webpack"); const Server = require("../../lib/Server"); const config = require("../fixtures/static-config/webpack.config"); -const runBrowser = require("../helpers/run-browser"); const { skipTestOnWindows } = require("../helpers/conditional-test"); const customHTTP = require("../helpers/custom-http"); const normalizeOptions = require("../helpers/normalize-options"); +const runBrowser = require("../helpers/run-browser"); const port = require("../ports-map")["server-option"]; const httpsCertificateDirectory = path.resolve( @@ -80,7 +80,7 @@ describe("server option", () => { () => performance.getEntries()[0].nextHopProtocol, ); - expect(HTTPVersion).not.toEqual("h2"); + expect(HTTPVersion).not.toBe("h2"); expect(response.status()).toMatchSnapshot("response status"); @@ -140,7 +140,7 @@ describe("server option", () => { () => performance.getEntries()[0].nextHopProtocol, ); - expect(HTTPVersion).not.toEqual("h2"); + expect(HTTPVersion).not.toBe("h2"); expect(response.status()).toMatchSnapshot("response status"); @@ -200,7 +200,7 @@ describe("server option", () => { () => performance.getEntries()[0].nextHopProtocol, ); - expect(HTTPVersion).not.toEqual("h2"); + expect(HTTPVersion).not.toBe("h2"); expect(response.status()).toMatchSnapshot("response status"); @@ -260,7 +260,7 @@ describe("server option", () => { () => performance.getEntries()[0].nextHopProtocol, ); - expect(HTTPVersion).toEqual("h2"); + expect(HTTPVersion).toBe("h2"); expect(response.status()).toBe(200); expect((await response.text()).trim()).toBe("Heyo."); expect(consoleMessages).toHaveLength(0); @@ -851,96 +851,13 @@ describe("server option", () => { waitUntil: "networkidle0", }); - expect(response.status()).toEqual(200); + expect(response.status()).toBe(200); expect(await response.text()).toContain("Heyo"); expect(consoleMessages.map((message) => message.text())).toEqual([]); expect(pageErrors).toEqual([]); }); }); - describe("ca, pfx, key and cert are buffer", () => { - let compiler; - let server; - let createServerSpy; - let page; - let browser; - let pageErrors; - let consoleMessages; - - beforeEach(async () => { - compiler = webpack(config); - - createServerSpy = jest.spyOn(https, "createServer"); - - server = new Server( - { - static: { - directory: staticDirectory, - watch: false, - }, - server: { - type: "https", - options: { - ca: fs.readFileSync( - path.join(httpsCertificateDirectory, "ca.pem"), - ), - pfx: fs.readFileSync( - path.join(httpsCertificateDirectory, "server.pfx"), - ), - key: fs.readFileSync( - path.join(httpsCertificateDirectory, "server.key"), - ), - cert: fs.readFileSync( - path.join(httpsCertificateDirectory, "server.crt"), - ), - passphrase: "webpack-dev-server", - }, - }, - port, - }, - compiler, - ); - - await server.start(); - - ({ page, browser } = await runBrowser()); - - pageErrors = []; - consoleMessages = []; - }); - - afterEach(async () => { - createServerSpy.mockRestore(); - - await browser.close(); - await server.stop(); - }); - - it("should handle GET request to index route (/)", async () => { - page - .on("console", (message) => { - consoleMessages.push(message); - }) - .on("pageerror", (error) => { - pageErrors.push(error); - }); - - const response = await page.goto(`https://localhost:${port}/`, { - waitUntil: "networkidle0", - }); - - expect( - normalizeOptions(createServerSpy.mock.calls[0][0]), - ).toMatchSnapshot("https options"); - expect(response.status()).toMatchSnapshot("response status"); - expect(await response.text()).toMatchSnapshot("response text"); - expect( - consoleMessages.map((message) => message.text()), - ).toMatchSnapshot("console messages"); - expect(pageErrors).toMatchSnapshot("page errors"); - }); - }); - describe("ca, pfx, key and cert are buffer, key and pfx are objects", () => { let compiler; let server; @@ -1346,7 +1263,7 @@ describe("server option", () => { const options = normalizeOptions(createServerSpy.mock.calls[0][0]); - expect(HTTPVersion).toEqual("h2"); + expect(HTTPVersion).toBe("h2"); expect(options.spdy).toEqual({ protocols: ["h2", "http/1.1"] }); expect(response.status()).toBe(200); expect((await response.text()).trim()).toBe("Heyo."); @@ -1418,7 +1335,7 @@ describe("server option", () => { () => performance.getEntries()[0].nextHopProtocol, ); - expect(HTTPVersion).toEqual("http/1.1"); + expect(HTTPVersion).toBe("http/1.1"); expect( normalizeOptions(createServerSpy.mock.calls[0][0]), ).toMatchSnapshot("http options"); diff --git a/test/e2e/setup-exit-signals.test.js b/test/e2e/setup-exit-signals.test.js index 0de9236d34..8b8de09674 100644 --- a/test/e2e/setup-exit-signals.test.js +++ b/test/e2e/setup-exit-signals.test.js @@ -59,9 +59,9 @@ describe("setupExitSignals option", () => { afterEach(async () => { exitSpy.mockReset(); stdinResumeSpy.mockReset(); - signals.forEach((signal) => { + for (const signal of signals) { process.removeAllListeners(signal); - }); + } process.stdin.removeAllListeners("end"); await browser.close(); await server.stop(); @@ -87,10 +87,10 @@ describe("setupExitSignals option", () => { await new Promise((resolve) => { const interval = setInterval(() => { if (doExit) { - expect(stopCallbackSpy.mock.calls.length).toEqual(1); + expect(stopCallbackSpy.mock.calls).toHaveLength(1); if (server.compiler.close) { - expect(closeCallbackSpy.mock.calls.length).toEqual(1); + expect(closeCallbackSpy.mock.calls).toHaveLength(1); } clearInterval(interval); diff --git a/test/e2e/static-directory.test.js b/test/e2e/static-directory.test.js index 982aca59a3..a4f2b02002 100644 --- a/test/e2e/static-directory.test.js +++ b/test/e2e/static-directory.test.js @@ -1,13 +1,13 @@ "use strict"; -const path = require("path"); +const path = require("node:path"); const fs = require("graceful-fs"); const webpack = require("webpack"); const Server = require("../../lib/Server"); -const testServer = require("../helpers/test-server"); const config = require("../fixtures/static-config/webpack.config"); -const port = require("../ports-map")["static-directory-option"]; const runBrowser = require("../helpers/run-browser"); +const testServer = require("../helpers/test-server"); +const port = require("../ports-map")["static-directory-option"]; const staticDirectory = path.resolve(__dirname, "../fixtures/static-config"); const publicDirectory = path.resolve(staticDirectory, "public"); @@ -100,10 +100,11 @@ describe("static.directory option", () => { expect(pageErrors).toMatchSnapshot("page errors"); }); - it("Watches folder recursively", (done) => { + it("watches folder recursively", (done) => { // chokidar emitted a change, // meaning it watched the file correctly - server.staticWatchers[0].on("change", () => { + server.staticWatchers[0].on("change", (filepath) => { + expect(typeof filepath).toBe("string"); done(); }); @@ -113,14 +114,16 @@ describe("static.directory option", () => { }, 1000); }); - it("Watches node_modules", (done) => { + it("watches node_modules", (done) => { const filePath = path.join(publicDirectory, "node_modules", "index.html"); fs.writeFileSync(filePath, "foo", "utf8"); // chokidar emitted a change, // meaning it watched the file correctly - server.staticWatchers[0].on("change", () => { + server.staticWatchers[0].on("change", (filepath) => { + expect(typeof filepath).toBe("string"); + fs.unlinkSync(filePath); done(); @@ -483,7 +486,7 @@ describe("static.directory option", () => { }); }); - it("Should throw exception (external url)", (done) => { + it("should throw exception (external url)", (done) => { expect.assertions(1); server = testServer.start( @@ -501,23 +504,26 @@ describe("static.directory option", () => { ); }); - it("Should not throw exception (local path with lower case first character)", (done) => { + it("should not throw exception (local path with lower case first character)", (done) => { testServer.start( config, { static: { directory: publicDirectory.charAt(0).toLowerCase() + - publicDirectory.substring(1), + publicDirectory.slice(1), watch: true, }, port, }, - done, + (error) => { + expect(error).toBeUndefined(); + done(error); + }, ); }); - it("Should not throw exception (local path with lower case first character & has '-')", (done) => { + it("should not throw exception (local path with lower case first character & has '-')", (done) => { testServer.start( config, { @@ -527,11 +533,14 @@ describe("static.directory option", () => { }, port, }, - done, + (error) => { + expect(error).toBeUndefined(); + done(error); + }, ); }); - it("Should not throw exception (local path with upper case first character & has '-')", (done) => { + it("should not throw exception (local path with upper case first character & has '-')", (done) => { testServer.start( config, { @@ -541,11 +550,14 @@ describe("static.directory option", () => { }, port, }, - done, + (error) => { + expect(error).toBeUndefined(); + done(error); + }, ); }); - it("Should throw exception (array with absolute url)", (done) => { + it("should throw exception (array with absolute url)", (done) => { server = testServer.start( config, { @@ -578,7 +590,6 @@ describe("static.directory option", () => { server = new Server( { - // eslint-disable-next-line no-undefined static: undefined, port, }, diff --git a/test/e2e/static-public-path.test.js b/test/e2e/static-public-path.test.js index 6818345f73..8af9cf0e58 100644 --- a/test/e2e/static-public-path.test.js +++ b/test/e2e/static-public-path.test.js @@ -1,11 +1,11 @@ "use strict"; -const path = require("path"); +const path = require("node:path"); const webpack = require("webpack"); const Server = require("../../lib/Server"); const config = require("../fixtures/static-config/webpack.config"); -const port = require("../ports-map")["static-public-path-option"]; const runBrowser = require("../helpers/run-browser"); +const port = require("../ports-map")["static-public-path-option"]; const staticDirectory = path.resolve(__dirname, "../fixtures/static-config"); const publicDirectory = path.resolve(staticDirectory, "public"); diff --git a/test/e2e/stats.test.js b/test/e2e/stats.test.js index 1d90ef6915..70f3017b12 100644 --- a/test/e2e/stats.test.js +++ b/test/e2e/stats.test.js @@ -7,7 +7,7 @@ const HTMLGeneratorPlugin = require("../helpers/html-generator-plugin"); const runBrowser = require("../helpers/run-browser"); const port = require("../ports-map").stats; -global.console.log = jest.fn(); +jest.spyOn(globalThis.console, "log").mockImplementation(); describe("stats", () => { const cases = [ @@ -24,7 +24,6 @@ describe("stats", () => { { title: 'should work using "undefined" value for the "stats" option', webpackOptions: { - // eslint-disable-next-line no-undefined stats: undefined, }, }, @@ -55,7 +54,7 @@ describe("stats", () => { webpackOptions: { stats: { colors: { - green: "\u001b[32m", + green: "\u001B[32m", }, }, }, @@ -108,7 +107,7 @@ describe("stats", () => { }); } - cases.forEach((testCase) => { + for (const testCase of cases) { it(testCase.title, async () => { const compiler = webpack({ ...config, ...testCase.webpackOptions }); const devServerOptions = { @@ -134,12 +133,10 @@ describe("stats", () => { expect( consoleMessages.map((message) => message.text()), ).toMatchSnapshot(); - } catch (error) { - throw error; } finally { await browser.close(); await server.stop(); } }); - }); + } }); diff --git a/test/e2e/target.test.js b/test/e2e/target.test.js index 940966fee7..32f9a5aaef 100644 --- a/test/e2e/target.test.js +++ b/test/e2e/target.test.js @@ -1,6 +1,6 @@ "use strict"; -const path = require("path"); +const path = require("node:path"); const webpack = require("webpack"); const Server = require("../../lib/Server"); const config = require("../fixtures/client-config/webpack.config"); @@ -84,8 +84,6 @@ describe("target", () => { } else { expect(pageErrors).toMatchSnapshot("page errors"); } - } catch (error) { - throw error; } finally { await browser.close(); await server.stop(); @@ -125,8 +123,6 @@ describe("target", () => { ).toMatchSnapshot("console messages"); expect(pageErrors).toMatchSnapshot("page errors"); - } catch (error) { - throw error; } finally { await browser.close(); await server.stop(); @@ -176,8 +172,6 @@ describe("target", () => { ).toMatchSnapshot("console messages"); expect(pageErrors).toMatchSnapshot("page errors"); - } catch (error) { - throw error; } finally { await browser.close(); await server.stop(); diff --git a/test/e2e/watch-files.test.js b/test/e2e/watch-files.test.js index 732e1077e3..c3785fbbec 100644 --- a/test/e2e/watch-files.test.js +++ b/test/e2e/watch-files.test.js @@ -1,6 +1,6 @@ "use strict"; -const path = require("path"); +const path = require("node:path"); const chokidar = require("chokidar"); const fs = require("graceful-fs"); const webpack = require("webpack"); @@ -240,7 +240,7 @@ describe("watchFiles option", () => { beforeEach(async () => { try { fs.unlinkSync(nonExistFile); - } catch (error) { + } catch { // ignore } @@ -599,7 +599,7 @@ describe("watchFiles option", () => { }, ]; - optionCases.forEach((optionCase) => { + for (const optionCase of optionCases) { describe(JSON.stringify(optionCase), () => { let compiler; let server; @@ -677,6 +677,6 @@ describe("watchFiles option", () => { }); }); }); - }); + } }); }); diff --git a/test/e2e/web-socket-communication.test.js b/test/e2e/web-socket-communication.test.js index 21731cf88b..8af3b3678a 100644 --- a/test/e2e/web-socket-communication.test.js +++ b/test/e2e/web-socket-communication.test.js @@ -8,12 +8,10 @@ const config = require("../fixtures/client-config/webpack.config"); const runBrowser = require("../helpers/run-browser"); const port = require("../ports-map")["web-socket-communication"]; -jest.setTimeout(60000); - describe("web socket communication", () => { const webSocketServers = ["ws", "sockjs"]; - webSocketServers.forEach((websocketServer) => { + for (const websocketServer of webSocketServers) { it(`should work and close web socket client connection when web socket server closed ("${websocketServer}")`, async () => { WebsocketServer.heartbeatInterval = 100; @@ -59,8 +57,6 @@ describe("web socket communication", () => { expect(consoleMessages).toMatchSnapshot("console messages"); expect(pageErrors).toMatchSnapshot("page errors"); - } catch (error) { - throw error; } finally { await browser.close(); } @@ -104,13 +100,11 @@ describe("web socket communication", () => { }, 200); }); - expect(server.webSocketServer.clients.length).toBe(0); + expect(server.webSocketServer.clients).toHaveLength(0); expect( consoleMessages.map((message) => message.text()), ).toMatchSnapshot("console messages"); expect(pageErrors).toMatchSnapshot("page errors"); - } catch (error) { - throw error; } finally { await server.stop(); } @@ -157,16 +151,14 @@ describe("web socket communication", () => { consoleMessages.map((message) => message.text()), ).toMatchSnapshot("console messages"); expect(pageErrors).toMatchSnapshot("page errors"); - } catch (error) { - throw error; } finally { await browser.close(); await server.stop(); } }); - }); + } - it(`should work and do heartbeat using ("ws" web socket server)`, async () => { + it('should work and do heartbeat using ("ws" web socket server)', async () => { WebsocketServer.heartbeatInterval = 100; const compiler = webpack(config); @@ -180,6 +172,9 @@ describe("web socket communication", () => { server.webSocketServer.heartbeatInterval = 100; + let opened = false; + let received = false; + await new Promise((resolve, reject) => { const ws = new WebSocket(`ws://localhost:${devServerOptions.port}/ws`, { headers: { @@ -188,9 +183,6 @@ describe("web socket communication", () => { }, }); - let opened = false; - let received = false; - ws.on("open", () => { opened = true; }); @@ -218,6 +210,9 @@ describe("web socket communication", () => { }); }); + expect(opened).toBe(true); + expect(received).toBe(true); + await server.stop(); }); }); diff --git a/test/e2e/web-socket-server-url.test.js b/test/e2e/web-socket-server-url.test.js index c781472082..24147d0ba2 100644 --- a/test/e2e/web-socket-server-url.test.js +++ b/test/e2e/web-socket-server-url.test.js @@ -1,8 +1,8 @@ "use strict"; const express = require("express"); -const webpack = require("webpack"); const { createProxyMiddleware } = require("http-proxy-middleware"); +const webpack = require("webpack"); const Server = require("../../lib/Server"); const config = require("../fixtures/client-config/webpack.config"); const runBrowser = require("../helpers/run-browser"); @@ -94,7 +94,7 @@ describe("web socket server URL", () => { await page.goto(`http://${proxyHost}:${proxyPort}/`, { waitUntil: "networkidle0", }); - const webSocketRequest = webSocketRequests[0]; + const [webSocketRequest] = webSocketRequests; expect(webSocketRequest.url).toContain( `${websocketURLProtocol}://${devServerHost}:${devServerPort}/ws`, @@ -103,8 +103,6 @@ describe("web socket server URL", () => { consoleMessages.map((message) => message.text()), ).toMatchSnapshot("console messages"); expect(pageErrors).toMatchSnapshot("page errors"); - } catch (error) { - throw error; } finally { proxy.close(); await browser.close(); @@ -192,7 +190,7 @@ describe("web socket server URL", () => { waitUntil: "networkidle0", }); - const webSocketRequest = webSocketRequests[0]; + const [webSocketRequest] = webSocketRequests; expect(webSocketRequest.url).toContain( `${websocketURLProtocol}://${devServerHost}:${devServerPort}/ws`, @@ -201,8 +199,6 @@ describe("web socket server URL", () => { consoleMessages.map((message) => message.text()), ).toMatchSnapshot("console messages"); expect(pageErrors).toMatchSnapshot("page errors"); - } catch (error) { - throw error; } finally { proxy.close(); await browser.close(); @@ -294,7 +290,7 @@ describe("web socket server URL", () => { waitUntil: "networkidle0", }); - const webSocketRequest = webSocketRequests[0]; + const [webSocketRequest] = webSocketRequests; expect(webSocketRequest.url).toContain( `${websocketURLProtocol}://${devServerHost}:${devServerPort}/ws`, @@ -303,8 +299,6 @@ describe("web socket server URL", () => { consoleMessages.map((message) => message.text()), ).toMatchSnapshot("console messages"); expect(pageErrors).toMatchSnapshot("page errors"); - } catch (error) { - throw error; } finally { proxy.close(); @@ -397,7 +391,7 @@ describe("web socket server URL", () => { waitUntil: "networkidle0", }); - const webSocketRequest = webSocketRequests[0]; + const [webSocketRequest] = webSocketRequests; expect(webSocketRequest.url).toContain( `${websocketURLProtocol}://${resolvedHost}:${resolvedPort}/ws`, @@ -406,8 +400,6 @@ describe("web socket server URL", () => { consoleMessages.map((message) => message.text()), ).toMatchSnapshot("console messages"); expect(pageErrors).toMatchSnapshot("page errors"); - } catch (error) { - throw error; } finally { proxy.close(); @@ -477,7 +469,7 @@ describe("web socket server URL", () => { waitUntil: "networkidle0", }); - const webSocketRequest = webSocketRequests[0]; + const [webSocketRequest] = webSocketRequests; expect(webSocketRequest.url).toContain( `${websocketURLProtocol}://localhost:${port1}/ws`, @@ -486,8 +478,6 @@ describe("web socket server URL", () => { consoleMessages.map((message) => message.text()), ).toMatchSnapshot("console messages"); expect(pageErrors).toMatchSnapshot("page errors"); - } catch (error) { - throw error; } finally { await browser.close(); await server.stop(); @@ -553,7 +543,7 @@ describe("web socket server URL", () => { waitUntil: "networkidle0", }); - const webSocketRequest = webSocketRequests[0]; + const [webSocketRequest] = webSocketRequests; expect(webSocketRequest.url).toContain( `${websocketURLProtocol}://localhost:${port1}/ws`, @@ -562,8 +552,6 @@ describe("web socket server URL", () => { consoleMessages.map((message) => message.text()), ).toMatchSnapshot("console messages"); expect(pageErrors).toMatchSnapshot("page errors"); - } catch (error) { - throw error; } finally { await browser.close(); await server.stop(); @@ -629,7 +617,7 @@ describe("web socket server URL", () => { waitUntil: "networkidle0", }); - const webSocketRequest = webSocketRequests[0]; + const [webSocketRequest] = webSocketRequests; expect(webSocketRequest.url).toContain( `${websocketURLProtocol}://localhost:${port1}/ws`, @@ -638,8 +626,6 @@ describe("web socket server URL", () => { consoleMessages.map((message) => message.text()), ).toMatchSnapshot("console messages"); expect(pageErrors).toMatchSnapshot("page errors"); - } catch (error) { - throw error; } finally { await browser.close(); await server.stop(); @@ -705,7 +691,7 @@ describe("web socket server URL", () => { waitUntil: "networkidle0", }); - const webSocketRequest = webSocketRequests[0]; + const [webSocketRequest] = webSocketRequests; expect(webSocketRequest.url).toContain( `${websocketURLProtocol}://127.0.0.1:${port1}/ws`, @@ -714,8 +700,6 @@ describe("web socket server URL", () => { consoleMessages.map((message) => message.text()), ).toMatchSnapshot("console messages"); expect(pageErrors).toMatchSnapshot("page errors"); - } catch (error) { - throw error; } finally { await browser.close(); await server.stop(); @@ -780,7 +764,7 @@ describe("web socket server URL", () => { waitUntil: "networkidle0", }); - const webSocketRequest = webSocketRequests[0]; + const [webSocketRequest] = webSocketRequests; expect(webSocketRequest.url).toContain( `${websocketURLProtocol}://127.0.0.1:${port1}/ws`, @@ -789,8 +773,6 @@ describe("web socket server URL", () => { consoleMessages.map((message) => message.text()), ).toMatchSnapshot("console messages"); expect(pageErrors).toMatchSnapshot("page errors"); - } catch (error) { - throw error; } finally { await browser.close(); await server.stop(); @@ -856,7 +838,7 @@ describe("web socket server URL", () => { waitUntil: "networkidle0", }); - const webSocketRequest = webSocketRequests[0]; + const [webSocketRequest] = webSocketRequests; expect(webSocketRequest.url).toContain( `${websocketURLProtocol}://127.0.0.1:${port1}/ws`, @@ -865,8 +847,6 @@ describe("web socket server URL", () => { consoleMessages.map((message) => message.text()), ).toMatchSnapshot("console messages"); expect(pageErrors).toMatchSnapshot("page errors"); - } catch (error) { - throw error; } finally { await browser.close(); await server.stop(); @@ -932,7 +912,7 @@ describe("web socket server URL", () => { waitUntil: "networkidle0", }); - const webSocketRequest = webSocketRequests[0]; + const [webSocketRequest] = webSocketRequests; expect(webSocketRequest.url).toContain( `${websocketURLProtocol}://127.0.0.1:${port1}/ws`, @@ -941,8 +921,6 @@ describe("web socket server URL", () => { consoleMessages.map((message) => message.text()), ).toMatchSnapshot("console messages"); expect(pageErrors).toMatchSnapshot("page errors"); - } catch (error) { - throw error; } finally { await browser.close(); await server.stop(); @@ -1015,7 +993,7 @@ describe("web socket server URL", () => { waitUntil: "networkidle0", }); - const webSocketRequest = webSocketRequests[0]; + const [webSocketRequest] = webSocketRequests; expect(webSocketRequest.url).toContain( webSocketServer === "sockjs" @@ -1026,8 +1004,6 @@ describe("web socket server URL", () => { consoleMessages.map((message) => message.text()), ).toMatchSnapshot("console messages"); expect(pageErrors).toMatchSnapshot("page errors"); - } catch (error) { - throw error; } finally { await browser.close(); await server.stop(); @@ -1092,7 +1068,7 @@ describe("web socket server URL", () => { waitUntil: "networkidle0", }); - const webSocketRequest = webSocketRequests[0]; + const [webSocketRequest] = webSocketRequests; expect(webSocketRequest.url).toContain( `${websocketURLProtocol}://127.0.0.1:${port1}/ws`, @@ -1101,8 +1077,6 @@ describe("web socket server URL", () => { consoleMessages.map((message) => message.text()), ).toMatchSnapshot("console messages"); expect(pageErrors).toMatchSnapshot("page errors"); - } catch (error) { - throw error; } finally { await browser.close(); await server.stop(); @@ -1168,7 +1142,7 @@ describe("web socket server URL", () => { waitUntil: "networkidle0", }); - const webSocketRequest = webSocketRequests[0]; + const [webSocketRequest] = webSocketRequests; expect(webSocketRequest.url).toContain( `${websocketURLProtocol}://127.0.0.1:${port1}/ws`, @@ -1177,8 +1151,6 @@ describe("web socket server URL", () => { consoleMessages.map((message) => message.text()), ).toMatchSnapshot("console messages"); expect(pageErrors).toMatchSnapshot("page errors"); - } catch (error) { - throw error; } finally { await browser.close(); await server.stop(); @@ -1239,7 +1211,7 @@ describe("web socket server URL", () => { waitUntil: "networkidle0", }); - const webSocketRequest = webSocketRequests[0]; + const [webSocketRequest] = webSocketRequests; expect(webSocketRequest.url).toContain( `${websocketURLProtocol}://127.0.0.1:${port1}/ws`, @@ -1248,8 +1220,6 @@ describe("web socket server URL", () => { consoleMessages.map((message) => message.text()), ).toMatchSnapshot("console messages"); expect(pageErrors).toMatchSnapshot("page errors"); - } catch (error) { - throw error; } finally { await browser.close(); await server.stop(); @@ -1314,7 +1284,7 @@ describe("web socket server URL", () => { waitUntil: "networkidle0", }); - const webSocketRequest = webSocketRequests[0]; + const [webSocketRequest] = webSocketRequests; expect(webSocketRequest.url).toContain( `${websocketURLProtocol}://zenitsu@127.0.0.1:${port1}/ws`, @@ -1323,8 +1293,6 @@ describe("web socket server URL", () => { consoleMessages.map((message) => message.text()), ).toMatchSnapshot("console messages"); expect(pageErrors).toMatchSnapshot("page errors"); - } catch (error) { - throw error; } finally { await browser.close(); await server.stop(); @@ -1393,7 +1361,7 @@ describe("web socket server URL", () => { waitUntil: "networkidle0", }); - const webSocketRequest = webSocketRequests[0]; + const [webSocketRequest] = webSocketRequests; expect(webSocketRequest.url).toContain( // "sockjs" has bug with parsing URL @@ -1405,8 +1373,6 @@ describe("web socket server URL", () => { consoleMessages.map((message) => message.text()), ).toMatchSnapshot("console messages"); expect(pageErrors).toMatchSnapshot("page errors"); - } catch (error) { - throw error; } finally { await browser.close(); await server.stop(); @@ -1473,7 +1439,7 @@ describe("web socket server URL", () => { waitUntil: "networkidle0", }); - const webSocketRequest = webSocketRequests[0]; + const [webSocketRequest] = webSocketRequests; expect(webSocketRequest.url).toContain( `${websocketURLProtocol}://zenitsu:chuntaro@127.0.0.1:${port1}/ws`, @@ -1482,8 +1448,6 @@ describe("web socket server URL", () => { consoleMessages.map((message) => message.text()), ).toMatchSnapshot("console messages"); expect(pageErrors).toMatchSnapshot("page errors"); - } catch (error) { - throw error; } finally { await browser.close(); await server.stop(); @@ -1549,7 +1513,7 @@ describe("web socket server URL", () => { waitUntil: "networkidle0", }); - const webSocketRequest = webSocketRequests[0]; + const [webSocketRequest] = webSocketRequests; expect(webSocketRequest.url).toContain( `${websocketURLProtocol}://127.0.0.1:${port1}/custom-ws/foo/bar`, @@ -1558,8 +1522,6 @@ describe("web socket server URL", () => { consoleMessages.map((message) => message.text()), ).toMatchSnapshot("console messages"); expect(pageErrors).toMatchSnapshot("page errors"); - } catch (error) { - throw error; } finally { await browser.close(); await server.stop(); @@ -1626,7 +1588,7 @@ describe("web socket server URL", () => { waitUntil: "networkidle0", }); - const webSocketRequest = webSocketRequests[0]; + const [webSocketRequest] = webSocketRequests; expect(webSocketRequest.url).toContain( webSocketServer === "ws" @@ -1637,8 +1599,6 @@ describe("web socket server URL", () => { consoleMessages.map((message) => message.text()), ).toMatchSnapshot("console messages"); expect(pageErrors).toMatchSnapshot("page errors"); - } catch (error) { - throw error; } finally { await browser.close(); await server.stop(); @@ -1709,7 +1669,7 @@ describe("web socket server URL", () => { waitUntil: "networkidle0", }); - const webSocketRequest = webSocketRequests[0]; + const [webSocketRequest] = webSocketRequests; expect(webSocketRequest.url).toContain( `${websocketURLProtocol}://127.0.0.1:${port1}/custom-ws/foo/bar`, @@ -1718,8 +1678,6 @@ describe("web socket server URL", () => { consoleMessages.map((message) => message.text()), ).toMatchSnapshot("console messages"); expect(pageErrors).toMatchSnapshot("page errors"); - } catch (error) { - throw error; } finally { await browser.close(); await server.stop(); @@ -1790,7 +1748,7 @@ describe("web socket server URL", () => { waitUntil: "networkidle0", }); - const webSocketRequest = webSocketRequests[0]; + const [webSocketRequest] = webSocketRequests; expect(webSocketRequest.url).toContain( `${websocketURLProtocol}://127.0.0.1:${port1}/custom-ws`, @@ -1799,8 +1757,6 @@ describe("web socket server URL", () => { consoleMessages.map((message) => message.text()), ).toMatchSnapshot("console messages"); expect(pageErrors).toMatchSnapshot("page errors"); - } catch (error) { - throw error; } finally { await browser.close(); await server.stop(); @@ -1871,7 +1827,7 @@ describe("web socket server URL", () => { waitUntil: "networkidle0", }); - const webSocketRequest = webSocketRequests[0]; + const [webSocketRequest] = webSocketRequests; expect(webSocketRequest.url).toContain( `${websocketURLProtocol}://127.0.0.1:${port1}/custom-ws/`, @@ -1880,8 +1836,6 @@ describe("web socket server URL", () => { consoleMessages.map((message) => message.text()), ).toMatchSnapshot("console messages"); expect(pageErrors).toMatchSnapshot("page errors"); - } catch (error) { - throw error; } finally { await browser.close(); await server.stop(); @@ -1953,7 +1907,7 @@ describe("web socket server URL", () => { waitUntil: "networkidle0", }); - const webSocketRequest = webSocketRequests[0]; + const [webSocketRequest] = webSocketRequests; expect(webSocketRequest.url).toContain( webSocketServer === "ws" @@ -1964,8 +1918,6 @@ describe("web socket server URL", () => { consoleMessages.map((message) => message.text()), ).toMatchSnapshot("console messages"); expect(pageErrors).toMatchSnapshot("page errors"); - } catch (error) { - throw error; } finally { await browser.close(); await server.stop(); @@ -2038,7 +1990,7 @@ describe("web socket server URL", () => { waitUntil: "networkidle0", }); - const webSocketRequest = webSocketRequests[0]; + const [webSocketRequest] = webSocketRequests; expect(webSocketRequest.url).toContain( `${websocketURLProtocol}://127.0.0.1:${port1}/custom-ws`, @@ -2047,8 +1999,6 @@ describe("web socket server URL", () => { consoleMessages.map((message) => message.text()), ).toMatchSnapshot("console messages"); expect(pageErrors).toMatchSnapshot("page errors"); - } catch (error) { - throw error; } finally { await browser.close(); await server.stop(); @@ -2108,7 +2058,7 @@ describe("web socket server URL", () => { waitUntil: "networkidle0", }); - const webSocketRequest = webSocketRequests[0]; + const [webSocketRequest] = webSocketRequests; expect(webSocketRequest.url).toContain( `${websocketURLProtocol}://${hostname}:${port1}/ws`, @@ -2117,8 +2067,6 @@ describe("web socket server URL", () => { consoleMessages.map((message) => message.text()), ).toMatchSnapshot("console messages"); expect(pageErrors).toMatchSnapshot("page errors"); - } catch (error) { - throw error; } finally { await browser.close(); await server.stop(); @@ -2179,7 +2127,7 @@ describe("web socket server URL", () => { waitUntil: "networkidle0", }); - const webSocketRequest = webSocketRequests[0]; + const [webSocketRequest] = webSocketRequests; expect(webSocketRequest.url).toContain( `${websocketURLProtocol}://${hostname}:${port1}/ws`, @@ -2188,8 +2136,6 @@ describe("web socket server URL", () => { consoleMessages.map((message) => message.text()), ).toMatchSnapshot("console messages"); expect(pageErrors).toMatchSnapshot("page errors"); - } catch (error) { - throw error; } finally { await browser.close(); await server.stop(); @@ -2249,7 +2195,7 @@ describe("web socket server URL", () => { waitUntil: "networkidle0", }); - const webSocketRequest = webSocketRequests[0]; + const [webSocketRequest] = webSocketRequests; expect(webSocketRequest.url).toContain( `${websocketURLProtocol}://${hostname}:${port1}/ws`, @@ -2258,8 +2204,6 @@ describe("web socket server URL", () => { consoleMessages.map((message) => message.text()), ).toMatchSnapshot("console messages"); expect(pageErrors).toMatchSnapshot("page errors"); - } catch (error) { - throw error; } finally { await browser.close(); await server.stop(); @@ -2320,7 +2264,7 @@ describe("web socket server URL", () => { waitUntil: "networkidle0", }); - const webSocketRequest = webSocketRequests[0]; + const [webSocketRequest] = webSocketRequests; if (webSocketServer === "ws") { expect(webSocketRequest.url).toContain( @@ -2336,8 +2280,6 @@ describe("web socket server URL", () => { consoleMessages.map((message) => message.text()), ).toMatchSnapshot("console messages"); expect(pageErrors).toMatchSnapshot("page errors"); - } catch (error) { - throw error; } finally { await browser.close(); await server.stop(); @@ -2402,8 +2344,9 @@ describe("web socket server URL", () => { waitUntil: "networkidle0", }); - const webSocketRequest = webSocketRequests[0]; + const [webSocketRequest] = webSocketRequests; + /* eslint-disable jest/no-standalone-expect */ if (webSocketServer === "ws") { expect(webSocketRequest.url).toContain( `wss://${hostname}:${port1}/ws`, @@ -2420,8 +2363,7 @@ describe("web socket server URL", () => { "Hey.", ]); expect(pageErrors).toHaveLength(0); - } catch (error) { - throw error; + /* eslint-enable jest/no-standalone-expect */ } finally { await browser.close(); await server.stop(); @@ -2487,7 +2429,7 @@ describe("web socket server URL", () => { waitUntil: "networkidle0", }); - const webSocketRequest = webSocketRequests[0]; + const [webSocketRequest] = webSocketRequests; expect(webSocketRequest.url).toContain( `${websocketURLProtocol}://127.0.0.1:${resolvedFreePort}/ws`, @@ -2496,8 +2438,6 @@ describe("web socket server URL", () => { consoleMessages.map((message) => message.text()), ).toMatchSnapshot("console messages"); expect(pageErrors).toMatchSnapshot("page errors"); - } catch (error) { - throw error; } finally { await browser.close(); await server.stop(); @@ -2568,7 +2508,7 @@ describe("web socket server URL", () => { waitUntil: "networkidle0", }); - const webSocketRequest = webSocketRequests[0]; + const [webSocketRequest] = webSocketRequests; expect(webSocketRequest.url).toContain( `${websocketURLProtocol}://127.0.0.1:${port1}/ws`, @@ -2577,8 +2517,6 @@ describe("web socket server URL", () => { consoleMessages.map((message) => message.text()), ).toMatchSnapshot("console messages"); expect(pageErrors).toMatchSnapshot("page errors"); - } catch (error) { - throw error; } finally { await browser.close(); await server.stop(); @@ -2642,7 +2580,7 @@ describe("web socket server URL", () => { waitUntil: "networkidle0", }); - const webSocketRequest = webSocketRequests[0]; + const [webSocketRequest] = webSocketRequests; expect(webSocketRequest.url).toContain( `${websocketURLProtocol}://127.0.0.1:${port1}/ws`, @@ -2651,8 +2589,6 @@ describe("web socket server URL", () => { consoleMessages.map((message) => message.text()), ).toMatchSnapshot("console messages"); expect(pageErrors).toMatchSnapshot("page errors"); - } catch (error) { - throw error; } finally { await browser.close(); await server.stop(); @@ -2700,8 +2636,6 @@ describe("web socket server URL", () => { pageError.message.split("\n")[0].replace("SyntaxError: ", ""), ), ).toMatchSnapshot("page errors"); - } catch (error) { - throw error; } finally { await browser.close(); await server.stop(); @@ -2737,7 +2671,7 @@ describe("web socket server URL", () => { if (!isDisconnected) { isDisconnected = /Disconnected!/.test(text); - consoleMessages.push(text.replace(/:[\d]+/g, ":")); + consoleMessages.push(text.replaceAll(/:[\d]+/g, ":")); } }) .on("pageerror", (error) => { @@ -2764,8 +2698,6 @@ describe("web socket server URL", () => { expect( pageErrors.map((pageError) => pageError.message.split("\n")[0]), ).toMatchSnapshot("page errors"); - } catch (error) { - throw error; } finally { await browser.close(); await server.stop(); diff --git a/test/e2e/web-socket-server.test.js b/test/e2e/web-socket-server.test.js index b3ffde1fb1..b611040e2e 100644 --- a/test/e2e/web-socket-server.test.js +++ b/test/e2e/web-socket-server.test.js @@ -58,8 +58,6 @@ describe("web socket server", () => { "console messages", ); expect(pageErrors).toMatchSnapshot("page errors"); - } catch (error) { - throw error; } finally { await browser.close(); await server.stop(); diff --git a/test/helpers/ExitOnDonePlugin.js b/test/helpers/ExitOnDonePlugin.js index 9db636139e..656b58579a 100644 --- a/test/helpers/ExitOnDonePlugin.js +++ b/test/helpers/ExitOnDonePlugin.js @@ -1,7 +1,6 @@ "use strict"; module.exports = class ExitOnDonePlugin { - // eslint-disable-next-line class-methods-use-this apply(compiler) { compiler.hooks.afterDone.tap("webpack-dev-server", (stats) => { let exitCode = 0; @@ -11,6 +10,7 @@ module.exports = class ExitOnDonePlugin { } setImmediate(() => { + // eslint-disable-next-line n/no-process-exit process.exit(exitCode); }); }); diff --git a/test/helpers/conditional-test.js b/test/helpers/conditional-test.js index f3486ed6a3..9a05682c72 100644 --- a/test/helpers/conditional-test.js +++ b/test/helpers/conditional-test.js @@ -1,11 +1,18 @@ "use strict"; +/* global test */ + const isWindows = process.platform === "win32"; +/** + * @param {string} reason reason + * @returns {boolean} true when it is windows, otherwise false + */ function skipTestOnWindows(reason) { if (isWindows) { test.skip(reason, () => {}); } + return isWindows; } diff --git a/test/helpers/custom-http.js b/test/helpers/custom-http.js index 0678c55d9a..29046c9bc3 100644 --- a/test/helpers/custom-http.js +++ b/test/helpers/custom-http.js @@ -1,5 +1,5 @@ "use strict"; -const customHTTP = require("http"); +const customHTTP = require("node:http"); module.exports = customHTTP; diff --git a/test/helpers/html-generator-plugin.js b/test/helpers/html-generator-plugin.js index 0c9fa99202..261d16e592 100644 --- a/test/helpers/html-generator-plugin.js +++ b/test/helpers/html-generator-plugin.js @@ -42,7 +42,6 @@ const HTMLContentForTest = ` `; module.exports = class HTMLGeneratorPlugin { - // eslint-disable-next-line class-methods-use-this apply(compiler) { const pluginName = "html-generator-plugin"; @@ -67,6 +66,7 @@ module.exports = class HTMLGeneratorPlugin { if (assetName !== "main.js") { const assetSource = new RawSource( + // eslint-disable-next-line new-cap HTMLContentForAssets(assetName), ); compilation.emitAsset( diff --git a/test/helpers/normalize-options.js b/test/helpers/normalize-options.js index 64814dc412..923b8146e1 100644 --- a/test/helpers/normalize-options.js +++ b/test/helpers/normalize-options.js @@ -1,9 +1,12 @@ "use strict"; +/** + * @param {import("https").ServerOptions} options server options + * @returns {Record} normalized server options + */ function normalizeOptions(options) { const normalizedOptions = {}; - // eslint-disable-next-line guard-for-in for (const propertyName in options) { let value = options[propertyName]; diff --git a/test/helpers/run-browser.js b/test/helpers/run-browser.js index 90d0c9a10a..e4d00b9ba9 100644 --- a/test/helpers/run-browser.js +++ b/test/helpers/run-browser.js @@ -3,52 +3,24 @@ const puppeteer = require("puppeteer"); const { puppeteerArgs } = require("./puppeteer-constants"); +/** @typedef {import('puppeteer').Browser} Browser */ +/** @typedef {import('puppeteer').Page} Page */ +/** @typedef {import('puppeteer').Device} Device */ + /** - * @typedef {Object} RunBrowserResult - * @property {import('puppeteer').Page} page - * @property {import('puppeteer').Browser} browser + * @typedef {object} RunBrowserResult + * @property {Page} page page + * @property {Browser} browser browser */ /** - * @param {Parameters[0]} config - * @returns {Promise} + * @param {Browser} browser browser + * @param {Device} device config + * @returns {Promise} page */ -function runBrowser(config) { - return new Promise((resolve, reject) => { - /** - * @type {import('puppeteer').Page} - */ - let page; - /** - * @type {import('puppeteer').Browser} - */ - let browser; - - puppeteer - .launch({ - headless: "new", - // because of invalid localhost certificate - acceptInsecureCerts: true, - // args come from: https://github.com/alixaxel/chrome-aws-lambda/blob/master/source/index.js - args: puppeteerArgs, - }) - .then((launchedBrowser) => { - browser = launchedBrowser; - - return runPage(launchedBrowser, config); - }) - .then((newPage) => { - page = newPage; - - resolve({ page, browser }); - }) - .catch(reject); - }); -} - -function runPage(browser, config) { +function runPage(browser, device) { /** - * @type {import('puppeteer').Page} + * @type {Page} */ let page; @@ -58,7 +30,7 @@ function runPage(browser, config) { height: 500, }, userAgent: "", - ...config, + ...device, }; return Promise.resolve() @@ -90,5 +62,42 @@ function runPage(browser, config) { }); } +/** + * @param {Device} device device + * @returns {Promise} browser result + */ +function runBrowser(device) { + return new Promise((resolve, reject) => { + /** + * @type {import('puppeteer').Page} + */ + let page; + /** + * @type {import('puppeteer').Browser} + */ + let browser; + + puppeteer + .launch({ + headless: "new", + // because of invalid localhost certificate + acceptInsecureCerts: true, + // args come from: https://github.com/alixaxel/chrome-aws-lambda/blob/master/source/index.js + args: puppeteerArgs, + }) + .then((launchedBrowser) => { + browser = launchedBrowser; + + return runPage(launchedBrowser, device); + }) + .then((newPage) => { + page = newPage; + + resolve({ page, browser }); + }) + .catch(reject); + }); +} + module.exports = runBrowser; module.exports.runPage = runPage; diff --git a/test/helpers/session-subscribe.js b/test/helpers/session-subscribe.js index 34e0a41902..88e71864b5 100644 --- a/test/helpers/session-subscribe.js +++ b/test/helpers/session-subscribe.js @@ -1,8 +1,8 @@ "use strict"; module.exports = async function sessionSubscribe(session) { - session.on("sessionattached", (s) => { - sessionSubscribe(s); + session.on("sessionattached", (attachedSession) => { + sessionSubscribe(attachedSession); }); session.send("Network.enable"); session.send("Runtime.runIfWaitingForDebugger"); diff --git a/test/helpers/snapshotResolver.js b/test/helpers/snapshotResolver.js index e9622480d6..cd4aa21bc0 100644 --- a/test/helpers/snapshotResolver.js +++ b/test/helpers/snapshotResolver.js @@ -1,6 +1,6 @@ "use strict"; -const path = require("path"); +const path = require("node:path"); const webpack = require("webpack"); const [webpackVersion] = webpack.version; diff --git a/test/helpers/test-bin.js b/test/helpers/test-bin.js index 0766445bf6..15667fe59e 100644 --- a/test/helpers/test-bin.js +++ b/test/helpers/test-bin.js @@ -1,9 +1,9 @@ "use strict"; -const os = require("os"); -const path = require("path"); +const os = require("node:os"); +const path = require("node:path"); +const util = require("node:util"); const execa = require("execa"); -const stripAnsi = require("strip-ansi-v6"); const { Writable } = require("readable-stream"); const webpackDevServerPath = path.resolve( @@ -67,7 +67,7 @@ const testBin = (testArgs = [], options = {}) => { new Writable({ write(chunk, encoding, callback) { const str = chunk.toString(); - const output = stripAnsi(str); + const output = util.stripVTControlCharacters(str); if (outputKillStr.test(output)) { processKill(subprocess); @@ -82,7 +82,7 @@ const testBin = (testArgs = [], options = {}) => { new Writable({ write(chunk, encoding, callback) { const str = chunk.toString(); - const output = stripAnsi(str); + const output = util.stripVTControlCharacters(str); if (outputKillStr.test(output)) { processKill(subprocess); @@ -123,27 +123,27 @@ const ipV6 = ` (?::(?:(?::${ipV6Seg}){0,5}:${ipV4}|(?::${ipV6Seg}){1,7}|:)) // ::2:3:4:5:6:7:8 ::2:3:4:5:6:7:8 ::8 ::1.2.3.4 )(?:%[0-9a-zA-Z]{1,})? // %eth0 %1 ` - .replace(/\s*\/\/.*$/gm, "") - .replace(/\n/g, "") + .replaceAll(/\s*\/\/.*$/gm, "") + .replaceAll("\n", "") .trim(); const normalizeStderr = (stderr, options = {}) => { - let normalizedStderr = stripAnsi(stderr); + let normalizedStderr = util.stripVTControlCharacters(stderr); normalizedStderr = normalizedStderr - .replace(/\\/g, "/") - .replace(new RegExp(process.cwd().replace(/\\/g, "/"), "g"), "") - .replace(new RegExp(os.tmpdir().replace(/\\/g, "/"), "g"), "") - .replace(new RegExp("\\\\.\\pipe".replace(/\\/g, "/"), "g"), "") - .replace(new RegExp(ipV4, "g"), "") - .replace(new RegExp(ipV6, "g"), ""); + .replaceAll("\\", "/") + .replaceAll(new RegExp(process.cwd().replaceAll("\\", "/"), "g"), "") + .replaceAll(new RegExp(os.tmpdir().replaceAll("\\", "/"), "g"), "") + .replaceAll(new RegExp("\\\\.\\pipe".replaceAll("\\", "/"), "g"), "") + .replaceAll(new RegExp(ipV4, "g"), "") + .replaceAll(new RegExp(ipV6, "g"), ""); // normalize node warnings - normalizedStderr = normalizedStderr.replace( + normalizedStderr = normalizedStderr.replaceAll( /.*DeprecationWarning.*(\n)*/gm, "", ); - normalizedStderr = normalizedStderr.replace( + normalizedStderr = normalizedStderr.replaceAll( /.*Use `node --trace-deprecation ...` to show where the warning was created.*(\n)*/gm, "", ); @@ -153,7 +153,7 @@ const normalizeStderr = (stderr, options = {}) => { (item) => !/.+wait until bundle finished.*(\n)?/g.test(item), ); normalizedStderr = normalizedStderr.join("\n"); - normalizedStderr = normalizedStderr.replace(/:[0-9]+\//g, ":/"); + normalizedStderr = normalizedStderr.replaceAll(/:[0-9]+\//g, ":/"); if (options.https) { // We have deprecation warning on windows in some cases diff --git a/test/helpers/test-server.js b/test/helpers/test-server.js index 98272e3fa3..9333c64601 100644 --- a/test/helpers/test-server.js +++ b/test/helpers/test-server.js @@ -3,22 +3,34 @@ const webpack = require("webpack"); const Server = require("../../lib/Server"); +/** @typedef {import("webpack").Configuration} Configuration */ +/** @typedef {import("../../lib/Server").Configuration} DevServerConfiguration */ +/** @typedef {import("webpack").Compiler} Compiler */ +/** @typedef {import("webpack").MultiCompiler} MultiCompiler */ + let server; // start server, returning the full setup of the server // (both the server and the compiler) -function startFullSetup(config, options, done) { + +/** + * @param {Configuration} config configuration + * @param {DevServerConfiguration} devServerConfig dev server configuration + * @param {(err?: Error) => void=} done done callback + * @returns {{ server: Server, compiler: Compiler | MultiCompiler }} server and compiler + */ +function startFullSetup(config, devServerConfig, done) { // disable watching by default for tests - if (typeof options.static === "undefined") { - options.static = false; - } else if (options.static === null) { + if (typeof devServerConfig.static === "undefined") { + devServerConfig.static = false; + } else if (devServerConfig.static === null) { // this provides a way of using the default static value - delete options.static; + delete devServerConfig.static; } const compiler = webpack(config); - server = new Server(options, compiler); + server = new Server(devServerConfig, compiler); server.startCallback((error) => { if (error && done) { @@ -36,7 +48,13 @@ function startFullSetup(config, options, done) { }; } -function startAwaitingCompilationFullSetup(config, options, done) { +/** + * @param {Configuration} config configuration + * @param {DevServerConfiguration} devServerConfig dev server configuration + * @param {(err?: Error) => void=} done done callback + * @returns {Server} server + */ +function start(config, devServerConfig, done) { let readyCount = 0; const ready = (error) => { @@ -53,31 +71,20 @@ function startAwaitingCompilationFullSetup(config, options, done) { } }; - const fullSetup = startFullSetup(config, options, ready); + const result = startFullSetup(config, devServerConfig, ready); // wait for compilation, since dev server can start before this // https://github.com/webpack/webpack-dev-server/issues/847 - fullSetup.compiler.hooks.done.tap("done", () => { + result.compiler.hooks.done.tap("done", () => { ready(); }); - return fullSetup; -} - -function startAwaitingCompilation(config, options, done) { - return startAwaitingCompilationFullSetup(config, options, done).server; -} - -function start(config, options, done) { - // I suspect that almost all tests need to wait for compilation to - // finish, because not doing so leaves open handles for jest, - // in the case where a compilation didn't finish before destroying - // the server and moving on. Thus, the default "start" should wait - // for compilation, and only special cases where you don't expect - // a compilation happen should use startBeforeCompilation - return startAwaitingCompilation(config, options, done); + return result.server; } +/** + * @param {() => void} done done callback + */ function close(done) { if (server) { server.stopCallback(() => { @@ -90,6 +97,6 @@ function close(done) { } module.exports = { - start, close, + start, }; diff --git a/test/helpers/trusted-types-html-generator-plugin.js b/test/helpers/trusted-types-html-generator-plugin.js index 53a5bd2f65..6d023305db 100644 --- a/test/helpers/trusted-types-html-generator-plugin.js +++ b/test/helpers/trusted-types-html-generator-plugin.js @@ -36,7 +36,6 @@ const HTMLContentForTest = ` `; module.exports = class HTMLGeneratorPlugin { - // eslint-disable-next-line class-methods-use-this apply(compiler) { const pluginName = "html-generator-plugin"; diff --git a/test/normalize-options.test.js b/test/normalize-options.test.js index e4c97d4bb3..b3ae68c021 100644 --- a/test/normalize-options.test.js +++ b/test/normalize-options.test.js @@ -1,7 +1,7 @@ "use strict"; -const webpack = require("webpack"); const { klona } = require("klona/full"); +const webpack = require("webpack"); const Server = require("../lib/Server"); const port = require("./ports-map")["normalize-option"]; @@ -579,7 +579,7 @@ describe("normalize options", () => { }, ]; - cases.forEach((item) => { + for (const item of cases) { it(item.title, async () => { let webpackConfig; @@ -587,9 +587,10 @@ describe("normalize options", () => { webpackConfig = require("./fixtures/multi-compiler-one-configuration/webpack.config"); if (Array.isArray(item.webpackConfig)) { - webpackConfig = item.webpackConfig.map((config, index) => { - return { ...webpackConfig[index], ...config }; - }); + webpackConfig = item.webpackConfig.map((config, index) => ({ + ...webpackConfig[index], + ...config, + })); } } else { webpackConfig = require("./fixtures/simple-config/webpack.config"); @@ -622,23 +623,21 @@ describe("normalize options", () => { optionsForSnapshot.port = ""; if (optionsForSnapshot.static.length > 0) { - optionsForSnapshot.static.forEach((i) => { + for (const i of optionsForSnapshot.static) { i.directory = i.directory - .replace(/\\/g, "/") - .replace( - new RegExp(process.cwd().replace(/\\/g, "/"), "g"), + .replaceAll("\\", "/") + .replaceAll( + new RegExp(process.cwd().replaceAll("\\", "/"), "g"), "", ); - }); + } } expect(optionsForSnapshot).toMatchSnapshot(); } - } catch (error) { - throw error; } finally { await server.stop(); } }); - }); + } }); diff --git a/test/ports-map.js b/test/ports-map.js index b3a3bc313a..d95dc62af9 100644 --- a/test/ports-map.js +++ b/test/ports-map.js @@ -88,14 +88,15 @@ let startPort = 8089; const ports = {}; -Object.keys(listOfTests).forEach((key) => { +for (const key of Object.keys(listOfTests)) { const value = listOfTests[key]; ports[key] = value === 1 ? (startPort += 1) - : [...new Array(value)].map(() => (startPort += 1)); -}); + : // eslint-disable-next-line no-loop-func + Array.from({ length: value }).map(() => (startPort += 1)); +} const busy = {}; diff --git a/test/server/open-option.test.js b/test/server/open-option.test.js index c31d8c0372..fea4bf65a6 100644 --- a/test/server/open-option.test.js +++ b/test/server/open-option.test.js @@ -17,11 +17,9 @@ if (needRequireMock) { jest.mock("open"); - open.mockImplementation(() => { - return { - catch: jest.fn(), - }; - }); + open.mockImplementation(() => ({ + catch: jest.fn(), + })); } describe('"open" option', () => { @@ -31,11 +29,9 @@ describe('"open" option', () => { compiler = webpack(config); if (!needRequireMock) { - jest.unstable_mockModule("open", () => { - return { - default: jest.fn(() => Promise.resolve()), - }; - }); + jest.unstable_mockModule("open", () => ({ + default: jest.fn(() => Promise.resolve()), + })); open = (await import("open")).default; } @@ -45,6 +41,7 @@ describe('"open" option', () => { open.mockClear(); }); + // eslint-disable-next-line jest/no-focused-tests it.only("should work with unspecified host", async () => { const server = new Server( { @@ -736,18 +733,16 @@ describe('"open" option', () => { }); it("should log warning when can't open", async () => { - open.mockImplementation(() => Promise.reject()); + open.mockRejectedValue(undefined); const loggerWarnSpy = jest.fn(); const getInfrastructureLoggerSpy = jest .spyOn(compiler, "getInfrastructureLogger") - .mockImplementation(() => { - return { - warn: loggerWarnSpy, - info: () => {}, - log: () => {}, - }; - }); + .mockImplementation(() => ({ + warn: loggerWarnSpy, + info: () => {}, + log: () => {}, + })); const server = new Server( { @@ -772,18 +767,16 @@ describe('"open" option', () => { }); it("should log warning when can't open with string", async () => { - open.mockImplementation(() => Promise.reject()); + open.mockRejectedValue(undefined); const loggerWarnSpy = jest.fn(); const getInfrastructureLoggerSpy = jest .spyOn(compiler, "getInfrastructureLogger") - .mockImplementation(() => { - return { - warn: loggerWarnSpy, - info: () => {}, - log: () => {}, - }; - }); + .mockImplementation(() => ({ + warn: loggerWarnSpy, + info: () => {}, + log: () => {}, + })); const server = new Server( { @@ -808,18 +801,16 @@ describe('"open" option', () => { }); it("should log warning when can't open with object", async () => { - open.mockImplementation(() => Promise.reject()); + open.mockRejectedValue(undefined); const loggerWarnSpy = jest.fn(); const getInfrastructureLoggerSpy = jest .spyOn(compiler, "getInfrastructureLogger") - .mockImplementation(() => { - return { - warn: loggerWarnSpy, - info: () => {}, - log: () => {}, - }; - }); + .mockImplementation(() => ({ + warn: loggerWarnSpy, + info: () => {}, + log: () => {}, + })); const server = new Server( { @@ -848,18 +839,16 @@ describe('"open" option', () => { }); it("should log warning when can't open with object with the 'app' option with arguments", async () => { - open.mockImplementation(() => Promise.reject()); + open.mockRejectedValue(undefined); const loggerWarnSpy = jest.fn(); const getInfrastructureLoggerSpy = jest .spyOn(compiler, "getInfrastructureLogger") - .mockImplementation(() => { - return { - warn: loggerWarnSpy, - info: () => {}, - log: () => {}, - }; - }); + .mockImplementation(() => ({ + warn: loggerWarnSpy, + info: () => {}, + log: () => {}, + })); const server = new Server( { @@ -893,19 +882,17 @@ describe('"open" option', () => { loggerWarnSpy.mockRestore(); }); - it("should log warning when can't open with object with the 'app' option with arguments", async () => { - open.mockImplementation(() => Promise.reject()); + it("should log warning when can't open with object with the 'app' option with arguments #2", async () => { + open.mockRejectedValue(undefined); const loggerWarnSpy = jest.fn(); const getInfrastructureLoggerSpy = jest .spyOn(compiler, "getInfrastructureLogger") - .mockImplementation(() => { - return { - warn: loggerWarnSpy, - info: () => {}, - log: () => {}, - }; - }); + .mockImplementation(() => ({ + warn: loggerWarnSpy, + info: () => {}, + log: () => {}, + })); const server = new Server( { diff --git a/test/server/proxy-option.test.js b/test/server/proxy-option.test.js index e77824a371..d6c209e055 100644 --- a/test/server/proxy-option.test.js +++ b/test/server/proxy-option.test.js @@ -1,12 +1,11 @@ "use strict"; -const path = require("path"); -const util = require("util"); -const request = require("supertest"); +const path = require("node:path"); +const util = require("node:util"); const express = require("express"); -const bodyParser = require("body-parser"); -const WebSocket = require("ws"); +const request = require("supertest"); const webpack = require("webpack"); +const WebSocket = require("ws"); const Server = require("../../lib/Server"); const config = require("../fixtures/proxy-config/webpack.config"); const [port1, port2, port3, port4] = require("../ports-map")["proxy-option"]; @@ -79,10 +78,9 @@ let maxServerListeners = 0; const proxyOptionOfArray = [ { context: "/proxy1", target: `http://localhost:${port1}` }, function proxy(req, res, next) { - if (req != null) { - const socket = req.socket != null ? req.socket : req.connection; - // @ts-ignore - const server = socket != null ? socket.server : null; + if (req) { + const socket = req.socket || req.connection; + const server = socket ? socket.server : null; if (server) { maxServerListeners = Math.max( maxServerListeners, @@ -218,7 +216,7 @@ describe("proxy option", () => { it("respects a proxy option when a request path is matched", async () => { const response = await req.get("/proxy1"); - expect(response.status).toEqual(200); + expect(response.status).toBe(200); expect(response.text).toContain("from proxy1"); }); }); @@ -227,7 +225,7 @@ describe("proxy option", () => { it("respects a pathRewrite option", async () => { const response = await req.get("/api/proxy2"); - expect(response.status).toEqual(200); + expect(response.status).toBe(200); expect(response.text).toContain("from proxy2"); }); }); @@ -238,15 +236,15 @@ describe("proxy option", () => { const response = await req.get("/foo/bar.html"); - expect(response.status).toEqual(200); + expect(response.status).toBe(200); expect(response.text).toContain("Hello"); const lastCall = utilSpy.mock.calls[utilSpy.mock.calls.length - 1]; - expect(lastCall[1]).toEqual( + expect(lastCall[1]).toBe( "Using the 'bypass' option is deprecated. Please use the 'router' or 'context' options. Read more at https://github.com/chimurai/http-proxy-middleware/tree/v2.0.6#http-proxy-middleware-options", ); - expect(lastCall[2]).toEqual( + expect(lastCall[2]).toBe( "DEP_WEBPACK_DEV_SERVER_PROXY_BYPASS_ARGUMENT", ); @@ -256,47 +254,47 @@ describe("proxy option", () => { it("can rewrite a request path", async () => { const response = await req.get("/foo/bar.html"); - expect(response.status).toEqual(200); + expect(response.status).toBe(200); expect(response.text).toContain("Hello"); }); it("can rewrite a request path regardless of the target defined a bypass option", async () => { const response = await req.get("/baz/hoge.html"); - expect(response.status).toEqual(200); + expect(response.status).toBe(200); expect(response.text).toContain("Hello"); }); it("should pass through a proxy when a bypass function returns null", async () => { const response = await req.get("/foo.js"); - expect(response.status).toEqual(200); + expect(response.status).toBe(200); expect(response.text).toContain("Hey"); }); it("should not pass through a proxy when a bypass function returns false", async () => { const response = await req.get("/proxyfalse"); - expect(response.status).toEqual(404); + expect(response.status).toBe(404); }); it("should wait if bypass returns promise", async () => { const response = await req.get("/proxy/async"); - expect(response.status).toEqual(200); + expect(response.status).toBe(200); expect(response.text).toContain("proxy async response"); }); it("should work with the 'target' option", async () => { const response = await req.get("/bypass-with-target/foo.js"); - expect(response.status).toEqual(404); + expect(response.status).toBe(404); }); it("should work with the 'target' option #2", async () => { const response = await req.get("/bypass-with-target/index.html"); - expect(response.status).toEqual(200); + expect(response.status).toBe(200); expect(response.text).toContain("Hello"); }); }); @@ -332,7 +330,7 @@ describe("proxy option", () => { it("respects a proxy option", async () => { const response = await req.get("/proxy1"); - expect(response.status).toEqual(200); + expect(response.status).toBe(200); expect(response.text).toContain("from proxy1"); }); }); @@ -367,7 +365,7 @@ describe("proxy option", () => { it("respects a proxy option", async () => { const response = await req.get("/proxy1"); - expect(response.status).toEqual(200); + expect(response.status).toBe(200); expect(response.text).toContain("from proxy1"); }); }); @@ -402,7 +400,7 @@ describe("proxy option", () => { it("respects a proxy option", async () => { const response = await req.get("/proxy1"); - expect(response.status).toEqual(200); + expect(response.status).toBe(200); expect(response.text).toContain("from proxy1"); }); }); @@ -437,7 +435,7 @@ describe("proxy option", () => { it("respects a proxy option", async () => { const response = await req.get("/proxy1"); - expect(response.status).toEqual(200); + expect(response.status).toBe(200); expect(response.text).toContain("from proxy1"); }); }); @@ -472,22 +470,22 @@ describe("proxy option", () => { it("respects a proxy option", async () => { const response = await req.get("/proxy1"); - expect(response.status).toEqual(200); + expect(response.status).toBe(200); expect(response.text).toContain("from proxy1"); }); it("respects a proxy option of function", async () => { const response = await req.get("/api/proxy2"); - expect(response.status).toEqual(200); + expect(response.status).toBe(200); expect(response.text).toContain("from proxy2"); }); it("should allow req, res, and next", async () => { const response = await req.get("/api/proxy2?foo=true"); - expect(response.statusCode).toEqual(200); - expect(response.text).toEqual("foo+next+function"); + expect(response.statusCode).toBe(200); + expect(response.text).toBe("foo+next+function"); }); it("should not exist multiple close events registered", async () => { @@ -525,7 +523,7 @@ describe("proxy option", () => { it("respects a proxy option", async () => { const response = await req.get("/proxy1"); - expect(response.status).toEqual(200); + expect(response.status).toBe(200); expect(response.text).toContain("from proxy1"); }); }); @@ -580,14 +578,14 @@ describe("proxy option", () => { it("respects proxy1 option", async () => { const response = await req.get("/proxy1"); - expect(response.status).toEqual(200); + expect(response.status).toBe(200); expect(response.text).toContain("from proxy"); }); it("respects proxy2 option", async () => { const response = await req.get("/proxy2"); - expect(response.status).toEqual(200); + expect(response.status).toBe(200); expect(response.text).toContain("from proxy"); }); }); @@ -600,7 +598,8 @@ describe("proxy option", () => { const webSocketServerTypes = ["sockjs", "ws"]; - webSocketServerTypes.forEach((webSocketServerType) => { + for (const webSocketServerType of webSocketServerTypes) { + // eslint-disable-next-line no-loop-func describe(`with webSocketServerType: ${webSocketServerType}`, () => { beforeAll(async () => { const compiler = webpack(config); @@ -643,10 +642,6 @@ describe("proxy option", () => { }); }); - it("Should receive response", () => { - expect(responseMessage).toEqual("foo"); - }); - afterAll(async () => { webSocketServer.close(); @@ -656,8 +651,12 @@ describe("proxy option", () => { await server.stop(); }); + + it("should receive response", () => { + expect(responseMessage).toBe("foo"); + }); }); - }); + } }); describe("should supports http methods", () => { @@ -686,10 +685,10 @@ describe("proxy option", () => { const proxy = express(); // Parse application/x-www-form-urlencoded - proxy.use(bodyParser.urlencoded({ extended: false })); + proxy.use(express.urlencoded({ extended: false })); // Parse application/json - proxy.use(bodyParser.json()); + proxy.use(express.json()); // This forces Express to try to decode URLs, which is needed for the test // associated with the middleware below. @@ -713,13 +712,13 @@ describe("proxy option", () => { }); proxy.post("/post-x-www-form-urlencoded", (proxyReq, res) => { - const id = proxyReq.body.id; + const { id } = proxyReq.body; res.status(200).send(`POST method from proxy (id: ${id})`); }); proxy.post("/post-application-json", (proxyReq, res) => { - const id = proxyReq.body.id; + const { id } = proxyReq.body; res.status(200).send({ answer: `POST method from proxy (id: ${id})` }); }); @@ -745,49 +744,49 @@ describe("proxy option", () => { it("errors", async () => { const response = await req.get("/%"); - expect(response.status).toEqual(500); + expect(response.status).toBe(500); expect(response.text).toContain("error from proxy"); }); - it("GET method", async () => { + it("gET method", async () => { const response = await req.get("/get"); - expect(response.status).toEqual(200); + expect(response.status).toBe(200); expect(response.text).toContain("GET method from proxy"); }); - it("HEAD method", async () => { + it("hEAD method", async () => { const response = await req.head("/head"); - expect(response.status).toEqual(200); + expect(response.status).toBe(200); }); - it("POST method (application/x-www-form-urlencoded)", async () => { + it("pOST method (application/x-www-form-urlencoded)", async () => { const response = await req .post("/post-x-www-form-urlencoded") .send("id=1"); - expect(response.status).toEqual(200); + expect(response.status).toBe(200); expect(response.text).toContain("POST method from proxy (id: 1)"); }); - it("POST method (application/json)", async () => { + it("pOST method (application/json)", async () => { const response = await req .post("/post-application-json") .send({ id: "1" }) .set("Accept", "application/json"); - expect(response.status).toEqual(200); - expect(response.headers["content-type"]).toEqual( + expect(response.status).toBe(200); + expect(response.headers["content-type"]).toBe( "application/json; charset=utf-8", ); expect(response.text).toContain("POST method from proxy (id: 1)"); }); - it("DELETE method", async () => { + it("dELETE method", async () => { const response = await req.delete("/delete"); - expect(response.status).toEqual(200); + expect(response.status).toBe(200); expect(response.text).toContain("DELETE method from proxy"); }); }); @@ -827,7 +826,7 @@ describe("proxy option", () => { it("respects a proxy option", async () => { const response = await req.get("/proxy1"); - expect(response.status).toEqual(200); + expect(response.status).toBe(200); expect(response.text).toContain("from proxy1"); }); }); diff --git a/test/validate-options.test.js b/test/validate-options.test.js index bc170f3dc3..b92f9be1fd 100644 --- a/test/validate-options.test.js +++ b/test/validate-options.test.js @@ -1,10 +1,10 @@ "use strict"; -const os = require("os"); -const path = require("path"); +const os = require("node:os"); +const path = require("node:path"); const { readFileSync } = require("graceful-fs"); +const { Volume, createFsFromVolume } = require("memfs"); const webpack = require("webpack"); -const { createFsFromVolume, Volume } = require("memfs"); const Server = require("../lib/Server"); const config = require("./fixtures/simple-config/webpack.config"); @@ -556,8 +556,6 @@ const tests = { }; describe("options", () => { - jest.setTimeout(20000); - let consoleMock; beforeAll(() => { @@ -585,9 +583,9 @@ describe("options", () => { if (typeof replacedValue === "string") { replacedValue = replacedValue - .replace(/\\/g, "/") - .replace( - new RegExp(process.cwd().replace(/\\/g, "/"), "g"), + .replaceAll("\\", "/") + .replaceAll( + new RegExp(process.cwd().replaceAll("\\", "/"), "g"), "", ); } @@ -618,7 +616,7 @@ describe("options", () => { if (type === "success") { expect(thrownError).toBeUndefined(); } else { - expect(thrownError).not.toBeUndefined(); + expect(thrownError).toBeDefined(); expect(thrownError.toString()).toMatchSnapshot(); } }); diff --git a/tsconfig.client.json b/tsconfig.client.json new file mode 100644 index 0000000000..4bd07e7495 --- /dev/null +++ b/tsconfig.client.json @@ -0,0 +1,17 @@ +{ + "compilerOptions": { + "target": "esnext", + "lib": ["es5", "dom", "webworker", "es2022.error"], + "module": "nodenext", + "moduleResolution": "nodenext", + "allowJs": true, + "checkJs": true, + "noEmit": true, + "strict": true, + "types": ["@types/trusted-types", "webpack/module"], + "skipDefaultLibCheck": true, + "esModuleInterop": true + }, + "include": ["./client-src/**/*"], + "exclude": ["./client-src/webpack.config.js"] +} diff --git a/tsconfig.json b/tsconfig.json index 83e104c5f7..a28baacbf5 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -10,9 +10,5 @@ "resolveJsonModule": true, "allowSyntheticDefaultImports": true }, - "include": [ - "./bin/**/*", - // "./client-src/**/*", - "./lib/**/*" - ] + "include": ["./bin/**/*", "./lib/**/*"] } diff --git a/types/bin/webpack-dev-server.d.ts b/types/bin/webpack-dev-server.d.ts index d3ec8a3a55..a84d4ae0f5 100644 --- a/types/bin/webpack-dev-server.d.ts +++ b/types/bin/webpack-dev-server.d.ts @@ -23,5 +23,5 @@ export type CliOption = { /** * preprocessor */ - preprocess: Function; + preprocess: () => void; }; diff --git a/types/lib/Server.d.ts b/types/lib/Server.d.ts index db75276fe2..47dfba4c62 100644 --- a/types/lib/Server.d.ts +++ b/types/lib/Server.d.ts @@ -1,6 +1,6 @@ export = Server; /** - * @typedef {Object} BasicApplication + * @typedef {object} BasicApplication * @property {typeof useFn} use */ /** @@ -1123,62 +1123,64 @@ declare class Server< }; }; /** - * @param {string} URL - * @returns {boolean} + * @private + * @returns {StatsOptions} default stats options + */ + private static get DEFAULT_STATS(); + /** + * @param {string} URL url + * @returns {boolean} true when URL is absolute, otherwise false */ static isAbsoluteURL(URL: string): boolean; /** - * @param {string} gatewayOrFamily or family - * @param {boolean} [isInternal] ip should be internal - * @returns {string | undefined} + * @param {string} gatewayOrFamily gateway or family + * @param {boolean=} isInternal ip should be internal + * @returns {string | undefined} resolved IP */ static findIp( gatewayOrFamily: string, - isInternal?: boolean, + isInternal?: boolean | undefined, ): string | undefined; /** - * @param {"v4" | "v6"} family - * @returns {Promise} + * @param {"v4" | "v6"} family family + * @returns {Promise} internal API */ static internalIP(family: "v4" | "v6"): Promise; /** - * @param {"v4" | "v6"} family - * @returns {string | undefined} + * @param {"v4" | "v6"} family family + * @returns {string | undefined} internal IP */ static internalIPSync(family: "v4" | "v6"): string | undefined; /** - * @param {Host} hostname - * @returns {Promise} + * @param {Host} hostname hostname + * @returns {Promise} resolved hostname */ static getHostname(hostname: Host): Promise; /** - * @param {Port} port - * @param {string} host - * @returns {Promise} + * @param {Port} port port + * @param {string} host host + * @returns {Promise} free port */ static getFreePort(port: Port, host: string): Promise; /** - * @returns {string} + * @returns {string} path to cache dir */ static findCacheDir(): string; /** * @private - * @param {Compiler} compiler - * @returns bool + * @param {Compiler} compiler compiler + * @returns {boolean} true when target is `web`, otherwise false */ private static isWebTarget; /** - * @param {Configuration} options - * @param {Compiler | MultiCompiler} compiler + * @param {Configuration} options options + * @param {Compiler | MultiCompiler} compiler compiler */ - constructor( - options: Configuration | undefined, - compiler: Compiler | MultiCompiler, - ); + constructor(options: Configuration, compiler: Compiler | MultiCompiler); compiler: import("webpack").Compiler | import("webpack").MultiCompiler; /** * @type {ReturnType} - * */ + */ logger: ReturnType; options: Configuration; /** @@ -1187,7 +1189,7 @@ declare class Server< staticWatchers: FSWatcher[]; /** * @private - * @type {{ name: string | symbol, listener: (...args: any[]) => void}[] }} + * @type {{ name: string | symbol, listener: (...args: EXPECTED_ANY[]) => void}[] }} */ private listeners; /** @@ -1206,12 +1208,12 @@ declare class Server< private currentHash; /** * @private - * @param {Compiler} compiler + * @param {Compiler} compiler compiler */ private addAdditionalEntries; /** * @private - * @returns {Compiler["options"]} + * @returns {Compiler["options"]} compiler options */ private getCompilerOptions; /** @@ -1221,13 +1223,13 @@ declare class Server< private normalizeOptions; /** * @private - * @returns {string} + * @returns {string} client transport */ private getClientTransport; /** * @template T * @private - * @returns {T} + * @returns {T} server transport */ private getServerTransport; /** @@ -1235,7 +1237,7 @@ declare class Server< */ getClientEntry(): string; /** - * @returns {string | void} + * @returns {string | void} client hot entry */ getClientHotEntry(): string | void; /** @@ -1253,12 +1255,12 @@ declare class Server< * @returns {Promise} */ private setupApp; - /** @type {A | undefined}*/ + /** @type {A | undefined} */ app: A | undefined; /** * @private - * @param {Stats | MultiStats} statsObj - * @returns {StatsCompilation} + * @param {Stats | MultiStats} statsObj stats + * @returns {StatsCompilation} stats of compilation */ private getStats; /** @@ -1304,7 +1306,7 @@ declare class Server< * @returns {Promise} */ private createServer; - /** @type {S | undefined}*/ + /** @type {S | undefined} */ server: S | undefined; isTlsServer: boolean | undefined; /** @@ -1316,7 +1318,7 @@ declare class Server< webSocketServer: WebSocketServerImplementation | undefined | null; /** * @private - * @param {string} defaultOpenTarget + * @param {string} defaultOpenTarget default open target * @returns {Promise} */ private openBrowser; @@ -1332,6 +1334,7 @@ declare class Server< private bonjour; /** * @private + * @param {() => void} callback callback * @returns {void} */ private stopBonjour; @@ -1342,79 +1345,83 @@ declare class Server< private logStatus; /** * @private - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next + * @param {Request} req request + * @param {Response} res response + * @param {NextFunction} next next function */ private setHeaders; /** * @private - * @param {string} value - * @returns {boolean} + * @param {string} value value + * @returns {boolean} true when host allowed, otherwise false */ private isHostAllowed; /** * @private - * @param {{ [key: string]: string | undefined }} headers - * @param {string} headerToCheck - * @param {boolean} validateHost - * @returns {boolean} + * @param {{ [key: string]: string | undefined }} headers headers + * @param {string} headerToCheck header to check + * @param {boolean} validateHost need to validate host + * @returns {boolean} true when host is valid, otherwise false */ private isValidHost; /** * @private - * @param {{ [key: string]: string | undefined }} headers - * @returns {boolean} + * @param {{ [key: string]: string | undefined }} headers headers + * @returns {boolean} true when is same origin, otherwise false */ private isSameOrigin; /** - * @param {ClientConnection[]} clients - * @param {string} type - * @param {any} [data] - * @param {any} [params] + * @param {ClientConnection[]} clients clients + * @param {string} type type + * @param {EXPECTED_ANY=} data data + * @param {EXPECTED_ANY=} params params */ sendMessage( clients: ClientConnection[], type: string, - data?: any, - params?: any, + data?: EXPECTED_ANY | undefined, + params?: EXPECTED_ANY | undefined, ): void; /** * @private - * @param {ClientConnection[]} clients - * @param {StatsCompilation} stats - * @param {boolean} [force] + * @param {ClientConnection[]} clients clients + * @param {StatsCompilation} stats stats + * @param {boolean=} force force */ private sendStats; /** - * @param {string | string[]} watchPath - * @param {WatchOptions} [watchOptions] + * @param {string | string[]} watchPath watch path + * @param {WatchOptions=} watchOptions watch options */ - watchFiles(watchPath: string | string[], watchOptions?: WatchOptions): void; + watchFiles( + watchPath: string | string[], + watchOptions?: WatchOptions | undefined, + ): void; /** - * @param {import("webpack-dev-middleware").Callback} [callback] + * @param {import("webpack-dev-middleware").Callback=} callback callback */ - invalidate(callback?: import("webpack-dev-middleware").Callback): void; + invalidate( + callback?: import("webpack-dev-middleware").Callback | undefined, + ): void; /** * @returns {Promise} */ start(): Promise; /** - * @param {(err?: Error) => void} [callback] + * @param {((err?: Error) => void)=} callback callback */ - startCallback(callback?: (err?: Error) => void): void; + startCallback(callback?: ((err?: Error) => void) | undefined): void; /** * @returns {Promise} */ stop(): Promise; /** - * @param {(err?: Error) => void} [callback] + * @param {((err?: Error) => void)=} callback callback */ - stopCallback(callback?: (err?: Error) => void): void; + stopCallback(callback?: ((err?: Error) => void) | undefined): void; } declare namespace Server { export { - DEFAULT_STATS, Schema, Compiler, MultiCompiler, @@ -1446,6 +1453,7 @@ declare namespace Server { ExpressErrorRequestHandler, ExpressRequest, ExpressResponse, + EXPECTED_ANY, NextFunction, SimpleHandleFunction, NextHandleFunction, @@ -1482,12 +1490,10 @@ declare namespace Server { Middleware, BasicServer, Configuration, + FunctionReturning, BasicApplication, }; } -declare class DEFAULT_STATS { - private constructor(); -} type Schema = import("schema-utils/declarations/validate").Schema; type Compiler = import("webpack").Compiler; type MultiCompiler = import("webpack").MultiCompiler; @@ -1520,7 +1526,8 @@ type ExpressRequestHandler = import("express").RequestHandler; type ExpressErrorRequestHandler = import("express").ErrorRequestHandler; type ExpressRequest = import("express").Request; type ExpressResponse = import("express").Response; -type NextFunction = (err?: any) => void; +type EXPECTED_ANY = any; +type NextFunction = (err?: EXPECTED_ANY) => void; type SimpleHandleFunction = (req: IncomingMessage, res: ServerResponse) => void; type NextHandleFunction = ( req: IncomingMessage, @@ -1528,7 +1535,7 @@ type NextHandleFunction = ( next: NextFunction, ) => void; type ErrorHandleFunction = ( - err: any, + err: EXPECTED_ANY, req: IncomingMessage, res: ServerResponse, next: NextFunction, @@ -1561,9 +1568,15 @@ type DevMiddlewareContext< type Host = "local-ip" | "local-ipv4" | "local-ipv6" | string; type Port = number | string | "auto"; type WatchFiles = { + /** + * paths + */ paths: string | string[]; + /** + * options + */ options?: - | (import("chokidar").WatchOptions & { + | (WatchOptions & { aggregateTimeout?: number; ignored?: WatchOptions["ignored"]; poll?: number | boolean; @@ -1571,21 +1584,34 @@ type WatchFiles = { | undefined; }; type Static = { + /** + * directory + */ directory?: string | undefined; - publicPath?: string | string[] | undefined; - serveIndex?: boolean | import("serve-index").Options | undefined; - staticOptions?: - | import("serve-static").ServeStaticOptions< - import("http").ServerResponse - > - | undefined; + /** + * public path + */ + publicPath?: (string | string[]) | undefined; + /** + * serve index + */ + serveIndex?: (boolean | ServeIndexOptions) | undefined; + /** + * static options + */ + staticOptions?: ServeStaticOptions | undefined; + /** + * watch and watch options + */ watch?: - | boolean - | (import("chokidar").WatchOptions & { - aggregateTimeout?: number; - ignored?: WatchOptions["ignored"]; - poll?: number | boolean; - }) + | ( + | boolean + | (WatchOptions & { + aggregateTimeout?: number; + ignored?: WatchOptions["ignored"]; + poll?: number | boolean; + }) + ) | undefined; }; type NormalizedStatic = { @@ -1607,7 +1633,7 @@ type ServerType< | "spdy" | "http2" | string - | ((arg0: ServerOptions, arg1: A) => S); + | ((serverOptions: ServerOptions, application: A) => S); type ServerConfiguration< A extends BasicApplication = import("express").Application, S extends BasicServer = import("http").Server< @@ -1615,12 +1641,26 @@ type ServerConfiguration< typeof import("http").ServerResponse >, > = { + /** + * type + */ type?: ServerType | undefined; + /** + * options + */ options?: ServerOptions | undefined; }; type WebSocketServerConfiguration = { - type?: string | Function | undefined; - options?: Record | undefined; + /** + * type + */ + type?: + | ("sockjs" | "ws" | string | (() => WebSocketServerConfiguration)) + | undefined; + /** + * options + */ + options?: Record | undefined; }; type ClientConnection = ( | import("ws").WebSocket @@ -1665,36 +1705,79 @@ type OpenApp = { arguments?: string[] | undefined; }; type Open = { - app?: string | string[] | OpenApp | undefined; - target?: string | string[] | undefined; + app?: (string | string[] | OpenApp) | undefined; + /** + * target + */ + target?: (string | string[]) | undefined; }; type NormalizedOpen = { target: string; options: import("open").Options; }; type WebSocketURL = { + /** + * hostname + */ hostname?: string | undefined; + /** + * password + */ password?: string | undefined; + /** + * pathname + */ pathname?: string | undefined; - port?: string | number | undefined; + /** + * port + */ + port?: (number | string) | undefined; + /** + * protocol + */ protocol?: string | undefined; + /** + * username + */ username?: string | undefined; }; type OverlayMessageOptions = boolean | ((error: Error) => void); type ClientConfiguration = { - logging?: "none" | "error" | "warn" | "info" | "log" | "verbose" | undefined; + /** + * logging + */ + logging?: + | ("log" | "info" | "warn" | "error" | "none" | "verbose") + | undefined; + /** + * overlay + */ overlay?: - | boolean - | { - warnings?: OverlayMessageOptions; - errors?: OverlayMessageOptions; - runtimeErrors?: OverlayMessageOptions; - } + | ( + | boolean + | { + warnings?: OverlayMessageOptions; + errors?: OverlayMessageOptions; + runtimeErrors?: OverlayMessageOptions; + } + ) | undefined; + /** + * progress + */ progress?: boolean | undefined; - reconnect?: number | boolean | undefined; - webSocketTransport?: string | undefined; - webSocketURL?: string | WebSocketURL | undefined; + /** + * reconnect + */ + reconnect?: (boolean | number) | undefined; + /** + * web socket transport + */ + webSocketTransport?: ("ws" | "sockjs" | string) | undefined; + /** + * web socket URL + */ + webSocketURL?: (string | WebSocketURL) | undefined; }; type Headers = | Array<{ @@ -1721,81 +1804,65 @@ type Configuration< typeof import("http").ServerResponse >, > = { - ipc?: string | boolean | undefined; - host?: string | undefined; + ipc?: (boolean | string) | undefined; + host?: Host | undefined; port?: Port | undefined; - hot?: boolean | "only" | undefined; + hot?: (boolean | "only") | undefined; liveReload?: boolean | undefined; - devMiddleware?: - | DevMiddlewareOptions< - import("express").Request< - import("express-serve-static-core").ParamsDictionary, - any, - any, - qs.ParsedQs, - Record - >, - import("express").Response> - > - | undefined; + devMiddleware?: DevMiddlewareOptions | undefined; compress?: boolean | undefined; - allowedHosts?: string | string[] | undefined; - historyApiFallback?: - | boolean - | import("connect-history-api-fallback").Options - | undefined; - bonjour?: - | boolean - | Record - | import("bonjour-service").Service - | undefined; + allowedHosts?: ("auto" | "all" | string | string[]) | undefined; + historyApiFallback?: (boolean | ConnectHistoryApiFallbackOptions) | undefined; + bonjour?: (boolean | Record | BonjourOptions) | undefined; watchFiles?: - | string - | string[] - | WatchFiles - | (string | WatchFiles)[] + | (string | string[] | WatchFiles | Array) | undefined; - static?: string | boolean | Static | (string | Static)[] | undefined; - server?: ServerType | ServerConfiguration | undefined; + static?: (boolean | string | Static | Array) | undefined; + server?: (ServerType | ServerConfiguration) | undefined; app?: (() => Promise) | undefined; - webSocketServer?: string | boolean | WebSocketServerConfiguration | undefined; + webSocketServer?: + | (boolean | "sockjs" | "ws" | string | WebSocketServerConfiguration) + | undefined; proxy?: ProxyConfigArray | undefined; - open?: string | boolean | Open | (string | Open)[] | undefined; + open?: (boolean | string | Open | Array) | undefined; setupExitSignals?: boolean | undefined; - client?: boolean | ClientConfiguration | undefined; + client?: (boolean | ClientConfiguration) | undefined; headers?: - | Headers - | (( - req: Request, - res: Response, - context: DevMiddlewareContext | undefined, - ) => Headers) + | ( + | Headers + | (( + req: Request, + res: Response, + context: DevMiddlewareContext | undefined, + ) => Headers) + ) | undefined; onListening?: ((devServer: Server) => void) | undefined; setupMiddlewares?: | ((middlewares: Middleware[], devServer: Server) => Middleware[]) | undefined; }; +type FunctionReturning = () => T; type BasicApplication = { use: typeof useFn; }; /** * @overload - * @param {NextHandleFunction} fn - * @returns {BasicApplication} + * @param {NextHandleFunction} fn function + * @returns {BasicApplication} application */ declare function useFn(fn: NextHandleFunction): BasicApplication; /** * @overload - * @param {HandleFunction} fn - * @returns {BasicApplication} + * @param {HandleFunction} fn function + * @returns {BasicApplication} application */ declare function useFn(fn: HandleFunction): BasicApplication; /** * @overload - * @param {string} route - * @param {NextHandleFunction} fn - * @returns {BasicApplication} + * @param {string} route route + * @param {NextHandleFunction} fn function + * @returns {BasicApplication} application */ declare function useFn(route: string, fn: NextHandleFunction): BasicApplication; diff --git a/types/lib/getPort.d.ts b/types/lib/getPort.d.ts index 358ae2c81d..677eb97671 100644 --- a/types/lib/getPort.d.ts +++ b/types/lib/getPort.d.ts @@ -1,8 +1,8 @@ export = getPorts; /** - * @param {number} basePort - * @param {string=} host - * @return {Promise} + * @param {number} basePort base port + * @param {string=} host host + * @returns {Promise} resolved port */ declare function getPorts( basePort: number, diff --git a/types/lib/servers/BaseServer.d.ts b/types/lib/servers/BaseServer.d.ts index 87aedf8ba9..07d29fb4b5 100644 --- a/types/lib/servers/BaseServer.d.ts +++ b/types/lib/servers/BaseServer.d.ts @@ -1,7 +1,7 @@ export = BaseServer; declare class BaseServer { /** - * @param {import("../Server")} server + * @param {import("../Server")} server server */ constructor(server: import("../Server")); /** @type {import("../Server")} */