From b0bb618d9921be0c7742ddcd03f39b7144322e38 Mon Sep 17 00:00:00 2001 From: Sebastian Beltran Date: Sun, 26 Apr 2026 13:06:37 -0500 Subject: [PATCH 01/29] refactor: migrate to ES module syntax --- babel.config.js | 6 +- bin/webpack-dev-server.js | 61 +- client-src/webpack.config.js | 11 +- commitlint.config.js | 4 +- eslint.config.mjs | 5 + lib/Server.js | 165 +++-- lib/getPort.js | 8 +- lib/servers/BaseServer.js | 12 +- lib/servers/WebsocketServer.js | 18 +- lint-staged.config.js | 4 +- package-lock.json | 499 +++++++------- package.json | 3 +- scripts/extend-webpack-types.js | 20 +- tsconfig.json | 10 +- types/lib/Server.d.ts | 915 ++++++++++++------------- types/lib/getPort.d.ts | 2 +- types/lib/servers/BaseServer.d.ts | 17 +- types/lib/servers/WebsocketServer.d.ts | 21 +- 18 files changed, 863 insertions(+), 918 deletions(-) diff --git a/babel.config.js b/babel.config.js index a34db39f39..07a5ee415b 100644 --- a/babel.config.js +++ b/babel.config.js @@ -1,6 +1,4 @@ -"use strict"; - -module.exports = (api) => { +export default (api) => { api.cache(true); return { @@ -24,7 +22,7 @@ module.exports = (api) => { "@babel/preset-env", { targets: { - node: "20.9.0", + node: "22.25.0", }, }, ], diff --git a/bin/webpack-dev-server.js b/bin/webpack-dev-server.js index de0cfd3b32..16e76b136b 100755 --- a/bin/webpack-dev-server.js +++ b/bin/webpack-dev-server.js @@ -2,17 +2,20 @@ /* Based on webpack/bin/webpack.js */ /* eslint-disable no-console */ -"use strict"; +import cp from "node:child_process"; +import nodeModule from "node:module"; +import path from "node:path"; +import readLine from "node:readline"; +import { fileURLToPath, pathToFileURL } from "node:url"; +import fs from "graceful-fs"; /** * @param {string} command process to run * @param {string[]} args command line arguments * @returns {Promise} promise */ -const runCommand = (command, args) => { - const cp = require("node:child_process"); - - return new Promise((resolve, reject) => { +const runCommand = (command, args) => + new Promise((resolve, reject) => { const executedCommand = cp.spawn(command, args, { stdio: "inherit", shell: true, @@ -30,7 +33,6 @@ const runCommand = (command, args) => { } }); }); -}; /** * @param {string} packageName name of the package @@ -41,10 +43,7 @@ const isInstalled = (packageName) => { return true; } - const path = require("node:path"); - const fs = require("graceful-fs"); - - let dir = __dirname; + let dir = path.dirname(fileURLToPath(import.meta.url)); do { try { @@ -58,9 +57,9 @@ const isInstalled = (packageName) => { } } while (dir !== (dir = path.dirname(dir))); - // https://github.com/nodejs/node/blob/v18.9.1/lib/internal/modules/cjs/loader.js#L1274 + // https://github.com/nodejs/node/blob/v22.12.0/lib/internal/modules/cjs/loader.js#L1818 // @ts-expect-error - for (const internalPath of require("node:module").globalPaths) { + for (const internalPath of nodeModule.globalPaths) { try { if (fs.statSync(path.join(internalPath, packageName)).isDirectory()) { return true; @@ -75,29 +74,20 @@ const isInstalled = (packageName) => { /** * @param {CliOption} cli options - * @returns {void} + * @returns {Promise} */ -const runCli = (cli) => { +const runCli = async (cli) => { if (cli.preprocess) { cli.preprocess(); } - const path = require("node:path"); + const pkgUrl = import.meta.resolve(`${cli.package}/package.json`); + const pkgPath = fileURLToPath(pkgUrl); + const pkg = (await import(pkgUrl, { with: { type: "json" } })).default; - const pkgPath = require.resolve(`${cli.package}/package.json`); + const binPath = path.resolve(path.dirname(pkgPath), pkg.bin[cli.binName]); - const pkg = require(pkgPath); - - if (pkg.type === "module" || /\.mjs/i.test(pkg.bin[cli.binName])) { - import(path.resolve(path.dirname(pkgPath), pkg.bin[cli.binName])).catch( - (error) => { - console.error(error); - process.exitCode = 1; - }, - ); - } else { - require(path.resolve(path.dirname(pkgPath), pkg.bin[cli.binName])); - } + await import(pathToFileURL(binPath).href); }; /** @@ -123,10 +113,6 @@ const cli = { }; if (!cli.installed) { - const path = require("node:path"); - const fs = require("graceful-fs"); - const readLine = require("node:readline"); - const notify = `CLI for webpack must be installed.\n ${cli.name} (${cli.url})\n`; console.error(notify); @@ -187,14 +173,17 @@ if (!cli.installed) { ); runCommand(packageManager, [...installOptions, cli.package]) - .then(() => { - runCli(cli); - }) + .then(() => runCli(cli)) .catch((error) => { console.error(error); process.exitCode = 1; }); }); } else { - runCli(cli); + try { + await runCli(cli); + } catch (error) { + console.error(error); + process.exitCode = 1; + } } diff --git a/client-src/webpack.config.js b/client-src/webpack.config.js index 7037f9406f..5aa430209b 100644 --- a/client-src/webpack.config.js +++ b/client-src/webpack.config.js @@ -1,8 +1,9 @@ -"use strict"; +import path from "node:path"; +import { fileURLToPath } from "node:url"; +import webpack from "webpack"; +import { merge } from "webpack-merge"; -const path = require("node:path"); -const webpack = require("webpack"); -const { merge } = require("webpack-merge"); +const __dirname = path.dirname(fileURLToPath(import.meta.url)); const library = { library: { @@ -37,7 +38,7 @@ const baseForModules = { }, }; -module.exports = [ +export default [ merge(baseForModules, { entry: path.join(__dirname, "modules/logger/index.js"), output: { diff --git a/commitlint.config.js b/commitlint.config.js index 1698d22ed8..f0f7617e9e 100644 --- a/commitlint.config.js +++ b/commitlint.config.js @@ -1,6 +1,4 @@ -"use strict"; - -module.exports = { +export default { extends: ["@commitlint/config-conventional"], rules: { "header-max-length": [0], diff --git a/eslint.config.mjs b/eslint.config.mjs index 6cd919c421..6d19bb4671 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -7,6 +7,11 @@ export default defineConfig([ { extends: [config], ignores: ["client-src/**/*", "!client-src/webpack.config.js"], + languageOptions: { + // ES2025 needed for import attributes (`import(x, { with: ... })`). + // eslint-config-webpack pins ecmaVersion to 2024 for Node 22. + ecmaVersion: "latest", + }, rules: { // TODO fix me "prefer-destructuring": "off", diff --git a/lib/Server.js b/lib/Server.js index 70f131041f..6dfdf90c23 100644 --- a/lib/Server.js +++ b/lib/Server.js @@ -1,14 +1,21 @@ -"use strict"; - -const os = require("node:os"); -const path = require("node:path"); -const url = require("node:url"); -const fs = require("graceful-fs"); -const ipaddr = require("ipaddr.js"); -const { validate } = require("schema-utils"); -const schema = require("./options.json"); +import net from "node:net"; +import os from "node:os"; +import path from "node:path"; +import url, { fileURLToPath } from "node:url"; +import fs from "graceful-fs"; +import ipaddr from "ipaddr.js"; +import { validate } from "schema-utils"; +import schema from "./options.json" with { type: "json" }; + +/** @type {typeof import("webpack") | undefined} */ +let webpackPeer; +try { + webpackPeer = (await import("webpack")).default; +} catch { + // webpack is an optional peer dependency +} -/** @typedef {import("schema-utils/declarations/validate").Schema} Schema */ +/** @typedef {import("schema-utils").Schema} Schema */ /** @typedef {import("webpack").Compiler} Compiler */ /** @typedef {import("webpack").MultiCompiler} MultiCompiler */ /** @typedef {import("webpack").Configuration} WebpackConfiguration */ @@ -266,7 +273,7 @@ const memoize = (fn) => { }; }; -const getExpress = memoize(() => require("express")); +const getExpress = memoize(async () => (await import("express")).default); /** * @param {OverlayMessageOptions=} setting overlay settings @@ -495,9 +502,8 @@ class Server { return port; } - const pRetry = (await import("p-retry")).default; - - const getPort = require("./getPort"); + const { default: pRetry } = await import("p-retry"); + const { default: getPort } = await import("./getPort.js"); const basePort = typeof process.env.WEBPACK_DEV_SERVER_BASE_PORT !== "undefined" @@ -738,7 +744,9 @@ class Server { additionalEntries.push(clientHotEntry); } - const webpack = compiler.webpack || require("webpack"); + const webpack = + compiler.webpack || + /** @type {NonNullable} */ (webpackPeer); // use a hook to add entries if available for (const additionalEntry of additionalEntries) { @@ -1139,7 +1147,7 @@ class Server { if (!certificateExists) { this.logger.info("Generating SSL certificate..."); - const selfsigned = require("selfsigned"); + const { default: selfsigned } = await import("selfsigned"); const attributes = [{ name: "commonName", value: "localhost" }]; const notBeforeDate = new Date(); @@ -1477,14 +1485,16 @@ class Server { switch (typeof clientTransport) { case "string": - // could be 'ws', or a path that should be required + // could be 'ws', or a path that should be resolved if (clientTransport === "ws") { - clientImplementation = require.resolve( - "../client/clients/WebSocketClient", + clientImplementation = fileURLToPath( + import.meta.resolve("../client/clients/WebSocketClient.js"), ); } else { try { - clientImplementation = require.resolve(clientTransport); + clientImplementation = fileURLToPath( + import.meta.resolve(clientTransport), + ); } catch { clientImplementationFound = false; } @@ -1500,7 +1510,7 @@ class Server { !isKnownWebSocketServerImplementation ? "When you use custom web socket implementation you must explicitly specify client.webSocketTransport. " : "" - }client.webSocketTransport must be a string denoting a default implementation (e.g. 'ws') or a full path to a JS file via require.resolve(...) which exports a class `, + }client.webSocketTransport must be a string denoting a default implementation (e.g. 'ws') or a resolvable module specifier or absolute file path which exports a class `, ); } @@ -1510,9 +1520,9 @@ class Server { /** * @template T * @private - * @returns {T} server transport + * @returns {Promise} server transport */ - getServerTransport() { + async getServerTransport() { let implementation; let implementationFound = true; @@ -1529,13 +1539,17 @@ class Server { this.options.webSocketServer ).type === "ws" ) { - implementation = require("./servers/WebsocketServer"); + implementation = (await import("./servers/WebsocketServer.js")) + .default; } else { try { - implementation = require( - /** @type {WebSocketServerConfiguration} */ - (this.options.webSocketServer).type, + const mod = await import( + /** @type {string} */ ( + /** @type {WebSocketServerConfiguration} */ + (this.options.webSocketServer).type + ) ); + implementation = mod.default || mod; } catch { implementationFound = false; } @@ -1552,9 +1566,9 @@ class Server { if (!implementationFound) { throw new Error( - "webSocketServer (webSocketServer.type) must be a string denoting a default implementation (e.g. 'ws'), a full path to " + - "a JS file which exports a class extending BaseServer (webpack-dev-server/lib/servers/BaseServer.js) " + - "via require.resolve(...), or the class itself which extends BaseServer", + "webSocketServer (webSocketServer.type) must be a string denoting a default implementation (e.g. 'ws'), a resolvable module specifier or absolute file path " + + "which exports a class extending BaseServer (webpack-dev-server/lib/servers/BaseServer.js), " + + "or the class itself which extends BaseServer", ); } @@ -1566,7 +1580,7 @@ class Server { */ getClientEntry() { - return require.resolve("../client/index.js"); + return fileURLToPath(import.meta.resolve("../client/index.js")); } /** @@ -1574,9 +1588,9 @@ class Server { */ getClientHotEntry() { if (this.options.hot === "only") { - return require.resolve("webpack/hot/only-dev-server"); + return fileURLToPath(import.meta.resolve("webpack/hot/only-dev-server")); } else if (this.options.hot) { - return require.resolve("webpack/hot/dev-server"); + return fileURLToPath(import.meta.resolve("webpack/hot/dev-server")); } } @@ -1646,7 +1660,9 @@ class Server { this.addAdditionalEntries(compiler); - const webpack = compiler.webpack || require("webpack"); + const webpack = + compiler.webpack || + /** @type {NonNullable} */ (webpackPeer); new webpack.ProvidePlugin({ __webpack_dev_server_client__: this.getClientTransport(), @@ -1680,9 +1696,9 @@ class Server { } } - this.setupWatchFiles(); - this.setupWatchStaticFiles(); - this.setupMiddlewares(); + await this.setupWatchFiles(); + await this.setupWatchStaticFiles(); + await this.setupMiddlewares(); if (this.options.setupExitSignals) { const signals = ["SIGINT", "SIGTERM"]; @@ -1749,7 +1765,7 @@ class Server { ( typeof this.options.app === "function" ? await this.options.app() - : getExpress()() + : (await getExpress())() ); } @@ -1805,15 +1821,15 @@ class Server { /** * @private - * @returns {void} + * @returns {Promise} */ - setupWatchStaticFiles() { + async setupWatchStaticFiles() { const watchFiles = /** @type {NormalizedStatic[]} */ (this.options.static); if (watchFiles.length > 0) { for (const item of watchFiles) { if (item.watch) { - this.watchFiles(item.directory, item.watch); + await this.watchFiles(item.directory, item.watch); } } } @@ -1821,23 +1837,23 @@ class Server { /** * @private - * @returns {void} + * @returns {Promise} */ - setupWatchFiles() { + async setupWatchFiles() { const watchFiles = /** @type {WatchFiles[]} */ (this.options.watchFiles); if (watchFiles.length > 0) { for (const item of watchFiles) { - this.watchFiles(item.paths, item.options); + await this.watchFiles(item.paths, item.options); } } } /** * @private - * @returns {void} + * @returns {Promise} */ - setupMiddlewares() { + async setupMiddlewares() { /** * @type {Array} */ @@ -1926,7 +1942,7 @@ class Server { // compress is placed last and uses unshift so that it will be the first middleware used if (this.options.compress) { - const compression = require("compression"); + const { default: compression } = await import("compression"); middlewares.push({ name: "compression", middleware: compression() }); } @@ -1971,9 +1987,9 @@ class Server { * @param {Request} req request * @param {Response} res response * @param {NextFunction} next next function - * @returns {void} + * @returns {Promise} */ - middleware: (req, res, next) => { + middleware: async (req, res, next) => { if (req.method !== "GET" && req.method !== "HEAD") { next(); return; @@ -1989,7 +2005,7 @@ class Server { const fileName = params.get("fileName"); if (typeof fileName === "string") { - const launchEditor = require("launch-editor"); + const { default: launchEditor } = await import("launch-editor"); launchEditor(fileName); } @@ -2082,7 +2098,7 @@ class Server { }); if (this.options.proxy) { - const { createProxyMiddleware } = require("http-proxy-middleware"); + const { createProxyMiddleware } = await import("http-proxy-middleware"); /** * @param {ProxyConfigArrayItem} proxyConfig proxy config @@ -2200,7 +2216,7 @@ class Server { middlewares.push({ name: "express-static", path: publicPath, - middleware: getExpress().static( + middleware: (await getExpress()).static( staticOption.directory, staticOption.staticOptions, ), @@ -2210,7 +2226,9 @@ class Server { } if (this.options.historyApiFallback) { - const connectHistoryApiFallback = require("connect-history-api-fallback"); + const { default: connectHistoryApiFallback } = await import( + "connect-history-api-fallback" + ); const { historyApiFallback } = this.options; @@ -2253,7 +2271,7 @@ class Server { middlewares.push({ name: "express-static", path: publicPath, - middleware: getExpress().static( + middleware: (await getExpress()).static( staticOption.directory, staticOption.staticOptions, ), @@ -2264,7 +2282,7 @@ class Server { } if (staticOptions.length > 0) { - const serveIndex = require("serve-index"); + const { default: serveIndex } = await import("serve-index"); for (const staticOption of staticOptions) { for (const publicPath of staticOption.publicPath) { @@ -2321,11 +2339,13 @@ class Server { middlewares = this.options.setupMiddlewares(middlewares, this); } + const { default: webpackDevMiddleware } = await import( + "webpack-dev-middleware" + ); + // Lazy init webpack dev middleware const lazyInitDevMiddleware = () => { if (!this.middleware) { - const webpackDevMiddleware = require("webpack-dev-middleware"); - // middleware for serving webpack bundle /** @type {import("webpack-dev-middleware").API} */ this.middleware = webpackDevMiddleware( @@ -2389,7 +2409,8 @@ class Server { (this.app), ); } else { - const serverType = require(/** @type {string} */ (type)); + const mod = await import(/** @type {string} */ (type)); + const serverType = mod.default || mod; /** @type {S | undefined} */ this.server = @@ -2437,11 +2458,11 @@ class Server { /** * @private - * @returns {void} + * @returns {Promise} */ - createWebSocketServer() { + async createWebSocketServer() { /** @type {WebSocketServerImplementation | undefined | null} */ - this.webSocketServer = new (this.getServerTransport())(this); + this.webSocketServer = new (await this.getServerTransport())(this); /** @type {WebSocketServerImplementation} */ (this.webSocketServer).implementation.on( @@ -2601,10 +2622,10 @@ class Server { /** * @private - * @returns {void} + * @returns {Promise} */ - runBonjour() { - const { Bonjour } = require("bonjour-service"); + async runBonjour() { + const { Bonjour } = await import("bonjour-service"); const type = this.isTlsServer ? "https" : "http"; @@ -3170,11 +3191,11 @@ class Server { /** * @param {string | string[]} watchPath watch path * @param {WatchOptions=} watchOptions watch options + * @returns {Promise} */ - watchFiles(watchPath, watchOptions = {}) { - const chokidar = require("chokidar"); - const path = require("node:path"); - const { globSync, isDynamicPattern } = require("tinyglobby"); + async watchFiles(watchPath, watchOptions = {}) { + const { default: chokidar } = await import("chokidar"); + const { globSync, isDynamicPattern } = await import("tinyglobby"); const isWin = path.sep === "\\"; const toPosix = (/** @type {string} */ filePath) => @@ -3242,8 +3263,6 @@ class Server { if (this.options.ipc) { await /** @type {Promise} */ ( new Promise((resolve, reject) => { - const net = require("node:net"); - const socket = new net.Socket(); socket.on( @@ -3313,11 +3332,11 @@ class Server { } if (this.options.webSocketServer) { - this.createWebSocketServer(); + await this.createWebSocketServer(); } if (this.options.bonjour) { - this.runBonjour(); + await this.runBonjour(); } await this.logStatus(); @@ -3442,4 +3461,4 @@ class Server { } } -module.exports = Server; +export default Server; diff --git a/lib/getPort.js b/lib/getPort.js index 23bc4e348a..032e41f31b 100644 --- a/lib/getPort.js +++ b/lib/getPort.js @@ -1,13 +1,11 @@ -"use strict"; - /* * Based on the packages get-port https://www.npmjs.com/package/get-port * and portfinder https://www.npmjs.com/package/portfinder * The code structure is similar to get-port, but it searches * ports deterministically like portfinder */ -const net = require("node:net"); -const os = require("node:os"); +import net from "node:net"; +import os from "node:os"; const minPort = 1024; const maxPort = 65_535; @@ -129,4 +127,4 @@ async function getPorts(basePort, host) { throw new Error("No available ports found"); } -module.exports = getPorts; +export default getPorts; diff --git a/lib/servers/BaseServer.js b/lib/servers/BaseServer.js index 9f5a18f4e0..13079303b8 100644 --- a/lib/servers/BaseServer.js +++ b/lib/servers/BaseServer.js @@ -1,18 +1,16 @@ -"use strict"; - -/** @typedef {import("../Server").ClientConnection} ClientConnection */ +/** @typedef {import("../Server.js").ClientConnection} ClientConnection */ // base class that users should extend if they are making their own // server implementation -module.exports = class BaseServer { +export default class BaseServer { /** - * @param {import("../Server")} server server + * @param {import("../Server.js").default} server server */ constructor(server) { - /** @type {import("../Server")} */ + /** @type {import("../Server.js").default} */ this.server = server; /** @type {ClientConnection[]} */ this.clients = []; } -}; +} diff --git a/lib/servers/WebsocketServer.js b/lib/servers/WebsocketServer.js index b9071f4bd3..cc3f7b635b 100644 --- a/lib/servers/WebsocketServer.js +++ b/lib/servers/WebsocketServer.js @@ -1,16 +1,14 @@ -"use strict"; +import { WebSocketServer as WsServer } from "ws"; +import BaseServer from "./BaseServer.js"; -const WebSocket = require("ws"); -const BaseServer = require("./BaseServer"); +/** @typedef {import("../Server.js").WebSocketServerConfiguration} WebSocketServerConfiguration */ +/** @typedef {import("../Server.js").ClientConnection} ClientConnection */ -/** @typedef {import("../Server").WebSocketServerConfiguration} WebSocketServerConfiguration */ -/** @typedef {import("../Server").ClientConnection} ClientConnection */ - -module.exports = class WebsocketServer extends BaseServer { +export default class WebsocketServer extends BaseServer { static heartbeatInterval = 1000; /** - * @param {import("../Server")} server server + * @param {import("../Server.js").default} server server */ constructor(server) { super(server); @@ -29,7 +27,7 @@ module.exports = class WebsocketServer extends BaseServer { options.noServer = true; } - this.implementation = new WebSocket.Server(options); + this.implementation = new WsServer(options); /** @type {import("http").Server} */ (this.server.server).on( @@ -108,4 +106,4 @@ module.exports = class WebsocketServer extends BaseServer { clearInterval(interval); }); } -}; +} diff --git a/lint-staged.config.js b/lint-staged.config.js index 2d40a32b75..50d30973d9 100644 --- a/lint-staged.config.js +++ b/lint-staged.config.js @@ -1,6 +1,4 @@ -"use strict"; - -module.exports = { +export default { "*": [ "prettier --cache --write --ignore-unknown", "cspell --cache --no-must-find-files", diff --git a/package-lock.json b/package-lock.json index f66ab5146e..1e5ddc4db3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -44,7 +44,7 @@ "@babel/eslint-parser": "^7.28.6", "@babel/plugin-transform-object-assign": "^7.27.1", "@babel/plugin-transform-runtime": "^7.29.0", - "@babel/preset-env": "^7.25.9", + "@babel/preset-env": "^7.29.2", "@babel/runtime": "^7.29.2", "@commitlint/cli": "^19.5.0", "@commitlint/config-conventional": "^19.5.0", @@ -392,18 +392,18 @@ } }, "node_modules/@babel/helper-create-class-features-plugin": { - "version": "7.28.3", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.28.3.tgz", - "integrity": "sha512-V9f6ZFIYSLNEbuGA/92uOvYsGCJNsuA8ESZ4ldc09bWk/j8H8TKiPw8Mk1eG6olpnO0ALHJmYfZvF4MEE4gajg==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.28.6.tgz", + "integrity": "sha512-dTOdvsjnG3xNT9Y0AUg1wAl38y+4Rl4sf9caSQZOXdNqVn+H+HbbJ4IyyHaIqNR6SW9oJpA/RuRjsjCw2IdIow==", "dev": true, "license": "MIT", "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", - "@babel/helper-member-expression-to-functions": "^7.27.1", + "@babel/helper-member-expression-to-functions": "^7.28.5", "@babel/helper-optimise-call-expression": "^7.27.1", - "@babel/helper-replace-supers": "^7.27.1", + "@babel/helper-replace-supers": "^7.28.6", "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", - "@babel/traverse": "^7.28.3", + "@babel/traverse": "^7.28.6", "semver": "^6.3.1" }, "engines": { @@ -414,14 +414,14 @@ } }, "node_modules/@babel/helper-create-regexp-features-plugin": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.27.1.tgz", - "integrity": "sha512-uVDC72XVf8UbrH5qQTc18Agb8emwjTiZrQE11Nv3CuBEZmVvTwwE9CBUEvHku06gQCAyYf8Nv6ja1IN+6LMbxQ==", + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.28.5.tgz", + "integrity": "sha512-N1EhvLtHzOvj7QQOUCCS3NrPJP8c5W6ZXCHDn7Yialuy1iu4r5EmIYkXlKNqT99Ciw+W0mDqWoR6HWMZlFP3hw==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-annotate-as-pure": "^7.27.1", - "regexpu-core": "^6.2.0", + "@babel/helper-annotate-as-pure": "^7.27.3", + "regexpu-core": "^6.3.1", "semver": "^6.3.1" }, "engines": { @@ -432,17 +432,17 @@ } }, "node_modules/@babel/helper-define-polyfill-provider": { - "version": "0.6.5", - "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.5.tgz", - "integrity": "sha512-uJnGFcPsWQK8fvjgGP5LZUZZsYGIoPeRjSF5PGwrelYgq7Q15/Ft9NGFp1zglwgIv//W0uG4BevRuSJRyylZPg==", + "version": "0.6.8", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.8.tgz", + "integrity": "sha512-47UwBLPpQi1NoWzLuHNjRoHlYXMwIJoBf7MFou6viC/sIHWYygpvr0B6IAyh5sBdA2nr2LPIRww8lfaUVQINBA==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-compilation-targets": "^7.27.2", - "@babel/helper-plugin-utils": "^7.27.1", - "debug": "^4.4.1", + "@babel/helper-compilation-targets": "^7.28.6", + "@babel/helper-plugin-utils": "^7.28.6", + "debug": "^4.4.3", "lodash.debounce": "^4.0.8", - "resolve": "^1.22.10" + "resolve": "^1.22.11" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" @@ -459,14 +459,14 @@ } }, "node_modules/@babel/helper-member-expression-to-functions": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.27.1.tgz", - "integrity": "sha512-E5chM8eWjTp/aNoVpcbfM7mLxu9XGLWYise2eBKGQomAk/Mb4XoxyqXTZbuTohbsl8EKqdlMhnDI2CCLfcs9wA==", + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.28.5.tgz", + "integrity": "sha512-cwM7SBRZcPCLgl8a7cY0soT1SptSzAlMH39vwiRpOQkJlh53r5hdHwLSCZpQdVLT39sZt+CRpNwYG4Y2v77atg==", "dev": true, "license": "MIT", "dependencies": { - "@babel/traverse": "^7.27.1", - "@babel/types": "^7.27.1" + "@babel/traverse": "^7.28.5", + "@babel/types": "^7.28.5" }, "engines": { "node": ">=6.9.0" @@ -546,15 +546,15 @@ } }, "node_modules/@babel/helper-replace-supers": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.27.1.tgz", - "integrity": "sha512-7EHz6qDZc8RYS5ElPoShMheWvEgERonFCs7IAonWLLUTXW59DP14bCZt89/GKyreYn8g3S83m21FelHKbeDCKA==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.28.6.tgz", + "integrity": "sha512-mq8e+laIk94/yFec3DxSjCRD2Z0TAjhVbEJY3UQrlwVo15Lmt7C2wAUbK4bjnTs4APkwsYLTahXRraQXhb1WCg==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-member-expression-to-functions": "^7.27.1", + "@babel/helper-member-expression-to-functions": "^7.28.5", "@babel/helper-optimise-call-expression": "^7.27.1", - "@babel/traverse": "^7.27.1" + "@babel/traverse": "^7.28.6" }, "engines": { "node": ">=6.9.0" @@ -608,15 +608,15 @@ } }, "node_modules/@babel/helper-wrap-function": { - "version": "7.28.3", - "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.28.3.tgz", - "integrity": "sha512-zdf983tNfLZFletc0RRXYrHrucBEg95NIFMkn6K9dbeMYnsgHaSBGcQqdsCSStG2PYwRre0Qc2NNSCXbG+xc6g==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.28.6.tgz", + "integrity": "sha512-z+PwLziMNBeSQJonizz2AGnndLsP2DeGHIxDAn+wdHOGuo4Fo1x1HBPPXeE9TAOPHNNWQKCSlA2VZyYyyibDnQ==", "dev": true, "license": "MIT", "dependencies": { - "@babel/template": "^7.27.2", - "@babel/traverse": "^7.28.3", - "@babel/types": "^7.28.2" + "@babel/template": "^7.28.6", + "@babel/traverse": "^7.28.6", + "@babel/types": "^7.28.6" }, "engines": { "node": ">=6.9.0" @@ -720,14 +720,14 @@ } }, "node_modules/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": { - "version": "7.28.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.28.3.tgz", - "integrity": "sha512-b6YTX108evsvE4YgWyQ921ZAFFQm3Bn+CA3+ZXlNVnPhx+UfsVURoPjfGAPCjBgrqo30yX/C2nZGX96DxvR9Iw==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.28.6.tgz", + "integrity": "sha512-a0aBScVTlNaiUe35UtfxAN7A/tehvvG4/ByO6+46VPKTRSlfnAFsgKy0FUh+qAkQrDTmhDkT+IBOKlOoMUxQ0g==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/traverse": "^7.28.3" + "@babel/helper-plugin-utils": "^7.28.6", + "@babel/traverse": "^7.28.6" }, "engines": { "node": ">=6.9.0" @@ -750,13 +750,13 @@ } }, "node_modules/@babel/plugin-syntax-import-assertions": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.27.1.tgz", - "integrity": "sha512-UT/Jrhw57xg4ILHLFnzFpPDlMbcdEicaAtjPQpbj9wa8T4r5KVWCimHcL/460g8Ht0DMxDyjsLgiWSkVjnwPFg==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.28.6.tgz", + "integrity": "sha512-pSJUpFHdx9z5nqTSirOCMtYVP2wFgoWhP0p3g8ONK/4IHhLIBd0B9NYqAvIUAhq+OkhO4VM1tENCt0cjlsNShw==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" + "@babel/helper-plugin-utils": "^7.28.6" }, "engines": { "node": ">=6.9.0" @@ -766,13 +766,13 @@ } }, "node_modules/@babel/plugin-syntax-import-attributes": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.27.1.tgz", - "integrity": "sha512-oFT0FrKHgF53f4vOsZGi2Hh3I35PfSmVs4IBFLFj4dnafP+hIWDLg3VyKmUHfLoLHlyxY4C7DGtmHuJgn+IGww==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.28.6.tgz", + "integrity": "sha512-jiLC0ma9XkQT3TKJ9uYvlakm66Pamywo+qwL+oL8HJOvc6TWdZXVfhqJr8CCzbSGUAbDOzlGHJC1U+vRfLQDvw==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" + "@babel/helper-plugin-utils": "^7.28.6" }, "engines": { "node": ">=6.9.0" @@ -815,15 +815,15 @@ } }, "node_modules/@babel/plugin-transform-async-generator-functions": { - "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.28.0.tgz", - "integrity": "sha512-BEOdvX4+M765icNPZeidyADIvQ1m1gmunXufXxvRESy/jNNyfovIqUyE7MVgGBjWktCoJlzvFA1To2O4ymIO3Q==", + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.29.0.tgz", + "integrity": "sha512-va0VdWro4zlBr2JsXC+ofCPB2iG12wPtVGTWFx2WLDOM3nYQZZIGP82qku2eW/JR83sD+k2k+CsNtyEbUqhU6w==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-plugin-utils": "^7.28.6", "@babel/helper-remap-async-to-generator": "^7.27.1", - "@babel/traverse": "^7.28.0" + "@babel/traverse": "^7.29.0" }, "engines": { "node": ">=6.9.0" @@ -833,14 +833,14 @@ } }, "node_modules/@babel/plugin-transform-async-to-generator": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.27.1.tgz", - "integrity": "sha512-NREkZsZVJS4xmTr8qzE5y8AfIPqsdQfRuUiLRTEzb7Qii8iFWCyDKaUV2c0rCuh4ljDZ98ALHP/PetiBV2nddA==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.28.6.tgz", + "integrity": "sha512-ilTRcmbuXjsMmcZ3HASTe4caH5Tpo93PkTxF9oG2VZsSWsahydmcEHhix9Ik122RcTnZnUzPbmux4wh1swfv7g==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-module-imports": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-module-imports": "^7.28.6", + "@babel/helper-plugin-utils": "^7.28.6", "@babel/helper-remap-async-to-generator": "^7.27.1" }, "engines": { @@ -867,13 +867,13 @@ } }, "node_modules/@babel/plugin-transform-block-scoping": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.28.5.tgz", - "integrity": "sha512-45DmULpySVvmq9Pj3X9B+62Xe+DJGov27QravQJU1LLcapR6/10i+gYVAucGGJpHBp5mYxIMK4nDAT/QDLr47g==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.28.6.tgz", + "integrity": "sha512-tt/7wOtBmwHPNMPu7ax4pdPz6shjFrmHDghvNC+FG9Qvj7D6mJcoRQIF5dy4njmxR941l6rgtvfSB2zX3VlUIw==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" + "@babel/helper-plugin-utils": "^7.28.6" }, "engines": { "node": ">=6.9.0" @@ -883,14 +883,14 @@ } }, "node_modules/@babel/plugin-transform-class-properties": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.27.1.tgz", - "integrity": "sha512-D0VcalChDMtuRvJIu3U/fwWjf8ZMykz5iZsg77Nuj821vCKI3zCyRLwRdWbsuJ/uRwZhZ002QtCqIkwC/ZkvbA==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.28.6.tgz", + "integrity": "sha512-dY2wS3I2G7D697VHndN91TJr8/AAfXQNt5ynCTI/MpxMsSzHp+52uNivYT5wCPax3whc47DR8Ba7cmlQMg24bw==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1" + "@babel/helper-create-class-features-plugin": "^7.28.6", + "@babel/helper-plugin-utils": "^7.28.6" }, "engines": { "node": ">=6.9.0" @@ -900,14 +900,14 @@ } }, "node_modules/@babel/plugin-transform-class-static-block": { - "version": "7.28.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.28.3.tgz", - "integrity": "sha512-LtPXlBbRoc4Njl/oh1CeD/3jC+atytbnf/UqLoqTDcEYGUPj022+rvfkbDYieUrSj3CaV4yHDByPE+T2HwfsJg==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.28.6.tgz", + "integrity": "sha512-rfQ++ghVwTWTqQ7w8qyDxL1XGihjBss4CmTgGRCTAC9RIbhVpyp4fOeZtta0Lbf+dTNIVJer6ych2ibHwkZqsQ==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.28.3", - "@babel/helper-plugin-utils": "^7.27.1" + "@babel/helper-create-class-features-plugin": "^7.28.6", + "@babel/helper-plugin-utils": "^7.28.6" }, "engines": { "node": ">=6.9.0" @@ -917,18 +917,18 @@ } }, "node_modules/@babel/plugin-transform-classes": { - "version": "7.28.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.28.4.tgz", - "integrity": "sha512-cFOlhIYPBv/iBoc+KS3M6et2XPtbT2HiCRfBXWtfpc9OAyostldxIf9YAYB6ypURBBbx+Qv6nyrLzASfJe+hBA==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.28.6.tgz", + "integrity": "sha512-EF5KONAqC5zAqT783iMGuM2ZtmEBy+mJMOKl2BCvPZ2lVrwvXnB6o+OBWCS+CoeCCpVRF2sA2RBKUxvT8tQT5Q==", "dev": true, "license": "MIT", "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", - "@babel/helper-compilation-targets": "^7.27.2", + "@babel/helper-compilation-targets": "^7.28.6", "@babel/helper-globals": "^7.28.0", - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/helper-replace-supers": "^7.27.1", - "@babel/traverse": "^7.28.4" + "@babel/helper-plugin-utils": "^7.28.6", + "@babel/helper-replace-supers": "^7.28.6", + "@babel/traverse": "^7.28.6" }, "engines": { "node": ">=6.9.0" @@ -938,14 +938,14 @@ } }, "node_modules/@babel/plugin-transform-computed-properties": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.27.1.tgz", - "integrity": "sha512-lj9PGWvMTVksbWiDT2tW68zGS/cyo4AkZ/QTp0sQT0mjPopCmrSkzxeXkznjqBxzDI6TclZhOJbBmbBLjuOZUw==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.28.6.tgz", + "integrity": "sha512-bcc3k0ijhHbc2lEfpFHgx7eYw9KNXqOerKWfzbxEHUGKnS3sz9C4CNL9OiFN1297bDNfUiSO7DaLzbvHQQQ1BQ==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/template": "^7.27.1" + "@babel/helper-plugin-utils": "^7.28.6", + "@babel/template": "^7.28.6" }, "engines": { "node": ">=6.9.0" @@ -972,14 +972,14 @@ } }, "node_modules/@babel/plugin-transform-dotall-regex": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.27.1.tgz", - "integrity": "sha512-gEbkDVGRvjj7+T1ivxrfgygpT7GUd4vmODtYpbs0gZATdkX8/iSnOtZSxiZnsgm1YjTgjI6VKBGSJJevkrclzw==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.28.6.tgz", + "integrity": "sha512-SljjowuNKB7q5Oayv4FoPzeB74g3QgLt8IVJw9ADvWy3QnUb/01aw8I4AVv8wYnPvQz2GDDZ/g3GhcNyDBI4Bg==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1" + "@babel/helper-create-regexp-features-plugin": "^7.28.5", + "@babel/helper-plugin-utils": "^7.28.6" }, "engines": { "node": ">=6.9.0" @@ -1005,14 +1005,14 @@ } }, "node_modules/@babel/plugin-transform-duplicate-named-capturing-groups-regex": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-named-capturing-groups-regex/-/plugin-transform-duplicate-named-capturing-groups-regex-7.27.1.tgz", - "integrity": "sha512-hkGcueTEzuhB30B3eJCbCYeCaaEQOmQR0AdvzpD4LoN0GXMWzzGSuRrxR2xTnCrvNbVwK9N6/jQ92GSLfiZWoQ==", + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-named-capturing-groups-regex/-/plugin-transform-duplicate-named-capturing-groups-regex-7.29.0.tgz", + "integrity": "sha512-zBPcW2lFGxdiD8PUnPwJjag2J9otbcLQzvbiOzDxpYXyCuYX9agOwMPGn1prVH0a4qzhCKu24rlH4c1f7yA8rw==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1" + "@babel/helper-create-regexp-features-plugin": "^7.28.5", + "@babel/helper-plugin-utils": "^7.28.6" }, "engines": { "node": ">=6.9.0" @@ -1038,14 +1038,14 @@ } }, "node_modules/@babel/plugin-transform-explicit-resource-management": { - "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-explicit-resource-management/-/plugin-transform-explicit-resource-management-7.28.0.tgz", - "integrity": "sha512-K8nhUcn3f6iB+P3gwCv/no7OdzOZQcKchW6N389V6PD8NUWKZHzndOd9sPDVbMoBsbmjMqlB4L9fm+fEFNVlwQ==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-explicit-resource-management/-/plugin-transform-explicit-resource-management-7.28.6.tgz", + "integrity": "sha512-Iao5Konzx2b6g7EPqTy40UZbcdXE126tTxVFr/nAIj+WItNxjKSYTEw3RC+A2/ZetmdJsgueL1KhaMCQHkLPIg==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/plugin-transform-destructuring": "^7.28.0" + "@babel/helper-plugin-utils": "^7.28.6", + "@babel/plugin-transform-destructuring": "^7.28.5" }, "engines": { "node": ">=6.9.0" @@ -1055,13 +1055,13 @@ } }, "node_modules/@babel/plugin-transform-exponentiation-operator": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.28.5.tgz", - "integrity": "sha512-D4WIMaFtwa2NizOp+dnoFjRez/ClKiC2BqqImwKd1X28nqBtZEyCYJ2ozQrrzlxAFrcrjxo39S6khe9RNDlGzw==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.28.6.tgz", + "integrity": "sha512-WitabqiGjV/vJ0aPOLSFfNY1u9U3R7W36B03r5I2KoNix+a3sOhJ3pKFB3R5It9/UiK78NiO0KE9P21cMhlPkw==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" + "@babel/helper-plugin-utils": "^7.28.6" }, "engines": { "node": ">=6.9.0" @@ -1122,13 +1122,13 @@ } }, "node_modules/@babel/plugin-transform-json-strings": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.27.1.tgz", - "integrity": "sha512-6WVLVJiTjqcQauBhn1LkICsR2H+zm62I3h9faTDKt1qP4jn2o72tSvqMwtGFKGTpojce0gJs+76eZ2uCHRZh0Q==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.28.6.tgz", + "integrity": "sha512-Nr+hEN+0geQkzhbdgQVPoqr47lZbm+5fCUmO70722xJZd0Mvb59+33QLImGj6F+DkK3xgDi1YVysP8whD6FQAw==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" + "@babel/helper-plugin-utils": "^7.28.6" }, "engines": { "node": ">=6.9.0" @@ -1154,13 +1154,13 @@ } }, "node_modules/@babel/plugin-transform-logical-assignment-operators": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.28.5.tgz", - "integrity": "sha512-axUuqnUTBuXyHGcJEVVh9pORaN6wC5bYfE7FGzPiaWa3syib9m7g+/IT/4VgCOe2Upef43PHzeAvcrVek6QuuA==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.28.6.tgz", + "integrity": "sha512-+anKKair6gpi8VsM/95kmomGNMD0eLz1NQ8+Pfw5sAwWH9fGYXT50E55ZpV0pHUHWf6IUTWPM+f/7AAff+wr9A==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" + "@babel/helper-plugin-utils": "^7.28.6" }, "engines": { "node": ">=6.9.0" @@ -1203,14 +1203,14 @@ } }, "node_modules/@babel/plugin-transform-modules-commonjs": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.27.1.tgz", - "integrity": "sha512-OJguuwlTYlN0gBZFRPqwOGNWssZjfIUdS7HMYtN8c1KmwpwHFBwTeFZrg9XZa+DFTitWOW5iTAG7tyCUPsCCyw==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.28.6.tgz", + "integrity": "sha512-jppVbf8IV9iWWwWTQIxJMAJCWBuuKx71475wHwYytrRGQ2CWiDvYlADQno3tcYpS/T2UUWFQp3nVtYfK/YBQrA==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-module-transforms": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1" + "@babel/helper-module-transforms": "^7.28.6", + "@babel/helper-plugin-utils": "^7.28.6" }, "engines": { "node": ">=6.9.0" @@ -1220,16 +1220,16 @@ } }, "node_modules/@babel/plugin-transform-modules-systemjs": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.28.5.tgz", - "integrity": "sha512-vn5Jma98LCOeBy/KpeQhXcV2WZgaRUtjwQmjoBuLNlOmkg0fB5pdvYVeWRYI69wWKwK2cD1QbMiUQnoujWvrew==", + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.29.0.tgz", + "integrity": "sha512-PrujnVFbOdUpw4UHiVwKvKRLMMic8+eC0CuNlxjsyZUiBjhFdPsewdXCkveh2KqBA9/waD0W1b4hXSOBQJezpQ==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-module-transforms": "^7.28.3", - "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-module-transforms": "^7.28.6", + "@babel/helper-plugin-utils": "^7.28.6", "@babel/helper-validator-identifier": "^7.28.5", - "@babel/traverse": "^7.28.5" + "@babel/traverse": "^7.29.0" }, "engines": { "node": ">=6.9.0" @@ -1256,14 +1256,14 @@ } }, "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.27.1.tgz", - "integrity": "sha512-SstR5JYy8ddZvD6MhV0tM/j16Qds4mIpJTOd1Yu9J9pJjH93bxHECF7pgtc28XvkzTD6Pxcm/0Z73Hvk7kb3Ng==", + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.29.0.tgz", + "integrity": "sha512-1CZQA5KNAD6ZYQLPw7oi5ewtDNxH/2vuCh+6SmvgDfhumForvs8a1o9n0UrEoBD8HU4djO2yWngTQlXl1NDVEQ==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1" + "@babel/helper-create-regexp-features-plugin": "^7.28.5", + "@babel/helper-plugin-utils": "^7.28.6" }, "engines": { "node": ">=6.9.0" @@ -1289,13 +1289,13 @@ } }, "node_modules/@babel/plugin-transform-nullish-coalescing-operator": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.27.1.tgz", - "integrity": "sha512-aGZh6xMo6q9vq1JGcw58lZ1Z0+i0xB2x0XaauNIUXd6O1xXc3RwoWEBlsTQrY4KQ9Jf0s5rgD6SiNkaUdJegTA==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.28.6.tgz", + "integrity": "sha512-3wKbRgmzYbw24mDJXT7N+ADXw8BC/imU9yo9c9X9NKaLF1fW+e5H1U5QjMUBe4Qo4Ox/o++IyUkl1sVCLgevKg==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" + "@babel/helper-plugin-utils": "^7.28.6" }, "engines": { "node": ">=6.9.0" @@ -1305,13 +1305,13 @@ } }, "node_modules/@babel/plugin-transform-numeric-separator": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.27.1.tgz", - "integrity": "sha512-fdPKAcujuvEChxDBJ5c+0BTaS6revLV7CJL08e4m3de8qJfNIuCc2nc7XJYOjBoTMJeqSmwXJ0ypE14RCjLwaw==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.28.6.tgz", + "integrity": "sha512-SJR8hPynj8outz+SlStQSwvziMN4+Bq99it4tMIf5/Caq+3iOc0JtKyse8puvyXkk3eFRIA5ID/XfunGgO5i6w==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" + "@babel/helper-plugin-utils": "^7.28.6" }, "engines": { "node": ">=6.9.0" @@ -1337,17 +1337,17 @@ } }, "node_modules/@babel/plugin-transform-object-rest-spread": { - "version": "7.28.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.28.4.tgz", - "integrity": "sha512-373KA2HQzKhQCYiRVIRr+3MjpCObqzDlyrM6u4I201wL8Mp2wHf7uB8GhDwis03k2ti8Zr65Zyyqs1xOxUF/Ew==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.28.6.tgz", + "integrity": "sha512-5rh+JR4JBC4pGkXLAcYdLHZjXudVxWMXbB6u6+E9lRL5TrGVbHt1TjxGbZ8CkmYw9zjkB7jutzOROArsqtncEA==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-compilation-targets": "^7.27.2", - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/plugin-transform-destructuring": "^7.28.0", + "@babel/helper-compilation-targets": "^7.28.6", + "@babel/helper-plugin-utils": "^7.28.6", + "@babel/plugin-transform-destructuring": "^7.28.5", "@babel/plugin-transform-parameters": "^7.27.7", - "@babel/traverse": "^7.28.4" + "@babel/traverse": "^7.28.6" }, "engines": { "node": ">=6.9.0" @@ -1374,13 +1374,13 @@ } }, "node_modules/@babel/plugin-transform-optional-catch-binding": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.27.1.tgz", - "integrity": "sha512-txEAEKzYrHEX4xSZN4kJ+OfKXFVSWKB2ZxM9dpcE3wT7smwkNmXo5ORRlVzMVdJbD+Q8ILTgSD7959uj+3Dm3Q==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.28.6.tgz", + "integrity": "sha512-R8ja/Pyrv0OGAvAXQhSTmWyPJPml+0TMqXlO5w+AsMEiwb2fg3WkOvob7UxFSL3OIttFSGSRFKQsOhJ/X6HQdQ==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" + "@babel/helper-plugin-utils": "^7.28.6" }, "engines": { "node": ">=6.9.0" @@ -1390,13 +1390,13 @@ } }, "node_modules/@babel/plugin-transform-optional-chaining": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.28.5.tgz", - "integrity": "sha512-N6fut9IZlPnjPwgiQkXNhb+cT8wQKFlJNqcZkWlcTqkcqx6/kU4ynGmLFoa4LViBSirn05YAwk+sQBbPfxtYzQ==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.28.6.tgz", + "integrity": "sha512-A4zobikRGJTsX9uqVFdafzGkqD30t26ck2LmOzAuLL8b2x6k3TIqRiT2xVvA9fNmFeTX484VpsdgmKNA0bS23w==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-plugin-utils": "^7.28.6", "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" }, "engines": { @@ -1423,14 +1423,14 @@ } }, "node_modules/@babel/plugin-transform-private-methods": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.27.1.tgz", - "integrity": "sha512-10FVt+X55AjRAYI9BrdISN9/AQWHqldOeZDUoLyif1Kn05a56xVBXb8ZouL8pZ9jem8QpXaOt8TS7RHUIS+GPA==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.28.6.tgz", + "integrity": "sha512-piiuapX9CRv7+0st8lmuUlRSmX6mBcVeNQ1b4AYzJxfCMuBfB0vBXDiGSmm03pKJw1v6cZ8KSeM+oUnM6yAExg==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1" + "@babel/helper-create-class-features-plugin": "^7.28.6", + "@babel/helper-plugin-utils": "^7.28.6" }, "engines": { "node": ">=6.9.0" @@ -1440,15 +1440,15 @@ } }, "node_modules/@babel/plugin-transform-private-property-in-object": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.27.1.tgz", - "integrity": "sha512-5J+IhqTi1XPa0DXF83jYOaARrX+41gOewWbkPyjMNRDqgOCqdffGh8L3f/Ek5utaEBZExjSAzcyjmV9SSAWObQ==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.28.6.tgz", + "integrity": "sha512-b97jvNSOb5+ehyQmBpmhOCiUC5oVK4PMnpRvO7+ymFBoqYjeDHIU9jnrNUuwHOiL9RpGDoKBpSViarV+BU+eVA==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-annotate-as-pure": "^7.27.1", - "@babel/helper-create-class-features-plugin": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1" + "@babel/helper-annotate-as-pure": "^7.27.3", + "@babel/helper-create-class-features-plugin": "^7.28.6", + "@babel/helper-plugin-utils": "^7.28.6" }, "engines": { "node": ">=6.9.0" @@ -1474,13 +1474,13 @@ } }, "node_modules/@babel/plugin-transform-regenerator": { - "version": "7.28.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.28.4.tgz", - "integrity": "sha512-+ZEdQlBoRg9m2NnzvEeLgtvBMO4tkFBw5SQIUgLICgTrumLoU7lr+Oghi6km2PFj+dbUt2u1oby2w3BDO9YQnA==", + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.29.0.tgz", + "integrity": "sha512-FijqlqMA7DmRdg/aINBSs04y8XNTYw/lr1gJ2WsmBnnaNw1iS43EPkJW+zK7z65auG3AWRFXWj+NcTQwYptUog==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" + "@babel/helper-plugin-utils": "^7.28.6" }, "engines": { "node": ">=6.9.0" @@ -1490,14 +1490,14 @@ } }, "node_modules/@babel/plugin-transform-regexp-modifiers": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regexp-modifiers/-/plugin-transform-regexp-modifiers-7.27.1.tgz", - "integrity": "sha512-TtEciroaiODtXvLZv4rmfMhkCv8jx3wgKpL68PuiPh2M4fvz5jhsA7697N1gMvkvr/JTF13DrFYyEbY9U7cVPA==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regexp-modifiers/-/plugin-transform-regexp-modifiers-7.28.6.tgz", + "integrity": "sha512-QGWAepm9qxpaIs7UM9FvUSnCGlb8Ua1RhyM4/veAxLwt3gMat/LSGrZixyuj4I6+Kn9iwvqCyPTtbdxanYoWYg==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1" + "@babel/helper-create-regexp-features-plugin": "^7.28.5", + "@babel/helper-plugin-utils": "^7.28.6" }, "engines": { "node": ">=6.9.0" @@ -1560,13 +1560,13 @@ } }, "node_modules/@babel/plugin-transform-spread": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.27.1.tgz", - "integrity": "sha512-kpb3HUqaILBJcRFVhFUs6Trdd4mkrzcGXss+6/mxUd273PfbWqSDHRzMT2234gIg2QYfAjvXLSquP1xECSg09Q==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.28.6.tgz", + "integrity": "sha512-9U4QObUC0FtJl05AsUcodau/RWDytrU6uKgkxu09mLR9HLDAtUMoPuuskm5huQsoktmsYpI+bGmq+iapDcriKA==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-plugin-utils": "^7.28.6", "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" }, "engines": { @@ -1641,14 +1641,14 @@ } }, "node_modules/@babel/plugin-transform-unicode-property-regex": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.27.1.tgz", - "integrity": "sha512-uW20S39PnaTImxp39O5qFlHLS9LJEmANjMG7SxIhap8rCHqu0Ik+tLEPX5DKmHn6CsWQ7j3lix2tFOa5YtL12Q==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.28.6.tgz", + "integrity": "sha512-4Wlbdl/sIZjzi/8St0evF0gEZrgOswVO6aOzqxh1kDZOl9WmLrHq2HtGhnOJZmHZYKP8WZ1MDLCt5DAWwRo57A==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1" + "@babel/helper-create-regexp-features-plugin": "^7.28.5", + "@babel/helper-plugin-utils": "^7.28.6" }, "engines": { "node": ">=6.9.0" @@ -1675,14 +1675,14 @@ } }, "node_modules/@babel/plugin-transform-unicode-sets-regex": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.27.1.tgz", - "integrity": "sha512-EtkOujbc4cgvb0mlpQefi4NTPBzhSIevblFevACNLUspmrALgmEBdL/XfnyyITfd8fKBZrZys92zOWcik7j9Tw==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.28.6.tgz", + "integrity": "sha512-/wHc/paTUmsDYN7SZkpWxogTOBNnlx7nBQYfy6JJlCT7G3mVhltk3e++N7zV0XfgGsrqBxd4rJQt9H16I21Y1Q==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1" + "@babel/helper-create-regexp-features-plugin": "^7.28.5", + "@babel/helper-plugin-utils": "^7.28.6" }, "engines": { "node": ">=6.9.0" @@ -1692,81 +1692,81 @@ } }, "node_modules/@babel/preset-env": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.28.5.tgz", - "integrity": "sha512-S36mOoi1Sb6Fz98fBfE+UZSpYw5mJm0NUHtIKrOuNcqeFauy1J6dIvXm2KRVKobOSaGq4t/hBXdN4HGU3wL9Wg==", + "version": "7.29.2", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.29.2.tgz", + "integrity": "sha512-DYD23veRYGvBFhcTY1iUvJnDNpuqNd/BzBwCvzOTKUnJjKg5kpUBh3/u9585Agdkgj+QuygG7jLfOPWMa2KVNw==", "dev": true, "license": "MIT", "dependencies": { - "@babel/compat-data": "^7.28.5", - "@babel/helper-compilation-targets": "^7.27.2", - "@babel/helper-plugin-utils": "^7.27.1", + "@babel/compat-data": "^7.29.0", + "@babel/helper-compilation-targets": "^7.28.6", + "@babel/helper-plugin-utils": "^7.28.6", "@babel/helper-validator-option": "^7.27.1", "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.28.5", "@babel/plugin-bugfix-safari-class-field-initializer-scope": "^7.27.1", "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.27.1", "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.27.1", - "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.28.3", + "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.28.6", "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", - "@babel/plugin-syntax-import-assertions": "^7.27.1", - "@babel/plugin-syntax-import-attributes": "^7.27.1", + "@babel/plugin-syntax-import-assertions": "^7.28.6", + "@babel/plugin-syntax-import-attributes": "^7.28.6", "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", "@babel/plugin-transform-arrow-functions": "^7.27.1", - "@babel/plugin-transform-async-generator-functions": "^7.28.0", - "@babel/plugin-transform-async-to-generator": "^7.27.1", + "@babel/plugin-transform-async-generator-functions": "^7.29.0", + "@babel/plugin-transform-async-to-generator": "^7.28.6", "@babel/plugin-transform-block-scoped-functions": "^7.27.1", - "@babel/plugin-transform-block-scoping": "^7.28.5", - "@babel/plugin-transform-class-properties": "^7.27.1", - "@babel/plugin-transform-class-static-block": "^7.28.3", - "@babel/plugin-transform-classes": "^7.28.4", - "@babel/plugin-transform-computed-properties": "^7.27.1", + "@babel/plugin-transform-block-scoping": "^7.28.6", + "@babel/plugin-transform-class-properties": "^7.28.6", + "@babel/plugin-transform-class-static-block": "^7.28.6", + "@babel/plugin-transform-classes": "^7.28.6", + "@babel/plugin-transform-computed-properties": "^7.28.6", "@babel/plugin-transform-destructuring": "^7.28.5", - "@babel/plugin-transform-dotall-regex": "^7.27.1", + "@babel/plugin-transform-dotall-regex": "^7.28.6", "@babel/plugin-transform-duplicate-keys": "^7.27.1", - "@babel/plugin-transform-duplicate-named-capturing-groups-regex": "^7.27.1", + "@babel/plugin-transform-duplicate-named-capturing-groups-regex": "^7.29.0", "@babel/plugin-transform-dynamic-import": "^7.27.1", - "@babel/plugin-transform-explicit-resource-management": "^7.28.0", - "@babel/plugin-transform-exponentiation-operator": "^7.28.5", + "@babel/plugin-transform-explicit-resource-management": "^7.28.6", + "@babel/plugin-transform-exponentiation-operator": "^7.28.6", "@babel/plugin-transform-export-namespace-from": "^7.27.1", "@babel/plugin-transform-for-of": "^7.27.1", "@babel/plugin-transform-function-name": "^7.27.1", - "@babel/plugin-transform-json-strings": "^7.27.1", + "@babel/plugin-transform-json-strings": "^7.28.6", "@babel/plugin-transform-literals": "^7.27.1", - "@babel/plugin-transform-logical-assignment-operators": "^7.28.5", + "@babel/plugin-transform-logical-assignment-operators": "^7.28.6", "@babel/plugin-transform-member-expression-literals": "^7.27.1", "@babel/plugin-transform-modules-amd": "^7.27.1", - "@babel/plugin-transform-modules-commonjs": "^7.27.1", - "@babel/plugin-transform-modules-systemjs": "^7.28.5", + "@babel/plugin-transform-modules-commonjs": "^7.28.6", + "@babel/plugin-transform-modules-systemjs": "^7.29.0", "@babel/plugin-transform-modules-umd": "^7.27.1", - "@babel/plugin-transform-named-capturing-groups-regex": "^7.27.1", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.29.0", "@babel/plugin-transform-new-target": "^7.27.1", - "@babel/plugin-transform-nullish-coalescing-operator": "^7.27.1", - "@babel/plugin-transform-numeric-separator": "^7.27.1", - "@babel/plugin-transform-object-rest-spread": "^7.28.4", + "@babel/plugin-transform-nullish-coalescing-operator": "^7.28.6", + "@babel/plugin-transform-numeric-separator": "^7.28.6", + "@babel/plugin-transform-object-rest-spread": "^7.28.6", "@babel/plugin-transform-object-super": "^7.27.1", - "@babel/plugin-transform-optional-catch-binding": "^7.27.1", - "@babel/plugin-transform-optional-chaining": "^7.28.5", + "@babel/plugin-transform-optional-catch-binding": "^7.28.6", + "@babel/plugin-transform-optional-chaining": "^7.28.6", "@babel/plugin-transform-parameters": "^7.27.7", - "@babel/plugin-transform-private-methods": "^7.27.1", - "@babel/plugin-transform-private-property-in-object": "^7.27.1", + "@babel/plugin-transform-private-methods": "^7.28.6", + "@babel/plugin-transform-private-property-in-object": "^7.28.6", "@babel/plugin-transform-property-literals": "^7.27.1", - "@babel/plugin-transform-regenerator": "^7.28.4", - "@babel/plugin-transform-regexp-modifiers": "^7.27.1", + "@babel/plugin-transform-regenerator": "^7.29.0", + "@babel/plugin-transform-regexp-modifiers": "^7.28.6", "@babel/plugin-transform-reserved-words": "^7.27.1", "@babel/plugin-transform-shorthand-properties": "^7.27.1", - "@babel/plugin-transform-spread": "^7.27.1", + "@babel/plugin-transform-spread": "^7.28.6", "@babel/plugin-transform-sticky-regex": "^7.27.1", "@babel/plugin-transform-template-literals": "^7.27.1", "@babel/plugin-transform-typeof-symbol": "^7.27.1", "@babel/plugin-transform-unicode-escapes": "^7.27.1", - "@babel/plugin-transform-unicode-property-regex": "^7.27.1", + "@babel/plugin-transform-unicode-property-regex": "^7.28.6", "@babel/plugin-transform-unicode-regex": "^7.27.1", - "@babel/plugin-transform-unicode-sets-regex": "^7.27.1", + "@babel/plugin-transform-unicode-sets-regex": "^7.28.6", "@babel/preset-modules": "0.1.6-no-external-plugins", - "babel-plugin-polyfill-corejs2": "^0.4.14", - "babel-plugin-polyfill-corejs3": "^0.13.0", - "babel-plugin-polyfill-regenerator": "^0.6.5", - "core-js-compat": "^3.43.0", + "babel-plugin-polyfill-corejs2": "^0.4.15", + "babel-plugin-polyfill-corejs3": "^0.14.0", + "babel-plugin-polyfill-regenerator": "^0.6.6", + "core-js-compat": "^3.48.0", "semver": "^6.3.1" }, "engines": { @@ -1776,6 +1776,20 @@ "@babel/core": "^7.0.0-0" } }, + "node_modules/@babel/preset-env/node_modules/babel-plugin-polyfill-corejs3": { + "version": "0.14.2", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.14.2.tgz", + "integrity": "sha512-coWpDLJ410R781Npmn/SIBZEsAetR4xVi0SxLMXPaMO4lSf1MwnkGYMtkFxew0Dn8B3/CpbpYxN0JCgg8mn67g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.6.8", + "core-js-compat": "^3.48.0" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, "node_modules/@babel/preset-modules": { "version": "0.1.6-no-external-plugins", "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.6-no-external-plugins.tgz", @@ -5422,14 +5436,14 @@ } }, "node_modules/babel-plugin-polyfill-corejs2": { - "version": "0.4.14", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.14.tgz", - "integrity": "sha512-Co2Y9wX854ts6U8gAAPXfn0GmAyctHuK8n0Yhfjd6t30g7yvKjspvvOo9yG+z52PZRgFErt7Ka2pYnXCjLKEpg==", + "version": "0.4.17", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.17.tgz", + "integrity": "sha512-aTyf30K/rqAsNwN76zYrdtx8obu0E4KoUME29B1xj+B3WxgvWkp943vYQ+z8Mv3lw9xHXMHpvSPOBxzAkIa94w==", "dev": true, "license": "MIT", "dependencies": { - "@babel/compat-data": "^7.27.7", - "@babel/helper-define-polyfill-provider": "^0.6.5", + "@babel/compat-data": "^7.28.6", + "@babel/helper-define-polyfill-provider": "^0.6.8", "semver": "^6.3.1" }, "peerDependencies": { @@ -5451,13 +5465,13 @@ } }, "node_modules/babel-plugin-polyfill-regenerator": { - "version": "0.6.5", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.5.tgz", - "integrity": "sha512-ISqQ2frbiNU9vIJkzg7dlPpznPZ4jOiUQ1uSmB0fEHeowtN3COYRsXr/xexn64NpU13P06jc/L5TgiJXOgrbEg==", + "version": "0.6.8", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.8.tgz", + "integrity": "sha512-M762rNHfSF1EV3SLtnCJXFoQbbIIz0OyRwnCmV0KPC7qosSfCO0QLTSuJX3ayAebubhE6oYBAYPrBA5ljowaZg==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.6.5" + "@babel/helper-define-polyfill-provider": "^0.6.8" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" @@ -7855,13 +7869,13 @@ } }, "node_modules/core-js-compat": { - "version": "3.45.1", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.45.1.tgz", - "integrity": "sha512-tqTt5T4PzsMIZ430XGviK4vzYSoeNJ6CXODi6c/voxOT6IZqBht5/EKaSNnYiEjjRYxjVz7DQIsOsY0XNi8PIA==", + "version": "3.49.0", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.49.0.tgz", + "integrity": "sha512-VQXt1jr9cBz03b331DFDCCP90b3fanciLkgiOoy8SBHy06gNf+vQ1A3WFLqG7I8TipYIKeYK9wxd0tUrvHcOZA==", "dev": true, "license": "MIT", "dependencies": { - "browserslist": "^4.25.3" + "browserslist": "^4.28.1" }, "funding": { "type": "opencollective", @@ -17257,13 +17271,14 @@ "license": "MIT" }, "node_modules/resolve": { - "version": "1.22.10", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz", - "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==", + "version": "1.22.12", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.12.tgz", + "integrity": "sha512-TyeJ1zif53BPfHootBGwPRYT1RUt6oGWsaQr8UyZW/eAm9bKoijtvruSDEmZHm92CwS9nj7/fWttqPCgzep8CA==", "dev": true, "license": "MIT", "dependencies": { - "is-core-module": "^2.16.0", + "es-errors": "^1.3.0", + "is-core-module": "^2.16.1", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, diff --git a/package.json b/package.json index 4c5683b23e..eecb29c95c 100644 --- a/package.json +++ b/package.json @@ -11,6 +11,7 @@ }, "license": "MIT", "author": "Tobias Koppers @sokra", + "type": "module", "main": "lib/Server.js", "types": "types/lib/Server.d.ts", "bin": "bin/webpack-dev-server.js", @@ -76,7 +77,7 @@ "@babel/eslint-parser": "^7.28.6", "@babel/plugin-transform-object-assign": "^7.27.1", "@babel/plugin-transform-runtime": "^7.29.0", - "@babel/preset-env": "^7.25.9", + "@babel/preset-env": "^7.29.2", "@babel/runtime": "^7.29.2", "@commitlint/cli": "^19.5.0", "@commitlint/config-conventional": "^19.5.0", diff --git a/scripts/extend-webpack-types.js b/scripts/extend-webpack-types.js index 36a811a933..5125aa55ed 100644 --- a/scripts/extend-webpack-types.js +++ b/scripts/extend-webpack-types.js @@ -1,13 +1,15 @@ -"use strict"; - -const path = require("node:path"); -const fs = require("graceful-fs"); +import path from "node:path"; +import { fileURLToPath } from "node:url"; +import fs from "graceful-fs"; /** * @returns {Promise} */ async function extendTypes() { - const typesPath = path.resolve(__dirname, "../types/lib/Server.d.ts"); + const typesPath = path.resolve( + path.dirname(fileURLToPath(import.meta.url)), + "../types/lib/Server.d.ts", + ); const content = await fs.promises.readFile(typesPath, "utf8"); const newContent = `${content} // DO NOT REMOVE THIS! @@ -26,10 +28,4 @@ declare module "webpack" { await fs.promises.writeFile(typesPath, newContent); } -// eslint-disable-next-line unicorn/prefer-top-level-await -Promise.resolve().then( - () => extendTypes(), - (error) => { - throw error; - }, -); +await extendTypes(); diff --git a/tsconfig.json b/tsconfig.json index a28baacbf5..f8f19ec5cb 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,14 +1,16 @@ { "compilerOptions": { - "target": "ES2017", - "module": "commonjs", - "lib": ["es2017", "dom"], + "target": "ES2022", + "module": "nodenext", + "moduleResolution": "nodenext", + "lib": ["es2022", "dom"], "allowJs": true, "checkJs": true, "strict": true, "types": ["node"], "resolveJsonModule": true, - "allowSyntheticDefaultImports": true + "allowSyntheticDefaultImports": true, + "esModuleInterop": true }, "include": ["./bin/**/*", "./lib/**/*"] } diff --git a/types/lib/Server.d.ts b/types/lib/Server.d.ts index 80a7fbe2df..678da2b5b1 100644 --- a/types/lib/Server.d.ts +++ b/types/lib/Server.d.ts @@ -1,4 +1,340 @@ -export = Server; +export default Server; +export type Schema = import("schema-utils").Schema; +export type Compiler = import("webpack").Compiler; +export type MultiCompiler = import("webpack").MultiCompiler; +export type WebpackConfiguration = import("webpack").Configuration; +export type StatsOptions = import("webpack").StatsOptions; +export type StatsCompilation = import("webpack").StatsCompilation; +export type Stats = import("webpack").Stats; +export type MultiStats = import("webpack").MultiStats; +export type NetworkInterfaceInfo = import("os").NetworkInterfaceInfo; +export type WatchOptions = import("chokidar").ChokidarOptions; +export type FSWatcher = import("chokidar").FSWatcher; +export type ConnectHistoryApiFallbackOptions = + import("connect-history-api-fallback").Options; +export type Bonjour = import("bonjour-service").Bonjour; +export type BonjourOptions = import("bonjour-service").Service; +export type RequestHandler = import("http-proxy-middleware").RequestHandler; +export type HttpProxyMiddlewareOptions = + import("http-proxy-middleware").Options; +export type HttpProxyMiddlewareOptionsFilter = + import("http-proxy-middleware").Filter; +export type ServeIndexOptions = import("serve-index").Options; +export type ServeStaticOptions = import("serve-static").ServeStaticOptions; +export type IPv4 = import("ipaddr.js").IPv4; +export type IPv6 = import("ipaddr.js").IPv6; +export type Socket = import("net").Socket; +export type HTTPServer = import("http").Server; +export type IncomingMessage = import("http").IncomingMessage; +export type ServerResponse = import("http").ServerResponse; +export type OpenOptions = import("open").Options; +export type ExpressApplication = import("express").Application; +export type ExpressRequestHandler = import("express").RequestHandler; +export type ExpressErrorRequestHandler = import("express").ErrorRequestHandler; +export type ExpressRequest = import("express").Request; +export type ExpressResponse = import("express").Response; +export type EXPECTED_ANY = any; +export type NextFunction = (err?: EXPECTED_ANY) => void; +export type SimpleHandleFunction = ( + req: IncomingMessage, + res: ServerResponse, +) => void; +export type NextHandleFunction = ( + req: IncomingMessage, + res: ServerResponse, + next: NextFunction, +) => void; +export type ErrorHandleFunction = ( + err: EXPECTED_ANY, + req: IncomingMessage, + res: ServerResponse, + next: NextFunction, +) => void; +export type HandleFunction = + | SimpleHandleFunction + | NextHandleFunction + | ErrorHandleFunction; +export type ServerOptions = import("https").ServerOptions; +export type Request< + T extends BasicApplication = import("express").Application, +> = T extends ExpressApplication ? ExpressRequest : IncomingMessage; +export type Response< + T extends BasicApplication = import("express").Application, +> = T extends ExpressApplication ? ExpressResponse : ServerResponse; +export type DevMiddlewareOptions< + T extends Request, + U extends Response, +> = import("webpack-dev-middleware").Options; +export type DevMiddlewareContext< + T extends Request, + U extends Response, +> = import("webpack-dev-middleware").Context; +export type Host = "local-ip" | "local-ipv4" | "local-ipv6" | string; +export type Port = number | string | "auto"; +export type WatchFiles = { + /** + * paths + */ + paths: string | string[]; + /** + * options + */ + options?: + | (WatchOptions & { + aggregateTimeout?: number; + ignored?: WatchOptions["ignored"]; + poll?: number | boolean; + }) + | undefined; +}; +export type Static = { + /** + * directory + */ + directory?: string | undefined; + /** + * public path + */ + publicPath?: (string | string[]) | undefined; + /** + * serve index + */ + serveIndex?: (boolean | ServeIndexOptions) | undefined; + /** + * static options + */ + staticOptions?: ServeStaticOptions | undefined; + /** + * watch and watch options + */ + watch?: + | ( + | boolean + | (WatchOptions & { + aggregateTimeout?: number; + ignored?: WatchOptions["ignored"]; + poll?: number | boolean; + }) + ) + | undefined; +}; +export type NormalizedStatic = { + directory: string; + publicPath: string[]; + serveIndex: false | ServeIndexOptions; + staticOptions: ServeStaticOptions; + watch: false | WatchOptions; +}; +export type ServerType< + A extends BasicApplication = import("express").Application, + S extends BasicServer = import("http").Server< + typeof import("http").IncomingMessage, + typeof import("http").ServerResponse + >, +> = + | "http" + | "https" + | "http2" + | string + | ((serverOptions: ServerOptions, application: A) => S); +export type ServerConfiguration< + A extends BasicApplication = import("express").Application, + S extends BasicServer = import("http").Server< + typeof import("http").IncomingMessage, + typeof import("http").ServerResponse + >, +> = { + /** + * type + */ + type?: ServerType | undefined; + /** + * options + */ + options?: ServerOptions | undefined; +}; +export type WebSocketServerConfiguration = { + /** + * type + */ + type?: ("ws" | string | (() => WebSocketServerConfiguration)) | undefined; + /** + * options + */ + options?: Record | undefined; +}; +export type ClientConnection = (import("ws").WebSocket & { + send: import("ws").WebSocket["send"]; + terminate: import("ws").WebSocket["terminate"]; + ping: import("ws").WebSocket["ping"]; +}) & { + isAlive?: boolean; +}; +export type WebSocketServer = import("ws").WebSocketServer & { + close: import("ws").WebSocketServer["close"]; +}; +export type WebSocketServerImplementation = { + implementation: WebSocketServer; + clients: ClientConnection[]; +}; +export type ProxyConfigArrayItem = { + path?: HttpProxyMiddlewareOptionsFilter | undefined; + context?: HttpProxyMiddlewareOptionsFilter | undefined; +} & HttpProxyMiddlewareOptions; +export type ProxyConfigArray = ( + | ProxyConfigArrayItem + | (( + req?: Request | undefined, + res?: Response | undefined, + next?: NextFunction | undefined, + ) => ProxyConfigArrayItem) +)[]; +export type OpenApp = { + name?: string | undefined; + arguments?: string[] | undefined; +}; +export type Open = { + app?: (string | string[] | OpenApp) | undefined; + /** + * target + */ + target?: (string | string[]) | undefined; +}; +export type NormalizedOpen = { + target: string; + options: import("open").Options; +}; +export type WebSocketURL = { + /** + * hostname + */ + hostname?: string | undefined; + /** + * password + */ + password?: string | undefined; + /** + * pathname + */ + pathname?: string | undefined; + /** + * port + */ + port?: (number | string) | undefined; + /** + * protocol + */ + protocol?: string | undefined; + /** + * username + */ + username?: string | undefined; +}; +export type OverlayMessageOptions = boolean | ((error: Error) => void); +export type ClientConfiguration = { + /** + * logging + */ + logging?: + | ("log" | "info" | "warn" | "error" | "none" | "verbose") + | undefined; + /** + * overlay + */ + overlay?: + | ( + | boolean + | { + warnings?: OverlayMessageOptions; + errors?: OverlayMessageOptions; + runtimeErrors?: OverlayMessageOptions; + } + ) + | undefined; + /** + * progress + */ + progress?: boolean | undefined; + /** + * reconnect + */ + reconnect?: (boolean | number) | undefined; + /** + * web socket transport + */ + webSocketTransport?: ("ws" | string) | undefined; + /** + * web socket URL + */ + webSocketURL?: (string | WebSocketURL) | undefined; +}; +export type Headers = + | Array<{ + key: string; + value: string; + }> + | Record; +export type MiddlewareHandler< + T extends BasicApplication = import("express").Application, +> = T extends ExpressApplication + ? ExpressRequestHandler | ExpressErrorRequestHandler + : HandleFunction; +export type MiddlewareObject = { + name?: string; + path?: string; + middleware: MiddlewareHandler; +}; +export type Middleware = MiddlewareObject | MiddlewareHandler; +export type BasicServer = import("net").Server | import("tls").Server; +export type Configuration< + A extends BasicApplication = import("express").Application, + S extends BasicServer = import("http").Server< + typeof import("http").IncomingMessage, + typeof import("http").ServerResponse + >, +> = { + ipc?: (boolean | string) | undefined; + host?: Host | undefined; + port?: Port | undefined; + hot?: (boolean | "only") | undefined; + liveReload?: boolean | undefined; + devMiddleware?: DevMiddlewareOptions | undefined; + compress?: boolean | undefined; + allowedHosts?: ("auto" | "all" | string | string[]) | undefined; + historyApiFallback?: (boolean | ConnectHistoryApiFallbackOptions) | undefined; + bonjour?: (boolean | Record | BonjourOptions) | undefined; + watchFiles?: + | (string | string[] | WatchFiles | Array) + | undefined; + static?: (boolean | string | Static | Array) | undefined; + server?: (ServerType | ServerConfiguration) | undefined; + app?: (() => Promise) | undefined; + webSocketServer?: + | (boolean | "ws" | string | WebSocketServerConfiguration) + | undefined; + proxy?: ProxyConfigArray | undefined; + open?: (boolean | string | Open | Array) | undefined; + setupExitSignals?: boolean | undefined; + client?: (boolean | ClientConfiguration) | undefined; + headers?: + | ( + | Headers + | (( + req: Request, + res: Response, + context: DevMiddlewareContext | undefined, + ) => Headers) + ) + | undefined; + onListening?: ((devServer: Server) => void) | undefined; + setupMiddlewares?: + | ((middlewares: Middleware[], devServer: Server) => Middleware[]) + | undefined; +}; +export type FunctionReturning = () => T; +export type BasicApplication = { + use: typeof useFn; +}; /** * @typedef {object} BasicApplication * @property {typeof useFn} use @@ -1219,7 +1555,7 @@ declare class Server< /** * @template T * @private - * @returns {T} server transport + * @returns {Promise} server transport */ private getServerTransport; /** @@ -1265,17 +1601,17 @@ declare class Server< private stats; /** * @private - * @returns {void} + * @returns {Promise} */ private setupWatchStaticFiles; /** * @private - * @returns {void} + * @returns {Promise} */ private setupWatchFiles; /** * @private - * @returns {void} + * @returns {Promise} */ private setupMiddlewares; /** @type {import("webpack-dev-middleware").API} */ @@ -1285,534 +1621,133 @@ declare class Server< import("express-serve-static-core").ParamsDictionary, any, any, - qs.ParsedQs, + import("qs").ParsedQs, Record >, import("express").Response> > | undefined; /** - * @private - * @returns {Promise} - */ - private createServer; - /** @type {S | undefined} */ - server: S | undefined; - isTlsServer: boolean | undefined; - /** - * @private - * @returns {void} - */ - private createWebSocketServer; - /** @type {WebSocketServerImplementation | undefined | null} */ - webSocketServer: WebSocketServerImplementation | undefined | null; - /** - * @private - * @param {string} defaultOpenTarget default open target - * @returns {Promise} - */ - private openBrowser; - /** - * @private - * @returns {void} - */ - private runBonjour; - /** - * @private - * @type {Bonjour | undefined} - */ - private bonjour; - /** - * @private - * @param {() => void} callback callback - * @returns {void} - */ - private stopBonjour; - /** - * @private - * @returns {Promise} - */ - private logStatus; - /** - * @private - * @param {Request} req request - * @param {Response} res response - * @param {NextFunction} next next function - */ - private setHeaders; - /** - * @private - * @param {string} value value - * @returns {boolean} true when host allowed, otherwise false - */ - private isHostAllowed; - /** - * @private - * @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 headers - * @returns {boolean} true when is same origin, otherwise false - */ - private isSameOrigin; - /** - * @param {ClientConnection[]} clients clients - * @param {string} type type - * @param {EXPECTED_ANY=} data data - * @param {EXPECTED_ANY=} params params - */ - sendMessage( - clients: ClientConnection[], - type: string, - data?: EXPECTED_ANY | undefined, - params?: EXPECTED_ANY | undefined, - ): void; - /** - * @private - * @param {ClientConnection[]} clients clients - * @param {StatsCompilation} stats stats - * @param {boolean=} force force - */ - private sendStats; - /** - * @param {string | string[]} watchPath watch path - * @param {WatchOptions=} watchOptions watch options - */ - watchFiles( - watchPath: string | string[], - watchOptions?: WatchOptions | undefined, - ): void; - /** - * @param {import("webpack-dev-middleware").Callback=} callback callback - */ - invalidate( - callback?: import("webpack-dev-middleware").Callback | undefined, - ): void; - /** - * @returns {Promise} - */ - start(): Promise; - /** - * @param {((err?: Error) => void)=} callback callback - */ - startCallback(callback?: ((err?: Error) => void) | undefined): void; - /** - * @returns {Promise} - */ - stop(): Promise; - /** - * @param {((err?: Error) => void)=} callback callback - */ - stopCallback(callback?: ((err?: Error) => void) | undefined): void; - #private; -} -declare namespace Server { - export { - Schema, - Compiler, - MultiCompiler, - WebpackConfiguration, - StatsOptions, - StatsCompilation, - Stats, - MultiStats, - NetworkInterfaceInfo, - WatchOptions, - FSWatcher, - ConnectHistoryApiFallbackOptions, - Bonjour, - BonjourOptions, - RequestHandler, - HttpProxyMiddlewareOptions, - HttpProxyMiddlewareOptionsFilter, - ServeIndexOptions, - ServeStaticOptions, - IPv4, - IPv6, - Socket, - HTTPServer, - IncomingMessage, - ServerResponse, - OpenOptions, - ExpressApplication, - ExpressRequestHandler, - ExpressErrorRequestHandler, - ExpressRequest, - ExpressResponse, - EXPECTED_ANY, - NextFunction, - SimpleHandleFunction, - NextHandleFunction, - ErrorHandleFunction, - HandleFunction, - ServerOptions, - Request, - Response, - DevMiddlewareOptions, - DevMiddlewareContext, - Host, - Port, - WatchFiles, - Static, - NormalizedStatic, - ServerType, - ServerConfiguration, - WebSocketServerConfiguration, - ClientConnection, - WebSocketServer, - WebSocketServerImplementation, - ProxyConfigArrayItem, - ProxyConfigArray, - OpenApp, - Open, - NormalizedOpen, - WebSocketURL, - OverlayMessageOptions, - ClientConfiguration, - Headers, - MiddlewareHandler, - MiddlewareObject, - Middleware, - BasicServer, - Configuration, - FunctionReturning, - BasicApplication, - }; -} -type Schema = import("schema-utils/declarations/validate").Schema; -type Compiler = import("webpack").Compiler; -type MultiCompiler = import("webpack").MultiCompiler; -type WebpackConfiguration = import("webpack").Configuration; -type StatsOptions = import("webpack").StatsOptions; -type StatsCompilation = import("webpack").StatsCompilation; -type Stats = import("webpack").Stats; -type MultiStats = import("webpack").MultiStats; -type NetworkInterfaceInfo = import("os").NetworkInterfaceInfo; -type WatchOptions = import("chokidar").ChokidarOptions; -type FSWatcher = import("chokidar").FSWatcher; -type ConnectHistoryApiFallbackOptions = - import("connect-history-api-fallback").Options; -type Bonjour = import("bonjour-service").Bonjour; -type BonjourOptions = import("bonjour-service").Service; -type RequestHandler = import("http-proxy-middleware").RequestHandler; -type HttpProxyMiddlewareOptions = import("http-proxy-middleware").Options; -type HttpProxyMiddlewareOptionsFilter = import("http-proxy-middleware").Filter; -type ServeIndexOptions = import("serve-index").Options; -type ServeStaticOptions = import("serve-static").ServeStaticOptions; -type IPv4 = import("ipaddr.js").IPv4; -type IPv6 = import("ipaddr.js").IPv6; -type Socket = import("net").Socket; -type HTTPServer = import("http").Server; -type IncomingMessage = import("http").IncomingMessage; -type ServerResponse = import("http").ServerResponse; -type OpenOptions = import("open").Options; -type ExpressApplication = import("express").Application; -type ExpressRequestHandler = import("express").RequestHandler; -type ExpressErrorRequestHandler = import("express").ErrorRequestHandler; -type ExpressRequest = import("express").Request; -type ExpressResponse = import("express").Response; -type EXPECTED_ANY = any; -type NextFunction = (err?: EXPECTED_ANY) => void; -type SimpleHandleFunction = (req: IncomingMessage, res: ServerResponse) => void; -type NextHandleFunction = ( - req: IncomingMessage, - res: ServerResponse, - next: NextFunction, -) => void; -type ErrorHandleFunction = ( - err: EXPECTED_ANY, - req: IncomingMessage, - res: ServerResponse, - next: NextFunction, -) => void; -type HandleFunction = - | SimpleHandleFunction - | NextHandleFunction - | ErrorHandleFunction; -type ServerOptions = import("https").ServerOptions; -type Request = - T extends ExpressApplication ? ExpressRequest : IncomingMessage; -type Response = - T extends ExpressApplication ? ExpressResponse : ServerResponse; -type DevMiddlewareOptions< - T extends Request, - U extends Response, -> = import("webpack-dev-middleware").Options; -type DevMiddlewareContext< - T extends Request, - U extends Response, -> = import("webpack-dev-middleware").Context; -type Host = "local-ip" | "local-ipv4" | "local-ipv6" | string; -type Port = number | string | "auto"; -type WatchFiles = { - /** - * paths - */ - paths: string | string[]; - /** - * options - */ - options?: - | (WatchOptions & { - aggregateTimeout?: number; - ignored?: WatchOptions["ignored"]; - poll?: number | boolean; - }) - | undefined; -}; -type Static = { - /** - * directory - */ - directory?: string | undefined; - /** - * public path - */ - publicPath?: (string | string[]) | undefined; - /** - * serve index - */ - serveIndex?: (boolean | ServeIndexOptions) | undefined; - /** - * static options + * @private + * @returns {Promise} */ - staticOptions?: ServeStaticOptions | undefined; + private createServer; + /** @type {S | undefined} */ + server: S | undefined; + isTlsServer: boolean | undefined; /** - * watch and watch options + * @private + * @returns {Promise} */ - watch?: - | ( - | boolean - | (WatchOptions & { - aggregateTimeout?: number; - ignored?: WatchOptions["ignored"]; - poll?: number | boolean; - }) - ) - | undefined; -}; -type NormalizedStatic = { - directory: string; - publicPath: string[]; - serveIndex: false | ServeIndexOptions; - staticOptions: ServeStaticOptions; - watch: false | WatchOptions; -}; -type ServerType< - A extends BasicApplication = import("express").Application, - S extends BasicServer = import("http").Server< - typeof import("http").IncomingMessage, - typeof import("http").ServerResponse - >, -> = - | "http" - | "https" - | "http2" - | string - | ((serverOptions: ServerOptions, application: A) => S); -type ServerConfiguration< - A extends BasicApplication = import("express").Application, - S extends BasicServer = import("http").Server< - typeof import("http").IncomingMessage, - typeof import("http").ServerResponse - >, -> = { + private createWebSocketServer; + /** @type {WebSocketServerImplementation | undefined | null} */ + webSocketServer: WebSocketServerImplementation | undefined | null; /** - * type + * @private + * @param {string} defaultOpenTarget default open target + * @returns {Promise} */ - type?: ServerType | undefined; + private openBrowser; /** - * options + * @private + * @returns {Promise} */ - options?: ServerOptions | undefined; -}; -type WebSocketServerConfiguration = { + private runBonjour; /** - * type + * @private + * @type {Bonjour | undefined} */ - type?: ("ws" | string | (() => WebSocketServerConfiguration)) | undefined; + private bonjour; /** - * options + * @private + * @param {() => void} callback callback + * @returns {void} */ - options?: Record | undefined; -}; -type ClientConnection = (import("ws").WebSocket & { - send: import("ws").WebSocket["send"]; - terminate: import("ws").WebSocket["terminate"]; - ping: import("ws").WebSocket["ping"]; -}) & { - isAlive?: boolean; -}; -type WebSocketServer = import("ws").WebSocketServer & { - close: import("ws").WebSocketServer["close"]; -}; -type WebSocketServerImplementation = { - implementation: WebSocketServer; - clients: ClientConnection[]; -}; -type ProxyConfigArrayItem = { - path?: HttpProxyMiddlewareOptionsFilter | undefined; - context?: HttpProxyMiddlewareOptionsFilter | undefined; -} & HttpProxyMiddlewareOptions; -type ProxyConfigArray = ( - | ProxyConfigArrayItem - | (( - req?: Request | undefined, - res?: Response | undefined, - next?: NextFunction | undefined, - ) => ProxyConfigArrayItem) -)[]; -type OpenApp = { - name?: string | undefined; - arguments?: string[] | undefined; -}; -type Open = { - app?: (string | string[] | OpenApp) | undefined; + private stopBonjour; /** - * target + * @private + * @returns {Promise} */ - target?: (string | string[]) | undefined; -}; -type NormalizedOpen = { - target: string; - options: import("open").Options; -}; -type WebSocketURL = { + private logStatus; /** - * hostname + * @private + * @param {Request} req request + * @param {Response} res response + * @param {NextFunction} next next function */ - hostname?: string | undefined; + private setHeaders; /** - * password + * @private + * @param {string} value value + * @returns {boolean} true when host allowed, otherwise false */ - password?: string | undefined; + private isHostAllowed; /** - * pathname + * @private + * @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 */ - pathname?: string | undefined; + private isValidHost; /** - * port + * @private + * @param {{ [key: string]: string | undefined }} headers headers + * @returns {boolean} true when is same origin, otherwise false */ - port?: (number | string) | undefined; + private isSameOrigin; /** - * protocol + * @param {ClientConnection[]} clients clients + * @param {string} type type + * @param {EXPECTED_ANY=} data data + * @param {EXPECTED_ANY=} params params */ - protocol?: string | undefined; + sendMessage( + clients: ClientConnection[], + type: string, + data?: EXPECTED_ANY | undefined, + params?: EXPECTED_ANY | undefined, + ): void; /** - * username + * @private + * @param {ClientConnection[]} clients clients + * @param {StatsCompilation} stats stats + * @param {boolean=} force force */ - username?: string | undefined; -}; -type OverlayMessageOptions = boolean | ((error: Error) => void); -type ClientConfiguration = { + private sendStats; /** - * logging + * @param {string | string[]} watchPath watch path + * @param {WatchOptions=} watchOptions watch options + * @returns {Promise} */ - logging?: - | ("log" | "info" | "warn" | "error" | "none" | "verbose") - | undefined; + watchFiles( + watchPath: string | string[], + watchOptions?: WatchOptions | undefined, + ): Promise; /** - * overlay + * @param {import("webpack-dev-middleware").Callback=} callback callback */ - overlay?: - | ( - | boolean - | { - warnings?: OverlayMessageOptions; - errors?: OverlayMessageOptions; - runtimeErrors?: OverlayMessageOptions; - } - ) - | undefined; + invalidate( + callback?: import("webpack-dev-middleware").Callback | undefined, + ): void; /** - * progress + * @returns {Promise} */ - progress?: boolean | undefined; + start(): Promise; /** - * reconnect + * @param {((err?: Error) => void)=} callback callback */ - reconnect?: (boolean | number) | undefined; + startCallback(callback?: ((err?: Error) => void) | undefined): void; /** - * web socket transport + * @returns {Promise} */ - webSocketTransport?: ("ws" | string) | undefined; + stop(): Promise; /** - * web socket URL + * @param {((err?: Error) => void)=} callback callback */ - webSocketURL?: (string | WebSocketURL) | undefined; -}; -type Headers = - | Array<{ - key: string; - value: string; - }> - | Record; -type MiddlewareHandler< - T extends BasicApplication = import("express").Application, -> = T extends ExpressApplication - ? ExpressRequestHandler | ExpressErrorRequestHandler - : HandleFunction; -type MiddlewareObject = { - name?: string; - path?: string; - middleware: MiddlewareHandler; -}; -type Middleware = MiddlewareObject | MiddlewareHandler; -type BasicServer = import("net").Server | import("tls").Server; -type Configuration< - A extends BasicApplication = import("express").Application, - S extends BasicServer = import("http").Server< - typeof import("http").IncomingMessage, - typeof import("http").ServerResponse - >, -> = { - ipc?: (boolean | string) | undefined; - host?: Host | undefined; - port?: Port | undefined; - hot?: (boolean | "only") | undefined; - liveReload?: boolean | undefined; - devMiddleware?: DevMiddlewareOptions | undefined; - compress?: boolean | undefined; - allowedHosts?: ("auto" | "all" | string | string[]) | undefined; - historyApiFallback?: (boolean | ConnectHistoryApiFallbackOptions) | undefined; - bonjour?: (boolean | Record | BonjourOptions) | undefined; - watchFiles?: - | (string | string[] | WatchFiles | Array) - | undefined; - static?: (boolean | string | Static | Array) | undefined; - server?: (ServerType | ServerConfiguration) | undefined; - app?: (() => Promise) | undefined; - webSocketServer?: - | (boolean | "ws" | string | WebSocketServerConfiguration) - | undefined; - proxy?: ProxyConfigArray | undefined; - open?: (boolean | string | Open | Array) | undefined; - setupExitSignals?: boolean | undefined; - client?: (boolean | ClientConfiguration) | 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; -}; + stopCallback(callback?: ((err?: Error) => void) | undefined): void; + #private; +} /** * @overload * @param {NextHandleFunction} fn function diff --git a/types/lib/getPort.d.ts b/types/lib/getPort.d.ts index 677eb97671..d6eec701a3 100644 --- a/types/lib/getPort.d.ts +++ b/types/lib/getPort.d.ts @@ -1,4 +1,4 @@ -export = getPorts; +export default getPorts; /** * @param {number} basePort base port * @param {string=} host host diff --git a/types/lib/servers/BaseServer.d.ts b/types/lib/servers/BaseServer.d.ts index 07d29fb4b5..4094129b1a 100644 --- a/types/lib/servers/BaseServer.d.ts +++ b/types/lib/servers/BaseServer.d.ts @@ -1,15 +1,12 @@ -export = BaseServer; -declare class BaseServer { +/** @typedef {import("../Server.js").ClientConnection} ClientConnection */ +export default class BaseServer { /** - * @param {import("../Server")} server server + * @param {import("../Server.js").default} server server */ - constructor(server: import("../Server")); - /** @type {import("../Server")} */ - server: import("../Server"); + constructor(server: import("../Server.js").default); + /** @type {import("../Server.js").default} */ + server: import("../Server.js").default; /** @type {ClientConnection[]} */ clients: ClientConnection[]; } -declare namespace BaseServer { - export { ClientConnection }; -} -type ClientConnection = import("../Server").ClientConnection; +export type ClientConnection = import("../Server.js").ClientConnection; diff --git a/types/lib/servers/WebsocketServer.d.ts b/types/lib/servers/WebsocketServer.d.ts index ce8c693789..19e7acbcd8 100644 --- a/types/lib/servers/WebsocketServer.d.ts +++ b/types/lib/servers/WebsocketServer.d.ts @@ -1,16 +1,13 @@ -export = WebsocketServer; -declare class WebsocketServer extends BaseServer { +/** @typedef {import("../Server.js").WebSocketServerConfiguration} WebSocketServerConfiguration */ +/** @typedef {import("../Server.js").ClientConnection} ClientConnection */ +export default class WebsocketServer extends BaseServer { static heartbeatInterval: number; - implementation: WebSocket.Server< - typeof WebSocket, + implementation: import("ws").Server< + typeof import("ws").default, typeof import("http").IncomingMessage >; } -declare namespace WebsocketServer { - export { WebSocketServerConfiguration, ClientConnection }; -} -import BaseServer = require("./BaseServer"); -import WebSocket = require("ws"); -type WebSocketServerConfiguration = - import("../Server").WebSocketServerConfiguration; -type ClientConnection = import("../Server").ClientConnection; +export type WebSocketServerConfiguration = + import("../Server.js").WebSocketServerConfiguration; +export type ClientConnection = import("../Server.js").ClientConnection; +import BaseServer from "./BaseServer.js"; From a59fdbab2cfe1da5dd8003ffae4e2e6d35b348e1 Mon Sep 17 00:00:00 2001 From: Sebastian Beltran Date: Mon, 11 May 2026 09:24:20 -0500 Subject: [PATCH 02/29] refactor: migrate ports-map.js to ES module syntax --- test/ports-map.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/test/ports-map.js b/test/ports-map.js index d898970fdf..e980495bc9 100644 --- a/test/ports-map.js +++ b/test/ports-map.js @@ -1,5 +1,3 @@ -"use strict"; - // important: new port mappings must be added to the bottom of this list const listOfTests = { // CLI tests @@ -98,7 +96,7 @@ for (const key of Object.keys(listOfTests)) { const busy = {}; -module.exports = new Proxy(ports, { +export default new Proxy(ports, { get(target, name) { if (!target[name]) { throw new Error( From d109bb9d7bd1231fb217af8880fbcff7ce4ef7bd Mon Sep 17 00:00:00 2001 From: Sebastian Beltran Date: Mon, 11 May 2026 09:41:26 -0500 Subject: [PATCH 03/29] refactor: migrate helper files to ES module syntax --- test/helpers/ExitOnDonePlugin.js | 6 +- test/helpers/conditional-test.js | 8 +- test/helpers/custom-http.js | 6 +- test/helpers/html-generator-plugin.js | 6 +- test/helpers/jsdom-setup.js | 4 +- test/helpers/normalize-options.js | 4 +- test/helpers/puppeteer-constants.js | 102 +++++++++--------- test/helpers/run-browser.js | 26 ++--- test/helpers/session-subscribe.js | 6 +- test/helpers/snapshotResolver.js | 25 ----- test/helpers/test-bin.js | 19 ++-- test/helpers/test-server.js | 15 +-- .../trusted-types-html-generator-plugin.js | 6 +- 13 files changed, 86 insertions(+), 147 deletions(-) delete mode 100644 test/helpers/snapshotResolver.js diff --git a/test/helpers/ExitOnDonePlugin.js b/test/helpers/ExitOnDonePlugin.js index 656b58579a..334e9bf9be 100644 --- a/test/helpers/ExitOnDonePlugin.js +++ b/test/helpers/ExitOnDonePlugin.js @@ -1,6 +1,4 @@ -"use strict"; - -module.exports = class ExitOnDonePlugin { +export default class ExitOnDonePlugin { apply(compiler) { compiler.hooks.afterDone.tap("webpack-dev-server", (stats) => { let exitCode = 0; @@ -15,4 +13,4 @@ module.exports = class ExitOnDonePlugin { }); }); } -}; +} diff --git a/test/helpers/conditional-test.js b/test/helpers/conditional-test.js index 7e82106e31..cafa92cb67 100644 --- a/test/helpers/conditional-test.js +++ b/test/helpers/conditional-test.js @@ -1,6 +1,4 @@ -"use strict"; - -const { test } = require("node:test"); +import { test } from "node:test"; const isWindows = process.platform === "win32"; @@ -8,12 +6,10 @@ const isWindows = process.platform === "win32"; * @param {string} reason reason * @returns {boolean} true when it is windows, otherwise false */ -function skipTestOnWindows(reason) { +export function skipTestOnWindows(reason) { if (isWindows) { test.skip(reason, () => {}); } return isWindows; } - -module.exports.skipTestOnWindows = skipTestOnWindows; diff --git a/test/helpers/custom-http.js b/test/helpers/custom-http.js index 29046c9bc3..9b4866f1b2 100644 --- a/test/helpers/custom-http.js +++ b/test/helpers/custom-http.js @@ -1,5 +1 @@ -"use strict"; - -const customHTTP = require("node:http"); - -module.exports = customHTTP; +export { default } from "node:http"; diff --git a/test/helpers/html-generator-plugin.js b/test/helpers/html-generator-plugin.js index 261d16e592..6b469ea12c 100644 --- a/test/helpers/html-generator-plugin.js +++ b/test/helpers/html-generator-plugin.js @@ -1,5 +1,3 @@ -"use strict"; - const HTMLContentForIndex = ` @@ -41,7 +39,7 @@ const HTMLContentForTest = ` `; -module.exports = class HTMLGeneratorPlugin { +export default class HTMLGeneratorPlugin { apply(compiler) { const pluginName = "html-generator-plugin"; @@ -79,4 +77,4 @@ module.exports = class HTMLGeneratorPlugin { ); }); } -}; +} diff --git a/test/helpers/jsdom-setup.js b/test/helpers/jsdom-setup.js index 5098e4dcea..919aae51b4 100644 --- a/test/helpers/jsdom-setup.js +++ b/test/helpers/jsdom-setup.js @@ -1,6 +1,4 @@ -"use strict"; - -const { JSDOM } = require("jsdom"); +import { JSDOM } from "jsdom"; const dom = new JSDOM("", { url: "http://localhost/", diff --git a/test/helpers/normalize-options.js b/test/helpers/normalize-options.js index 923b8146e1..fa34ec779e 100644 --- a/test/helpers/normalize-options.js +++ b/test/helpers/normalize-options.js @@ -1,5 +1,3 @@ -"use strict"; - /** * @param {import("https").ServerOptions} options server options * @returns {Record} normalized server options @@ -38,4 +36,4 @@ function normalizeOptions(options) { return normalizedOptions; } -module.exports = normalizeOptions; +export default normalizeOptions; diff --git a/test/helpers/puppeteer-constants.js b/test/helpers/puppeteer-constants.js index 23bce93c45..346298d823 100644 --- a/test/helpers/puppeteer-constants.js +++ b/test/helpers/puppeteer-constants.js @@ -1,53 +1,49 @@ -"use strict"; - -module.exports = { - reloadReadyDelay: 5000, - completeReloadDelay: 10000, - initConsoleDelay: 3000, - awaitServerCloseDelay: 1000, - beforeBrowserCloseDelay: 3000, - puppeteerArgs: [ - "--disable-background-timer-throttling", - "--disable-breakpad", - "--disable-client-side-phishing-detection", - "--disable-cloud-import", - "--disable-default-apps", - "--disable-dev-shm-usage", - "--disable-extensions", - "--disable-gesture-typing", - "--disable-hang-monitor", - "--disable-infobars", - "--disable-notifications", - "--disable-offer-store-unmasked-wallet-cards", - "--disable-offer-upload-credit-cards", - "--disable-popup-blocking", - "--disable-print-preview", - "--disable-prompt-on-repost", - "--disable-setuid-sandbox", - "--disable-speech-api", - "--disable-sync", - "--disable-tab-for-desktop-share", - "--disable-translate", - "--disable-voice-input", - "--disable-wake-on-wifi", - "--enable-async-dns", - "--enable-simple-cache-backend", - "--enable-tcp-fast-open", - "--enable-webgl", - "--hide-scrollbars", - "--ignore-gpu-blacklist", - "--media-cache-size=33554432", - "--metrics-recording-only", - "--mute-audio", - "--no-default-browser-check", - "--no-first-run", - "--no-pings", - "--no-sandbox", - "--no-zygote", - "--password-store=basic", - "--prerender-from-omnibox=disabled", - "--use-gl=swiftshader", - "--use-mock-keychain", - "--disable-field-trial-config", - ], -}; +export const reloadReadyDelay = 5000; +export const completeReloadDelay = 10000; +export const initConsoleDelay = 3000; +export const awaitServerCloseDelay = 1000; +export const beforeBrowserCloseDelay = 3000; +export const puppeteerArgs = [ + "--disable-background-timer-throttling", + "--disable-breakpad", + "--disable-client-side-phishing-detection", + "--disable-cloud-import", + "--disable-default-apps", + "--disable-dev-shm-usage", + "--disable-extensions", + "--disable-gesture-typing", + "--disable-hang-monitor", + "--disable-infobars", + "--disable-notifications", + "--disable-offer-store-unmasked-wallet-cards", + "--disable-offer-upload-credit-cards", + "--disable-popup-blocking", + "--disable-print-preview", + "--disable-prompt-on-repost", + "--disable-setuid-sandbox", + "--disable-speech-api", + "--disable-sync", + "--disable-tab-for-desktop-share", + "--disable-translate", + "--disable-voice-input", + "--disable-wake-on-wifi", + "--enable-async-dns", + "--enable-simple-cache-backend", + "--enable-tcp-fast-open", + "--enable-webgl", + "--hide-scrollbars", + "--ignore-gpu-blacklist", + "--media-cache-size=33554432", + "--metrics-recording-only", + "--mute-audio", + "--no-default-browser-check", + "--no-first-run", + "--no-pings", + "--no-sandbox", + "--no-zygote", + "--password-store=basic", + "--prerender-from-omnibox=disabled", + "--use-gl=swiftshader", + "--use-mock-keychain", + "--disable-field-trial-config", +]; diff --git a/test/helpers/run-browser.js b/test/helpers/run-browser.js index e4d00b9ba9..547de9b256 100644 --- a/test/helpers/run-browser.js +++ b/test/helpers/run-browser.js @@ -1,7 +1,5 @@ -"use strict"; - -const puppeteer = require("puppeteer"); -const { puppeteerArgs } = require("./puppeteer-constants"); +import { launch } from "puppeteer"; +import { puppeteerArgs } from "./puppeteer-constants.js"; /** @typedef {import('puppeteer').Browser} Browser */ /** @typedef {import('puppeteer').Page} Page */ @@ -18,7 +16,7 @@ const { puppeteerArgs } = require("./puppeteer-constants"); * @param {Device} device config * @returns {Promise} page */ -function runPage(browser, device) { +export function runPage(browser, device) { /** * @type {Page} */ @@ -77,14 +75,13 @@ function runBrowser(device) { */ 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, - }) + 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; @@ -99,5 +96,4 @@ function runBrowser(device) { }); } -module.exports = runBrowser; -module.exports.runPage = runPage; +export default runBrowser; diff --git a/test/helpers/session-subscribe.js b/test/helpers/session-subscribe.js index 9287e2646a..7a1fdb9795 100644 --- a/test/helpers/session-subscribe.js +++ b/test/helpers/session-subscribe.js @@ -1,9 +1,7 @@ -"use strict"; - -module.exports = async function sessionSubscribe(session) { +export default async function sessionSubscribe(session) { session.on("sessionattached", (attachedSession) => { sessionSubscribe(attachedSession); }); await session.send("Network.enable"); await session.send("Runtime.runIfWaitingForDebugger"); -}; +} diff --git a/test/helpers/snapshotResolver.js b/test/helpers/snapshotResolver.js deleted file mode 100644 index cd4aa21bc0..0000000000 --- a/test/helpers/snapshotResolver.js +++ /dev/null @@ -1,25 +0,0 @@ -"use strict"; - -const path = require("node:path"); -const webpack = require("webpack"); - -const [webpackVersion] = webpack.version; -const snapshotExtension = `.snap.webpack${webpackVersion}`; - -module.exports = { - resolveSnapshotPath: (testPath) => - path.join( - path.dirname(testPath), - "__snapshots__", - `${path.basename(testPath)}${snapshotExtension}`, - ), - resolveTestPath: (snapshotPath) => - snapshotPath - .replace(`${path.sep}__snapshots__`, "") - .slice(0, -snapshotExtension.length), - testPathForConsistencyCheck: path.join( - "consistency_check", - "__tests__", - "example.test.js", - ), -}; diff --git a/test/helpers/test-bin.js b/test/helpers/test-bin.js index ecec46868b..cdc1eb64be 100644 --- a/test/helpers/test-bin.js +++ b/test/helpers/test-bin.js @@ -1,10 +1,11 @@ -"use strict"; +import os from "node:os"; +import path from "node:path"; +import { fileURLToPath } from "node:url"; +import util from "node:util"; +import execa from "execa"; +import { Writable } from "readable-stream"; -const os = require("node:os"); -const path = require("node:path"); -const util = require("node:util"); -const execa = require("execa"); -const { Writable } = require("readable-stream"); +const __dirname = path.dirname(fileURLToPath(import.meta.url)); const webpackDevServerPath = path.resolve( __dirname, @@ -27,7 +28,7 @@ const processKill = (process) => { // } }; -const testBin = (testArgs = [], options = {}) => { +export const testBin = (testArgs = [], options = {}) => { const cwd = process.cwd(); const env = { WEBPACK_CLI_HELP_WIDTH: 2048, @@ -127,7 +128,7 @@ const ipV6 = ` .replaceAll("\n", "") .trim(); -const normalizeStderr = (stderr, options = {}) => { +export const normalizeStderr = (stderr, options = {}) => { let normalizedStderr = util.stripVTControlCharacters(stderr); normalizedStderr = normalizedStderr @@ -207,5 +208,3 @@ const normalizeStderr = (stderr, options = {}) => { return normalizedStderr; }; - -module.exports = { normalizeStderr, testBin }; diff --git a/test/helpers/test-server.js b/test/helpers/test-server.js index 9333c64601..e6ba6a4790 100644 --- a/test/helpers/test-server.js +++ b/test/helpers/test-server.js @@ -1,7 +1,5 @@ -"use strict"; - -const webpack = require("webpack"); -const Server = require("../../lib/Server"); +import webpack from "webpack"; +import Server from "../../lib/Server.js"; /** @typedef {import("webpack").Configuration} Configuration */ /** @typedef {import("../../lib/Server").Configuration} DevServerConfiguration */ @@ -54,7 +52,7 @@ function startFullSetup(config, devServerConfig, done) { * @param {(err?: Error) => void=} done done callback * @returns {Server} server */ -function start(config, devServerConfig, done) { +export function start(config, devServerConfig, done) { let readyCount = 0; const ready = (error) => { @@ -85,7 +83,7 @@ function start(config, devServerConfig, done) { /** * @param {() => void} done done callback */ -function close(done) { +export function close(done) { if (server) { server.stopCallback(() => { server = null; @@ -95,8 +93,3 @@ function close(done) { done(); } } - -module.exports = { - close, - start, -}; diff --git a/test/helpers/trusted-types-html-generator-plugin.js b/test/helpers/trusted-types-html-generator-plugin.js index 6d023305db..1daf0ed870 100644 --- a/test/helpers/trusted-types-html-generator-plugin.js +++ b/test/helpers/trusted-types-html-generator-plugin.js @@ -1,5 +1,3 @@ -"use strict"; - const HTMLContentForIndex = ` @@ -35,7 +33,7 @@ const HTMLContentForTest = ` `; -module.exports = class HTMLGeneratorPlugin { +export default class HTMLGeneratorPlugin { apply(compiler) { const pluginName = "html-generator-plugin"; @@ -78,4 +76,4 @@ module.exports = class HTMLGeneratorPlugin { } }); } -}; +} From d7e222b1121ce4aa43d4fa3b7e57ff1dc8d7a76b Mon Sep 17 00:00:00 2001 From: Sebastian Beltran Date: Mon, 11 May 2026 09:52:29 -0500 Subject: [PATCH 04/29] refactor: migrate fixtures configs to ES module syntax --- .../cli-colors-default-stats/webpack.config.js | 7 +++++-- test/fixtures/cli-colors-disabled/webpack.config.js | 7 +++++-- test/fixtures/cli-colors-enabled/webpack.config.js | 7 +++++-- test/fixtures/cli-empty-entry/webpack.config.js | 4 +--- .../cli-entry-as-descriptor/webpack.config.js | 7 +++++-- test/fixtures/cli-multi-entry/webpack.config.js | 7 ++++--- test/fixtures/cli-promise-config/webpack.config.js | 7 ++++--- test/fixtures/cli-single-entry/webpack.config.js | 7 ++++--- test/fixtures/cli-target-config/webpack.config.js | 7 ++++--- .../cli-universal-compiler-config/webpack.config.js | 7 +++++-- test/fixtures/cli/webpack.config.js | 7 +++++-- test/fixtures/client-config/webpack.config.js | 8 +++++--- test/fixtures/custom-client/CustomWebSocketClient.js | 6 ++---- test/fixtures/dev-public-path/webpack.config.js | 7 ++++--- test/fixtures/dev-server/client-custom-path-config.js | 7 ++++--- .../fixtures/dev-server/client-default-path-config.js | 7 ++++--- test/fixtures/entry-as-function/webpack.config.js | 7 +++++-- .../historyapifallback-2-config/webpack.config.js | 7 +++++-- test/fixtures/historyapifallback-3-config/foo.js | 4 +--- .../historyapifallback-3-config/webpack.config.js | 7 ++++--- test/fixtures/historyapifallback-config/foo.js | 6 ++---- .../historyapifallback-config/webpack.config.js | 7 ++++--- .../webpack.config.js | 7 ++++--- .../lazy-compilation-single-entry/webpack.config.js | 7 ++++--- test/fixtures/mime-types-config/foo.js | 4 +--- test/fixtures/mime-types-config/webpack.config.js | 7 ++++--- test/fixtures/module-federation-config/entry1.js | 4 +--- test/fixtures/module-federation-config/entry2.js | 4 +--- .../module-federation-config/webpack.config.js | 7 +++++-- .../module-federation-config/webpack.multi.config.js | 7 +++++-- .../webpack.object-entry.config.js | 7 +++++-- .../module-federation-config/webpack.plugin.js | 11 +++++++---- .../webpack.config.js | 8 +++++--- .../webpack.config.js | 8 +++++--- test/fixtures/multi-public-path-config/foo.js | 4 +--- .../multi-public-path-config/webpack.config.js | 7 ++++--- .../overlay-config/trusted-types.webpack.config.js | 8 +++++--- test/fixtures/overlay-config/webpack.config.js | 8 +++++--- test/fixtures/provide-plugin-custom/foo.js | 4 +--- test/fixtures/provide-plugin-custom/webpack.config.js | 8 +++++--- test/fixtures/provide-plugin-default/foo.js | 5 +---- .../fixtures/provide-plugin-default/webpack.config.js | 8 +++++--- test/fixtures/provide-plugin-ws-config/foo.js | 5 +---- .../provide-plugin-ws-config/webpack.config.js | 8 +++++--- test/fixtures/proxy-config/webpack.config.js | 7 +++++-- test/fixtures/reload-config-2/foo.js | 4 +--- test/fixtures/reload-config-2/webpack.config.js | 8 +++++--- test/fixtures/reload-config/foo.js | 4 +--- test/fixtures/reload-config/webpack.config.js | 8 +++++--- test/fixtures/schema/webpack.config.simple.js | 7 +++++-- test/fixtures/simple-config-other/webpack.config.js | 7 +++++-- test/fixtures/simple-config/webpack.config.js | 8 +++++--- test/fixtures/static-config/webpack.config.js | 7 +++++-- test/fixtures/static/webpack.config.js | 7 ++++--- .../universal-compiler-config/webpack.config.js | 8 +++++--- test/fixtures/watch-files-config/webpack.config.js | 8 +++++--- .../worker-config-dev-server-false/webpack.config.js | 9 +++++---- test/fixtures/worker-config/webpack.config.js | 8 +++++--- 58 files changed, 228 insertions(+), 165 deletions(-) diff --git a/test/fixtures/cli-colors-default-stats/webpack.config.js b/test/fixtures/cli-colors-default-stats/webpack.config.js index 856a6d18a2..dc3b9cff4e 100644 --- a/test/fixtures/cli-colors-default-stats/webpack.config.js +++ b/test/fixtures/cli-colors-default-stats/webpack.config.js @@ -1,6 +1,9 @@ -"use strict"; +import path from "node:path"; +import { fileURLToPath } from "node:url"; -module.exports = { +const __dirname = path.dirname(fileURLToPath(import.meta.url)); + +export default { mode: "development", context: __dirname, entry: "./foo.js", diff --git a/test/fixtures/cli-colors-disabled/webpack.config.js b/test/fixtures/cli-colors-disabled/webpack.config.js index e0c751cb9e..630461f4f0 100644 --- a/test/fixtures/cli-colors-disabled/webpack.config.js +++ b/test/fixtures/cli-colors-disabled/webpack.config.js @@ -1,6 +1,9 @@ -"use strict"; +import path from "node:path"; +import { fileURLToPath } from "node:url"; -module.exports = { +const __dirname = path.dirname(fileURLToPath(import.meta.url)); + +export default { mode: "development", stats: { colors: false, diff --git a/test/fixtures/cli-colors-enabled/webpack.config.js b/test/fixtures/cli-colors-enabled/webpack.config.js index 9cdfeb4a69..e8b0a7d80a 100644 --- a/test/fixtures/cli-colors-enabled/webpack.config.js +++ b/test/fixtures/cli-colors-enabled/webpack.config.js @@ -1,6 +1,9 @@ -"use strict"; +import path from "node:path"; +import { fileURLToPath } from "node:url"; -module.exports = { +const __dirname = path.dirname(fileURLToPath(import.meta.url)); + +export default { mode: "development", stats: { colors: true, diff --git a/test/fixtures/cli-empty-entry/webpack.config.js b/test/fixtures/cli-empty-entry/webpack.config.js index 82d77e536f..f6d4be0bf0 100644 --- a/test/fixtures/cli-empty-entry/webpack.config.js +++ b/test/fixtures/cli-empty-entry/webpack.config.js @@ -1,6 +1,4 @@ -"use strict"; - -module.exports = { +export default { mode: "development", stats: { orphanModules: true, preset: "detailed" }, entry: {}, diff --git a/test/fixtures/cli-entry-as-descriptor/webpack.config.js b/test/fixtures/cli-entry-as-descriptor/webpack.config.js index d7649d4b3c..300ccf9f97 100644 --- a/test/fixtures/cli-entry-as-descriptor/webpack.config.js +++ b/test/fixtures/cli-entry-as-descriptor/webpack.config.js @@ -1,6 +1,9 @@ -"use strict"; +import path from "node:path"; +import { fileURLToPath } from "node:url"; -module.exports = { +const __dirname = path.dirname(fileURLToPath(import.meta.url)); + +export default { mode: "development", context: __dirname, entry: { diff --git a/test/fixtures/cli-multi-entry/webpack.config.js b/test/fixtures/cli-multi-entry/webpack.config.js index c171eb78c8..62ac3132cb 100644 --- a/test/fixtures/cli-multi-entry/webpack.config.js +++ b/test/fixtures/cli-multi-entry/webpack.config.js @@ -1,8 +1,9 @@ -"use strict"; +import path, { resolve } from "node:path"; +import { fileURLToPath } from "node:url"; -const { resolve } = require("path"); +const __dirname = path.dirname(fileURLToPath(import.meta.url)); -module.exports = { +export default { mode: "development", stats: "detailed", context: __dirname, diff --git a/test/fixtures/cli-promise-config/webpack.config.js b/test/fixtures/cli-promise-config/webpack.config.js index a75b90a920..d75b468886 100644 --- a/test/fixtures/cli-promise-config/webpack.config.js +++ b/test/fixtures/cli-promise-config/webpack.config.js @@ -1,8 +1,9 @@ -"use strict"; +import path, { join } from "node:path"; +import { fileURLToPath } from "node:url"; -const { join } = require("path"); +const __dirname = path.dirname(fileURLToPath(import.meta.url)); -module.exports = () => +export default () => new Promise((resolve) => { resolve({ mode: "development", diff --git a/test/fixtures/cli-single-entry/webpack.config.js b/test/fixtures/cli-single-entry/webpack.config.js index 2106279701..1a9dc8b050 100644 --- a/test/fixtures/cli-single-entry/webpack.config.js +++ b/test/fixtures/cli-single-entry/webpack.config.js @@ -1,8 +1,9 @@ -"use strict"; +import path, { resolve } from "node:path"; +import { fileURLToPath } from "node:url"; -const { resolve } = require("path"); +const __dirname = path.dirname(fileURLToPath(import.meta.url)); -module.exports = { +export default { mode: "development", stats: "detailed", entry: resolve(__dirname, "./foo.js"), diff --git a/test/fixtures/cli-target-config/webpack.config.js b/test/fixtures/cli-target-config/webpack.config.js index 6b6380e474..bfc85ffa88 100644 --- a/test/fixtures/cli-target-config/webpack.config.js +++ b/test/fixtures/cli-target-config/webpack.config.js @@ -1,8 +1,9 @@ -"use strict"; +import path, { resolve } from "node:path"; +import { fileURLToPath } from "node:url"; -const { resolve } = require("path"); +const __dirname = path.dirname(fileURLToPath(import.meta.url)); -module.exports = { +export default { mode: "development", stats: "detailed", entry: resolve(__dirname, "./foo.js"), diff --git a/test/fixtures/cli-universal-compiler-config/webpack.config.js b/test/fixtures/cli-universal-compiler-config/webpack.config.js index 7562d54206..cbb08cbd60 100644 --- a/test/fixtures/cli-universal-compiler-config/webpack.config.js +++ b/test/fixtures/cli-universal-compiler-config/webpack.config.js @@ -1,6 +1,9 @@ -"use strict"; +import path from "node:path"; +import { fileURLToPath } from "node:url"; -module.exports = [ +const __dirname = path.dirname(fileURLToPath(import.meta.url)); + +export default [ { name: "client", mode: "development", diff --git a/test/fixtures/cli/webpack.config.js b/test/fixtures/cli/webpack.config.js index 20a13bb93d..c671dbb513 100644 --- a/test/fixtures/cli/webpack.config.js +++ b/test/fixtures/cli/webpack.config.js @@ -1,6 +1,9 @@ -"use strict"; +import path from "node:path"; +import { fileURLToPath } from "node:url"; -module.exports = { +const __dirname = path.dirname(fileURLToPath(import.meta.url)); + +export default { mode: "development", stats: "detailed", context: __dirname, diff --git a/test/fixtures/client-config/webpack.config.js b/test/fixtures/client-config/webpack.config.js index 41cfbc5928..3a44fbfc82 100644 --- a/test/fixtures/client-config/webpack.config.js +++ b/test/fixtures/client-config/webpack.config.js @@ -1,8 +1,10 @@ -"use strict"; +import path from "node:path"; +import { fileURLToPath } from "node:url"; +import HTMLGeneratorPlugin from "../../helpers/html-generator-plugin.js"; -const HTMLGeneratorPlugin = require("../../helpers/html-generator-plugin"); +const __dirname = path.dirname(fileURLToPath(import.meta.url)); -module.exports = { +export default { devtool: false, mode: "development", context: __dirname, diff --git a/test/fixtures/custom-client/CustomWebSocketClient.js b/test/fixtures/custom-client/CustomWebSocketClient.js index 58ec6c2136..94490700f0 100644 --- a/test/fixtures/custom-client/CustomWebSocketClient.js +++ b/test/fixtures/custom-client/CustomWebSocketClient.js @@ -1,6 +1,4 @@ -"use strict"; - -module.exports = class WebSocketClient { +export default class WebSocketClient { constructor(url) { this.client = new WebSocket(url); this.client.onerror = (error) => { @@ -30,4 +28,4 @@ module.exports = class WebSocketClient { f(e.data); }; } -}; +} diff --git a/test/fixtures/dev-public-path/webpack.config.js b/test/fixtures/dev-public-path/webpack.config.js index 2faa9805d1..55dd346ec2 100644 --- a/test/fixtures/dev-public-path/webpack.config.js +++ b/test/fixtures/dev-public-path/webpack.config.js @@ -1,8 +1,9 @@ -"use strict"; +import path, { join } from "node:path"; +import { fileURLToPath } from "node:url"; -const { join } = require("path"); +const __dirname = path.dirname(fileURLToPath(import.meta.url)); -module.exports = { +export default { mode: "development", entry: join(__dirname, "foo.js"), devServer: { diff --git a/test/fixtures/dev-server/client-custom-path-config.js b/test/fixtures/dev-server/client-custom-path-config.js index 8c9d377854..487644c33b 100644 --- a/test/fixtures/dev-server/client-custom-path-config.js +++ b/test/fixtures/dev-server/client-custom-path-config.js @@ -1,8 +1,9 @@ -"use strict"; +import path, { resolve } from "node:path"; +import { fileURLToPath } from "node:url"; -const { resolve } = require("path"); +const __dirname = path.dirname(fileURLToPath(import.meta.url)); -module.exports = { +export default { mode: "development", stats: "detailed", entry: resolve(__dirname, "./foo.js"), diff --git a/test/fixtures/dev-server/client-default-path-config.js b/test/fixtures/dev-server/client-default-path-config.js index f208a49af4..25355ea55c 100644 --- a/test/fixtures/dev-server/client-default-path-config.js +++ b/test/fixtures/dev-server/client-default-path-config.js @@ -1,8 +1,9 @@ -"use strict"; +import path, { resolve } from "node:path"; +import { fileURLToPath } from "node:url"; -const { resolve } = require("path"); +const __dirname = path.dirname(fileURLToPath(import.meta.url)); -module.exports = { +export default { mode: "development", stats: "detailed", entry: resolve(__dirname, "./foo.js"), diff --git a/test/fixtures/entry-as-function/webpack.config.js b/test/fixtures/entry-as-function/webpack.config.js index cf48f0b924..b0add3e0ff 100644 --- a/test/fixtures/entry-as-function/webpack.config.js +++ b/test/fixtures/entry-as-function/webpack.config.js @@ -1,6 +1,9 @@ -"use strict"; +import path from "node:path"; +import { fileURLToPath } from "node:url"; -module.exports = { +const __dirname = path.dirname(fileURLToPath(import.meta.url)); + +export default { mode: "development", context: __dirname, entry: () => "./foo.js", diff --git a/test/fixtures/historyapifallback-2-config/webpack.config.js b/test/fixtures/historyapifallback-2-config/webpack.config.js index f03898aa61..49b0c25f95 100644 --- a/test/fixtures/historyapifallback-2-config/webpack.config.js +++ b/test/fixtures/historyapifallback-2-config/webpack.config.js @@ -1,6 +1,9 @@ -"use strict"; +import path from "node:path"; +import { fileURLToPath } from "node:url"; -module.exports = { +const __dirname = path.dirname(fileURLToPath(import.meta.url)); + +export default { mode: "development", context: __dirname, stats: "none", diff --git a/test/fixtures/historyapifallback-3-config/foo.js b/test/fixtures/historyapifallback-3-config/foo.js index aae7eee3a7..ff0128eab4 100644 --- a/test/fixtures/historyapifallback-3-config/foo.js +++ b/test/fixtures/historyapifallback-3-config/foo.js @@ -1,5 +1,3 @@ -"use strict"; - -require("./bar.html"); +import "./bar.html"; console.log("Hey."); diff --git a/test/fixtures/historyapifallback-3-config/webpack.config.js b/test/fixtures/historyapifallback-3-config/webpack.config.js index 792be36f9c..635fb6ad4c 100644 --- a/test/fixtures/historyapifallback-3-config/webpack.config.js +++ b/test/fixtures/historyapifallback-3-config/webpack.config.js @@ -1,6 +1,7 @@ -"use strict"; +import path from "node:path"; +import { fileURLToPath } from "node:url"; -const moduleRuleForHTML = { +const __dirname = path.dirname(fileURLToPath(import.meta.url));const moduleRuleForHTML = { test: /\.html$/, type: "asset/resource", generator: { @@ -8,7 +9,7 @@ const moduleRuleForHTML = { }, }; -module.exports = { +export default { mode: "development", context: __dirname, stats: "none", diff --git a/test/fixtures/historyapifallback-config/foo.js b/test/fixtures/historyapifallback-config/foo.js index fa06808d30..49d08468b9 100644 --- a/test/fixtures/historyapifallback-config/foo.js +++ b/test/fixtures/historyapifallback-config/foo.js @@ -1,6 +1,4 @@ -"use strict"; - -require("./index.html"); -require("./bar.html"); +import "./index.html"; +import "./bar.html"; console.log("Hey."); diff --git a/test/fixtures/historyapifallback-config/webpack.config.js b/test/fixtures/historyapifallback-config/webpack.config.js index bf2a52ba91..03f0045481 100644 --- a/test/fixtures/historyapifallback-config/webpack.config.js +++ b/test/fixtures/historyapifallback-config/webpack.config.js @@ -1,6 +1,7 @@ -"use strict"; +import path from "node:path"; +import { fileURLToPath } from "node:url"; -const moduleRuleForHTML = { +const __dirname = path.dirname(fileURLToPath(import.meta.url));const moduleRuleForHTML = { test: /\.html$/, type: "asset/resource", generator: { @@ -8,7 +9,7 @@ const moduleRuleForHTML = { }, }; -module.exports = { +export default { mode: "development", context: __dirname, stats: "none", diff --git a/test/fixtures/lazy-compilation-multiple-entries/webpack.config.js b/test/fixtures/lazy-compilation-multiple-entries/webpack.config.js index 74f65f722b..f3ce49d37b 100644 --- a/test/fixtures/lazy-compilation-multiple-entries/webpack.config.js +++ b/test/fixtures/lazy-compilation-multiple-entries/webpack.config.js @@ -1,6 +1,7 @@ -"use strict"; +import path from "node:path"; +import { fileURLToPath } from "node:url"; -const oneHTMLContent = ` +const __dirname = path.dirname(fileURLToPath(import.meta.url));const oneHTMLContent = ` @@ -23,7 +24,7 @@ const twoHTMLContent = ` `; -module.exports = { +export default { devtool: false, mode: "development", context: __dirname, diff --git a/test/fixtures/lazy-compilation-single-entry/webpack.config.js b/test/fixtures/lazy-compilation-single-entry/webpack.config.js index c3223f029a..9222f6e6da 100644 --- a/test/fixtures/lazy-compilation-single-entry/webpack.config.js +++ b/test/fixtures/lazy-compilation-single-entry/webpack.config.js @@ -1,6 +1,7 @@ -"use strict"; +import path from "node:path"; +import { fileURLToPath } from "node:url"; -const HTMLContent = ` +const __dirname = path.dirname(fileURLToPath(import.meta.url));const HTMLContent = ` @@ -12,7 +13,7 @@ const HTMLContent = ` `; -module.exports = { +export default { devtool: false, mode: "development", context: __dirname, diff --git a/test/fixtures/mime-types-config/foo.js b/test/fixtures/mime-types-config/foo.js index 739d9bd638..af7b2d3f91 100644 --- a/test/fixtures/mime-types-config/foo.js +++ b/test/fixtures/mime-types-config/foo.js @@ -1,5 +1,3 @@ -"use strict"; - -require("./file.custom"); +import "./file.custom"; console.log("Hey."); diff --git a/test/fixtures/mime-types-config/webpack.config.js b/test/fixtures/mime-types-config/webpack.config.js index 5e59b2d444..0dcbb43634 100644 --- a/test/fixtures/mime-types-config/webpack.config.js +++ b/test/fixtures/mime-types-config/webpack.config.js @@ -1,6 +1,7 @@ -"use strict"; +import path from "node:path"; +import { fileURLToPath } from "node:url"; -const moduleRuleForCustom = { +const __dirname = path.dirname(fileURLToPath(import.meta.url));const moduleRuleForCustom = { test: /\.custom$/, type: "asset/resource", generator: { @@ -8,7 +9,7 @@ const moduleRuleForCustom = { }, }; -module.exports = { +export default { mode: "development", context: __dirname, stats: "none", diff --git a/test/fixtures/module-federation-config/entry1.js b/test/fixtures/module-federation-config/entry1.js index dbd0f49a83..ae45df7780 100644 --- a/test/fixtures/module-federation-config/entry1.js +++ b/test/fixtures/module-federation-config/entry1.js @@ -1,3 +1 @@ -"use strict"; - -module.exports = "entry1"; +export default "entry1"; diff --git a/test/fixtures/module-federation-config/entry2.js b/test/fixtures/module-federation-config/entry2.js index 74f9bc577f..bbfcd5c63c 100644 --- a/test/fixtures/module-federation-config/entry2.js +++ b/test/fixtures/module-federation-config/entry2.js @@ -1,3 +1 @@ -"use strict"; - -module.exports = "entry2"; +export default "entry2"; diff --git a/test/fixtures/module-federation-config/webpack.config.js b/test/fixtures/module-federation-config/webpack.config.js index 269e4cab41..0c5fd8e97c 100644 --- a/test/fixtures/module-federation-config/webpack.config.js +++ b/test/fixtures/module-federation-config/webpack.config.js @@ -1,6 +1,9 @@ -"use strict"; +import path from "node:path"; +import { fileURLToPath } from "node:url"; -module.exports = { +const __dirname = path.dirname(fileURLToPath(import.meta.url)); + +export default { mode: "development", target: "node", stats: "none", diff --git a/test/fixtures/module-federation-config/webpack.multi.config.js b/test/fixtures/module-federation-config/webpack.multi.config.js index 5863c8e14a..5397b3232d 100644 --- a/test/fixtures/module-federation-config/webpack.multi.config.js +++ b/test/fixtures/module-federation-config/webpack.multi.config.js @@ -1,6 +1,9 @@ -"use strict"; +import path from "node:path"; +import { fileURLToPath } from "node:url"; -module.exports = [ +const __dirname = path.dirname(fileURLToPath(import.meta.url)); + +export default [ { mode: "development", target: "node", diff --git a/test/fixtures/module-federation-config/webpack.object-entry.config.js b/test/fixtures/module-federation-config/webpack.object-entry.config.js index 43c47a4183..b80b2539b5 100644 --- a/test/fixtures/module-federation-config/webpack.object-entry.config.js +++ b/test/fixtures/module-federation-config/webpack.object-entry.config.js @@ -1,6 +1,9 @@ -"use strict"; +import path from "node:path"; +import { fileURLToPath } from "node:url"; -module.exports = { +const __dirname = path.dirname(fileURLToPath(import.meta.url)); + +export default { mode: "development", target: "node", stats: "none", diff --git a/test/fixtures/module-federation-config/webpack.plugin.js b/test/fixtures/module-federation-config/webpack.plugin.js index 9178e3c600..c7f28bc20f 100644 --- a/test/fixtures/module-federation-config/webpack.plugin.js +++ b/test/fixtures/module-federation-config/webpack.plugin.js @@ -1,9 +1,12 @@ -"use strict"; +import path from "node:path"; +import { fileURLToPath } from "node:url"; +import webpack from "webpack"; -const ModuleFederationPlugin = - require("webpack").container.ModuleFederationPlugin; +const __dirname = path.dirname(fileURLToPath(import.meta.url)); -module.exports = { +const { ModuleFederationPlugin } = webpack.container; + +export default { mode: "development", target: "node", stats: "none", diff --git a/test/fixtures/multi-compiler-one-configuration/webpack.config.js b/test/fixtures/multi-compiler-one-configuration/webpack.config.js index d00d2b4c86..7ac41529dd 100644 --- a/test/fixtures/multi-compiler-one-configuration/webpack.config.js +++ b/test/fixtures/multi-compiler-one-configuration/webpack.config.js @@ -1,8 +1,10 @@ -"use strict"; +import path from "node:path"; +import { fileURLToPath } from "node:url"; +import HTMLGeneratorPlugin from "../../helpers/html-generator-plugin.js"; -const HTMLGeneratorPlugin = require("../../helpers/html-generator-plugin"); +const __dirname = path.dirname(fileURLToPath(import.meta.url)); -module.exports = [ +export default [ { target: "web", mode: "development", diff --git a/test/fixtures/multi-compiler-two-configurations/webpack.config.js b/test/fixtures/multi-compiler-two-configurations/webpack.config.js index eaeba3006d..8ee150acf6 100644 --- a/test/fixtures/multi-compiler-two-configurations/webpack.config.js +++ b/test/fixtures/multi-compiler-two-configurations/webpack.config.js @@ -1,8 +1,10 @@ -"use strict"; +import path from "node:path"; +import { fileURLToPath } from "node:url"; +import HTMLGeneratorPlugin from "../../helpers/html-generator-plugin.js"; -const HTMLGeneratorPlugin = require("../../helpers/html-generator-plugin"); +const __dirname = path.dirname(fileURLToPath(import.meta.url)); -module.exports = [ +export default [ { target: "web", name: "one", diff --git a/test/fixtures/multi-public-path-config/foo.js b/test/fixtures/multi-public-path-config/foo.js index d2f0aa53dd..287ee67d45 100644 --- a/test/fixtures/multi-public-path-config/foo.js +++ b/test/fixtures/multi-public-path-config/foo.js @@ -1,3 +1 @@ -"use strict"; - -require("./test.html"); +import "./test.html"; diff --git a/test/fixtures/multi-public-path-config/webpack.config.js b/test/fixtures/multi-public-path-config/webpack.config.js index 71e82d2309..7807cb6a56 100644 --- a/test/fixtures/multi-public-path-config/webpack.config.js +++ b/test/fixtures/multi-public-path-config/webpack.config.js @@ -1,6 +1,7 @@ -"use strict"; +import path from "node:path"; +import { fileURLToPath } from "node:url"; -const path = require("path"); +const __dirname = path.dirname(fileURLToPath(import.meta.url)); const moduleRuleForHTML = { test: /\.html$/, @@ -10,7 +11,7 @@ const moduleRuleForHTML = { }, }; -module.exports = [ +export default [ { mode: "development", context: __dirname, diff --git a/test/fixtures/overlay-config/trusted-types.webpack.config.js b/test/fixtures/overlay-config/trusted-types.webpack.config.js index 94c2921269..4839c71b2c 100644 --- a/test/fixtures/overlay-config/trusted-types.webpack.config.js +++ b/test/fixtures/overlay-config/trusted-types.webpack.config.js @@ -1,8 +1,10 @@ -"use strict"; +import path from "node:path"; +import { fileURLToPath } from "node:url"; +import HTMLGeneratorPlugin from "../../helpers/trusted-types-html-generator-plugin.js"; -const HTMLGeneratorPlugin = require("../../helpers/trusted-types-html-generator-plugin"); +const __dirname = path.dirname(fileURLToPath(import.meta.url)); -module.exports = { +export default { mode: "development", context: __dirname, stats: "none", diff --git a/test/fixtures/overlay-config/webpack.config.js b/test/fixtures/overlay-config/webpack.config.js index c1e0b481b1..94e2cc00c3 100644 --- a/test/fixtures/overlay-config/webpack.config.js +++ b/test/fixtures/overlay-config/webpack.config.js @@ -1,8 +1,10 @@ -"use strict"; +import path from "node:path"; +import { fileURLToPath } from "node:url"; +import HTMLGeneratorPlugin from "../../helpers/html-generator-plugin.js"; -const HTMLGeneratorPlugin = require("../../helpers/html-generator-plugin"); +const __dirname = path.dirname(fileURLToPath(import.meta.url)); -module.exports = { +export default { mode: "development", context: __dirname, stats: "none", diff --git a/test/fixtures/provide-plugin-custom/foo.js b/test/fixtures/provide-plugin-custom/foo.js index c1faff1c20..81525bac58 100644 --- a/test/fixtures/provide-plugin-custom/foo.js +++ b/test/fixtures/provide-plugin-custom/foo.js @@ -1,7 +1,5 @@ -"use strict"; - // 'npm run prepare' must be run for this to work during testing -const CustomClient = require("../custom-client/CustomWebSocketClient"); +import CustomClient from "../custom-client/CustomWebSocketClient.js"; window.expectedClient = CustomClient; // eslint-disable-next-line camelcase, no-undef diff --git a/test/fixtures/provide-plugin-custom/webpack.config.js b/test/fixtures/provide-plugin-custom/webpack.config.js index 6006074030..3ca91f1f3f 100644 --- a/test/fixtures/provide-plugin-custom/webpack.config.js +++ b/test/fixtures/provide-plugin-custom/webpack.config.js @@ -1,8 +1,10 @@ -"use strict"; +import path from "node:path"; +import { fileURLToPath } from "node:url"; +import HTMLGeneratorPlugin from "../../helpers/html-generator-plugin.js"; -const HTMLGeneratorPlugin = require("../../helpers/html-generator-plugin"); +const __dirname = path.dirname(fileURLToPath(import.meta.url)); -module.exports = { +export default { mode: "development", context: __dirname, stats: "none", diff --git a/test/fixtures/provide-plugin-default/foo.js b/test/fixtures/provide-plugin-default/foo.js index bd4904444f..a1e1f87ff3 100644 --- a/test/fixtures/provide-plugin-default/foo.js +++ b/test/fixtures/provide-plugin-default/foo.js @@ -1,8 +1,5 @@ -"use strict"; - // 'npm run prepare' must be run for this to work during testing -const WebsocketClient = - require("../../../client/clients/WebSocketClient").default; +import WebsocketClient from "../../../client/clients/WebSocketClient.js"; window.expectedClient = WebsocketClient; // eslint-disable-next-line camelcase, no-undef diff --git a/test/fixtures/provide-plugin-default/webpack.config.js b/test/fixtures/provide-plugin-default/webpack.config.js index 6006074030..3ca91f1f3f 100644 --- a/test/fixtures/provide-plugin-default/webpack.config.js +++ b/test/fixtures/provide-plugin-default/webpack.config.js @@ -1,8 +1,10 @@ -"use strict"; +import path from "node:path"; +import { fileURLToPath } from "node:url"; +import HTMLGeneratorPlugin from "../../helpers/html-generator-plugin.js"; -const HTMLGeneratorPlugin = require("../../helpers/html-generator-plugin"); +const __dirname = path.dirname(fileURLToPath(import.meta.url)); -module.exports = { +export default { mode: "development", context: __dirname, stats: "none", diff --git a/test/fixtures/provide-plugin-ws-config/foo.js b/test/fixtures/provide-plugin-ws-config/foo.js index bd4904444f..a1e1f87ff3 100644 --- a/test/fixtures/provide-plugin-ws-config/foo.js +++ b/test/fixtures/provide-plugin-ws-config/foo.js @@ -1,8 +1,5 @@ -"use strict"; - // 'npm run prepare' must be run for this to work during testing -const WebsocketClient = - require("../../../client/clients/WebSocketClient").default; +import WebsocketClient from "../../../client/clients/WebSocketClient.js"; window.expectedClient = WebsocketClient; // eslint-disable-next-line camelcase, no-undef diff --git a/test/fixtures/provide-plugin-ws-config/webpack.config.js b/test/fixtures/provide-plugin-ws-config/webpack.config.js index 6006074030..3ca91f1f3f 100644 --- a/test/fixtures/provide-plugin-ws-config/webpack.config.js +++ b/test/fixtures/provide-plugin-ws-config/webpack.config.js @@ -1,8 +1,10 @@ -"use strict"; +import path from "node:path"; +import { fileURLToPath } from "node:url"; +import HTMLGeneratorPlugin from "../../helpers/html-generator-plugin.js"; -const HTMLGeneratorPlugin = require("../../helpers/html-generator-plugin"); +const __dirname = path.dirname(fileURLToPath(import.meta.url)); -module.exports = { +export default { mode: "development", context: __dirname, stats: "none", diff --git a/test/fixtures/proxy-config/webpack.config.js b/test/fixtures/proxy-config/webpack.config.js index f03898aa61..49b0c25f95 100644 --- a/test/fixtures/proxy-config/webpack.config.js +++ b/test/fixtures/proxy-config/webpack.config.js @@ -1,6 +1,9 @@ -"use strict"; +import path from "node:path"; +import { fileURLToPath } from "node:url"; -module.exports = { +const __dirname = path.dirname(fileURLToPath(import.meta.url)); + +export default { mode: "development", context: __dirname, stats: "none", diff --git a/test/fixtures/reload-config-2/foo.js b/test/fixtures/reload-config-2/foo.js index 37887d2535..361bfb33ae 100644 --- a/test/fixtures/reload-config-2/foo.js +++ b/test/fixtures/reload-config-2/foo.js @@ -1,4 +1,2 @@ -"use strict"; - // eslint-disable-next-line import/no-unresolved -require("./main.css"); +import "./main.css"; diff --git a/test/fixtures/reload-config-2/webpack.config.js b/test/fixtures/reload-config-2/webpack.config.js index b8d11148bb..272c1adba8 100644 --- a/test/fixtures/reload-config-2/webpack.config.js +++ b/test/fixtures/reload-config-2/webpack.config.js @@ -1,8 +1,10 @@ -"use strict"; +import path from "node:path"; +import { fileURLToPath } from "node:url"; +import HTMLGeneratorPlugin from "../../helpers/html-generator-plugin.js"; -const HTMLGeneratorPlugin = require("../../helpers/html-generator-plugin"); +const __dirname = path.dirname(fileURLToPath(import.meta.url)); -module.exports = { +export default { mode: "development", context: __dirname, stats: "none", diff --git a/test/fixtures/reload-config/foo.js b/test/fixtures/reload-config/foo.js index 68ad7bddf6..1bebc0ca7a 100644 --- a/test/fixtures/reload-config/foo.js +++ b/test/fixtures/reload-config/foo.js @@ -1,3 +1 @@ -"use strict"; - -require("./main.css"); +import "./main.css"; diff --git a/test/fixtures/reload-config/webpack.config.js b/test/fixtures/reload-config/webpack.config.js index 9801ab7ac2..0d36f857a8 100644 --- a/test/fixtures/reload-config/webpack.config.js +++ b/test/fixtures/reload-config/webpack.config.js @@ -1,8 +1,10 @@ -"use strict"; +import path from "node:path"; +import { fileURLToPath } from "node:url"; +import HTMLGeneratorPlugin from "../../helpers/html-generator-plugin.js"; -const HTMLGeneratorPlugin = require("../../helpers/html-generator-plugin"); +const __dirname = path.dirname(fileURLToPath(import.meta.url)); -module.exports = { +export default { mode: "development", context: __dirname, entry: "./foo.js", diff --git a/test/fixtures/schema/webpack.config.simple.js b/test/fixtures/schema/webpack.config.simple.js index ad290af1fb..49649d403d 100644 --- a/test/fixtures/schema/webpack.config.simple.js +++ b/test/fixtures/schema/webpack.config.simple.js @@ -1,6 +1,9 @@ -"use strict"; +import path from "node:path"; +import { fileURLToPath } from "node:url"; -module.exports = { +const __dirname = path.dirname(fileURLToPath(import.meta.url)); + +export default { mode: "development", context: __dirname, entry: "./foo.js", diff --git a/test/fixtures/simple-config-other/webpack.config.js b/test/fixtures/simple-config-other/webpack.config.js index 624dc8a648..15f143f25a 100644 --- a/test/fixtures/simple-config-other/webpack.config.js +++ b/test/fixtures/simple-config-other/webpack.config.js @@ -1,6 +1,9 @@ -"use strict"; +import path from "node:path"; +import { fileURLToPath } from "node:url"; -module.exports = { +const __dirname = path.dirname(fileURLToPath(import.meta.url)); + +export default { mode: "development", context: __dirname, stats: "none", diff --git a/test/fixtures/simple-config/webpack.config.js b/test/fixtures/simple-config/webpack.config.js index 6006074030..3ca91f1f3f 100644 --- a/test/fixtures/simple-config/webpack.config.js +++ b/test/fixtures/simple-config/webpack.config.js @@ -1,8 +1,10 @@ -"use strict"; +import path from "node:path"; +import { fileURLToPath } from "node:url"; +import HTMLGeneratorPlugin from "../../helpers/html-generator-plugin.js"; -const HTMLGeneratorPlugin = require("../../helpers/html-generator-plugin"); +const __dirname = path.dirname(fileURLToPath(import.meta.url)); -module.exports = { +export default { mode: "development", context: __dirname, stats: "none", diff --git a/test/fixtures/static-config/webpack.config.js b/test/fixtures/static-config/webpack.config.js index e0a2dfdbd5..32509ce43c 100644 --- a/test/fixtures/static-config/webpack.config.js +++ b/test/fixtures/static-config/webpack.config.js @@ -1,6 +1,9 @@ -"use strict"; +import path from "node:path"; +import { fileURLToPath } from "node:url"; -module.exports = { +const __dirname = path.dirname(fileURLToPath(import.meta.url)); + +export default { mode: "development", context: __dirname, stats: "none", diff --git a/test/fixtures/static/webpack.config.js b/test/fixtures/static/webpack.config.js index a710816d46..fbaf1ed462 100644 --- a/test/fixtures/static/webpack.config.js +++ b/test/fixtures/static/webpack.config.js @@ -1,8 +1,9 @@ -"use strict"; +import path from "node:path"; +import { fileURLToPath } from "node:url"; -const path = require("path"); +const __dirname = path.dirname(fileURLToPath(import.meta.url)); -module.exports = { +export default { mode: "development", entry: path.resolve(__dirname, "foo.js"), devServer: { diff --git a/test/fixtures/universal-compiler-config/webpack.config.js b/test/fixtures/universal-compiler-config/webpack.config.js index 368e5606f4..d8c6a07af5 100644 --- a/test/fixtures/universal-compiler-config/webpack.config.js +++ b/test/fixtures/universal-compiler-config/webpack.config.js @@ -1,8 +1,10 @@ -"use strict"; +import path from "node:path"; +import { fileURLToPath } from "node:url"; +import HTMLGeneratorPlugin from "../../helpers/html-generator-plugin.js"; -const HTMLGeneratorPlugin = require("../../helpers/html-generator-plugin"); +const __dirname = path.dirname(fileURLToPath(import.meta.url)); -module.exports = [ +export default [ { name: "browser", mode: "development", diff --git a/test/fixtures/watch-files-config/webpack.config.js b/test/fixtures/watch-files-config/webpack.config.js index 2f64765a90..64a75adf88 100644 --- a/test/fixtures/watch-files-config/webpack.config.js +++ b/test/fixtures/watch-files-config/webpack.config.js @@ -1,8 +1,10 @@ -"use strict"; +import path from "node:path"; +import { fileURLToPath } from "node:url"; +import HTMLGeneratorPlugin from "../../helpers/html-generator-plugin.js"; -const HTMLGeneratorPlugin = require("../../helpers/html-generator-plugin"); +const __dirname = path.dirname(fileURLToPath(import.meta.url)); -module.exports = { +export default { mode: "development", devtool: false, context: __dirname, diff --git a/test/fixtures/worker-config-dev-server-false/webpack.config.js b/test/fixtures/worker-config-dev-server-false/webpack.config.js index a53fe51d31..5a8079216c 100644 --- a/test/fixtures/worker-config-dev-server-false/webpack.config.js +++ b/test/fixtures/worker-config-dev-server-false/webpack.config.js @@ -1,9 +1,10 @@ -"use strict"; +import path from "node:path"; +import { fileURLToPath } from "node:url"; +import HTMLGeneratorPlugin from "../../helpers/html-generator-plugin.js"; -const path = require("path"); -const HTMLGeneratorPlugin = require("../../helpers/html-generator-plugin"); +const __dirname = path.dirname(fileURLToPath(import.meta.url)); -module.exports = [ +export default [ { name: "app", // dependencies: ["worker"], diff --git a/test/fixtures/worker-config/webpack.config.js b/test/fixtures/worker-config/webpack.config.js index a4b8cc5940..bf3e51136e 100644 --- a/test/fixtures/worker-config/webpack.config.js +++ b/test/fixtures/worker-config/webpack.config.js @@ -1,8 +1,10 @@ -"use strict"; +import path from "node:path"; +import { fileURLToPath } from "node:url"; +import HTMLGeneratorPlugin from "../../helpers/html-generator-plugin.js"; -const HTMLGeneratorPlugin = require("../../helpers/html-generator-plugin"); +const __dirname = path.dirname(fileURLToPath(import.meta.url)); -module.exports = [ +export default [ { name: "app", dependencies: ["worker"], From 250c87be6bc2ed3f057d8a5b5eadb8873bcd4a4f Mon Sep 17 00:00:00 2001 From: Sebastian Beltran Date: Mon, 11 May 2026 10:00:04 -0500 Subject: [PATCH 05/29] refactor: migrate test files to ES module syntax --- test/normalize-options.test.js | 20 +++++---- test/validate-options.test.js | 76 +++++++++++++++++----------------- 2 files changed, 50 insertions(+), 46 deletions(-) diff --git a/test/normalize-options.test.js b/test/normalize-options.test.js index a5515e8abb..a5591ab139 100644 --- a/test/normalize-options.test.js +++ b/test/normalize-options.test.js @@ -1,11 +1,13 @@ -"use strict"; +import { describe, it } from "node:test"; +import { expect } from "expect"; +import { klona } from "klona/full"; +import webpack from "webpack"; +import Server from "../lib/Server.js"; +import multiCompilerConfig from "./fixtures/multi-compiler-one-configuration/webpack.config.js"; +import simpleConfig from "./fixtures/simple-config/webpack.config.js"; +import portsMap from "./ports-map.js"; -const { describe, it } = require("node:test"); -const { expect } = require("expect"); -const { klona } = require("klona/full"); -const webpack = require("webpack"); -const Server = require("../lib/Server"); -const port = require("./ports-map")["normalize-option"]; +const port = portsMap["normalize-option"]; describe("normalize options", () => { const cases = [ @@ -577,7 +579,7 @@ describe("normalize options", () => { let webpackConfig; if (item.multiCompiler) { - webpackConfig = require("./fixtures/multi-compiler-one-configuration/webpack.config"); + webpackConfig = multiCompilerConfig; if (Array.isArray(item.webpackConfig)) { webpackConfig = item.webpackConfig.map((config, index) => ({ @@ -586,7 +588,7 @@ describe("normalize options", () => { })); } } else { - webpackConfig = require("./fixtures/simple-config/webpack.config"); + webpackConfig = simpleConfig; if (item.webpackConfig) { webpackConfig = { diff --git a/test/validate-options.test.js b/test/validate-options.test.js index 8936e3662e..312860ac3c 100644 --- a/test/validate-options.test.js +++ b/test/validate-options.test.js @@ -1,15 +1,17 @@ -"use strict"; +import os from "node:os"; +import path from "node:path"; +import { after, before, describe, it } from "node:test"; +import { fileURLToPath } from "node:url"; +import connect from "connect"; +import { expect } from "expect"; +import fs from "graceful-fs"; +import { spyOn } from "jest-mock"; +import { Volume, createFsFromVolume } from "memfs"; +import webpack from "webpack"; +import Server from "../lib/Server.js"; +import config from "./fixtures/simple-config/webpack.config.js"; -const os = require("node:os"); -const path = require("node:path"); -const { after, before, describe, it } = require("node:test"); -const { expect } = require("expect"); -const { readFileSync } = require("graceful-fs"); -const { spyOn } = require("jest-mock"); -const { Volume, createFsFromVolume } = require("memfs"); -const webpack = require("webpack"); -const Server = require("../lib/Server"); -const config = require("./fixtures/simple-config/webpack.config"); +const __dirname = path.dirname(fileURLToPath(import.meta.url)); const httpsCertificateDirectory = path.join( __dirname, @@ -272,16 +274,16 @@ const tests = { { type: "https", options: { - ca: readFileSync( + ca: fs.readFileSync( path.join(httpsCertificateDirectory, "ca.pem"), ).toString(), - pfx: readFileSync( + pfx: fs.readFileSync( path.join(httpsCertificateDirectory, "server.pfx"), ).toString(), - key: readFileSync( + key: fs.readFileSync( path.join(httpsCertificateDirectory, "server.key"), ).toString(), - cert: readFileSync( + cert: fs.readFileSync( path.join(httpsCertificateDirectory, "server.crt"), ).toString(), passphrase: "webpack-dev-server", @@ -291,22 +293,22 @@ const tests = { type: "https", options: { ca: [ - readFileSync( + fs.readFileSync( path.join(httpsCertificateDirectory, "ca.pem"), ).toString(), ], pfx: [ - readFileSync( + fs.readFileSync( path.join(httpsCertificateDirectory, "server.pfx"), ).toString(), ], key: [ - readFileSync( + fs.readFileSync( path.join(httpsCertificateDirectory, "server.key"), ).toString(), ], cert: [ - readFileSync( + fs.readFileSync( path.join(httpsCertificateDirectory, "server.crt"), ).toString(), ], @@ -316,10 +318,10 @@ const tests = { { type: "https", options: { - ca: readFileSync(path.join(httpsCertificateDirectory, "ca.pem")), - pfx: readFileSync(path.join(httpsCertificateDirectory, "server.pfx")), - key: readFileSync(path.join(httpsCertificateDirectory, "server.key")), - cert: readFileSync( + 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", @@ -328,15 +330,15 @@ const tests = { { type: "https", options: { - ca: [readFileSync(path.join(httpsCertificateDirectory, "ca.pem"))], + ca: [fs.readFileSync(path.join(httpsCertificateDirectory, "ca.pem"))], pfx: [ - readFileSync(path.join(httpsCertificateDirectory, "server.pfx")), + fs.readFileSync(path.join(httpsCertificateDirectory, "server.pfx")), ], key: [ - readFileSync(path.join(httpsCertificateDirectory, "server.key")), + fs.readFileSync(path.join(httpsCertificateDirectory, "server.key")), ], cert: [ - readFileSync(path.join(httpsCertificateDirectory, "server.crt")), + fs.readFileSync(path.join(httpsCertificateDirectory, "server.crt")), ], passphrase: "webpack-dev-server", }, @@ -356,10 +358,10 @@ const tests = { type: "https", options: { minVersion: "TLSv1.1", - ca: readFileSync(path.join(httpsCertificateDirectory, "ca.pem")), - pfx: readFileSync(path.join(httpsCertificateDirectory, "server.pfx")), - key: readFileSync(path.join(httpsCertificateDirectory, "server.key")), - cert: readFileSync( + 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", @@ -368,22 +370,22 @@ const tests = { { type: "https", options: { - ca: readFileSync(path.join(httpsCertificateDirectory, "ca.pem")), + ca: fs.readFileSync(path.join(httpsCertificateDirectory, "ca.pem")), pfx: [ { - buf: readFileSync( + buf: fs.readFileSync( path.join(httpsCertificateDirectory, "server.pfx"), ), }, ], key: [ { - pem: readFileSync( + pem: fs.readFileSync( path.join(httpsCertificateDirectory, "server.key"), ), }, ], - cert: readFileSync( + cert: fs.readFileSync( path.join(httpsCertificateDirectory, "server.crt"), ), passphrase: "webpack-dev-server", @@ -435,10 +437,10 @@ const tests = { }, app: { success: [ - () => require("connect")(), + () => connect(), async () => new Promise((resolve) => { - resolve(require("connect")()); + resolve(connect()); }), ], failure: ["test", false], From e6e09570d2826f0eeff996defaa44bad07dfa5d5 Mon Sep 17 00:00:00 2001 From: Sebastian Beltran Date: Mon, 11 May 2026 10:20:43 -0500 Subject: [PATCH 06/29] refactor: migrate test files to ES module syntax --- test/cli/allowedHosts-option.test.js | 10 +-- test/cli/basic.test.js | 20 +++--- test/cli/bonjour-option.test.js | 16 ++--- test/cli/client-option.test.js | 10 +-- test/cli/colors.test.js | 23 +++---- test/cli/compress-option.test.js | 10 +-- test/cli/historyApiFallback-option.test.js | 10 +-- test/cli/host-option.test.js | 18 +++--- test/cli/hot-option.test.js | 10 +-- test/cli/ipc-option.test.js | 12 ++-- test/cli/liveReload-option.test.js | 10 +-- test/cli/open-option.test.js | 10 +-- test/cli/port-option.test.js | 10 +-- test/cli/server-option.test.js | 20 +++--- test/cli/static-option.test.js | 10 +-- test/cli/watchFiles-option.test.js | 16 ++--- test/cli/webSocketServer-option.test.js | 10 +-- test/client/ReactErrorBoundary.test.js | 12 ++-- test/client/bundle.test.js | 18 +++--- test/client/clients/WebsocketClient.test.js | 29 +++++---- test/client/index.test.js | 36 +++-------- test/client/socket-helper.test.js | 28 ++++----- test/client/utils/createSocketURL.test.js | 22 +++---- .../utils/getCurrentScriptSource.test.js | 16 ++--- test/client/utils/log.test.js | 22 +++---- test/client/utils/sendMessage.test.js | 12 ++-- test/e2e/allowed-hosts.test.js | 18 +++--- test/e2e/api.test.js | 30 ++++----- test/e2e/app.test.js | 61 +++++++++++-------- test/e2e/bonjour.test.js | 22 +++---- test/e2e/built-in-routes.test.js | 20 +++--- test/e2e/client-reconnect.test.js | 14 ++--- test/e2e/client.test.js | 35 ++++++----- test/e2e/compress.test.js | 14 ++--- test/e2e/cross-origin-request.test.js | 24 ++++---- test/e2e/entry.test.js | 16 ++--- test/e2e/headers.test.js | 20 +++--- test/e2e/history-api-fallback.test.js | 26 ++++---- test/e2e/host.test.js | 20 +++--- test/e2e/hot-and-live-reload.test.js | 55 +++++++++-------- test/e2e/ipc.test.js | 30 ++++----- test/e2e/lazy-compilation.test.js | 16 ++--- test/e2e/logging.test.js | 20 +++--- test/e2e/mime-types.test.js | 14 ++--- test/e2e/module-federation.test.js | 26 ++++---- test/e2e/multi-compiler.test.js | 26 ++++---- test/e2e/on-listening.test.js | 18 +++--- test/e2e/options-middleware.test.js | 20 +++--- test/e2e/overlay.test.js | 30 ++++----- test/e2e/port.test.js | 18 +++--- test/e2e/progress.test.js | 22 +++---- test/e2e/range-header.test.js | 18 +++--- test/e2e/server-and-client-transport.test.js | 27 ++++---- test/e2e/server.test.js | 34 +++++------ test/e2e/setup-exit-signals.test.js | 20 +++--- test/e2e/setup-middlewares.test.js | 14 ++--- test/e2e/static-directory.test.js | 26 ++++---- test/e2e/static-public-path.test.js | 22 +++---- test/e2e/stats.test.js | 18 +++--- test/e2e/target.test.js | 26 ++++---- test/e2e/watch-files.test.js | 22 +++---- test/e2e/web-socket-communication.test.js | 22 +++---- test/e2e/web-socket-server-url.test.js | 24 ++++---- test/e2e/web-socket-server.test.js | 18 +++--- test/server/open-option.test.js | 18 +++--- test/server/proxy-option.test.js | 30 +++++---- 66 files changed, 685 insertions(+), 689 deletions(-) diff --git a/test/cli/allowedHosts-option.test.js b/test/cli/allowedHosts-option.test.js index f6be66b972..575c5000ae 100644 --- a/test/cli/allowedHosts-option.test.js +++ b/test/cli/allowedHosts-option.test.js @@ -1,9 +1,9 @@ -"use strict"; +import { describe, it } from "node:test"; +import { expect } from "expect"; +import { testBin } from "../helpers/test-bin.js"; +import portsMap from "../ports-map.js"; -const { describe, it } = require("node:test"); -const { expect } = require("expect"); -const { testBin } = require("../helpers/test-bin"); -const port = require("../ports-map")["cli-allowed-hosts"]; +const port = portsMap["cli-allowed-hosts"]; describe('"allowedHosts" CLI option', () => { it('should work using "--allowed-hosts auto"', async () => { diff --git a/test/cli/basic.test.js b/test/cli/basic.test.js index 11fe928de0..b5c851721c 100644 --- a/test/cli/basic.test.js +++ b/test/cli/basic.test.js @@ -1,12 +1,14 @@ -"use strict"; - -const path = require("node:path"); -const { describe, it } = require("node:test"); -const util = require("node:util"); -const execa = require("execa"); -const { expect } = require("expect"); -const { normalizeStderr, testBin } = require("../helpers/test-bin"); -const port = require("../ports-map")["cli-basic"]; +import path from "node:path"; +import { fileURLToPath } from "node:url"; +import { describe, it } from "node:test"; +import util from "node:util"; +import execa from "execa"; +import { expect } from "expect"; +import { normalizeStderr, testBin } from "../helpers/test-bin.js"; +import portsMap from "../ports-map.js"; + +const __dirname = path.dirname(fileURLToPath(import.meta.url)); +const port = portsMap["cli-basic"]; const isMacOS = process.platform === "darwin"; diff --git a/test/cli/bonjour-option.test.js b/test/cli/bonjour-option.test.js index 973301c60e..3e021d7e6c 100644 --- a/test/cli/bonjour-option.test.js +++ b/test/cli/bonjour-option.test.js @@ -1,11 +1,11 @@ -"use strict"; - -const fs = require("node:fs"); -const { beforeEach, describe, it } = require("node:test"); -const { expect } = require("expect"); -const Server = require("../../lib/Server"); -const { normalizeStderr, testBin } = require("../helpers/test-bin"); -const port = require("../ports-map")["cli-bonjour"]; +import fs from "node:fs"; +import { beforeEach, describe, it } from "node:test"; +import { expect } from "expect"; +import Server from "../../lib/Server.js"; +import { normalizeStderr, testBin } from "../helpers/test-bin.js"; +import portsMap from "../ports-map.js"; + +const port = portsMap["cli-bonjour"]; const defaultCertificateDir = Server.findCacheDir(); diff --git a/test/cli/client-option.test.js b/test/cli/client-option.test.js index 61ede3cb01..2fad5a0c65 100644 --- a/test/cli/client-option.test.js +++ b/test/cli/client-option.test.js @@ -1,9 +1,9 @@ -"use strict"; +import { describe, it } from "node:test"; +import { expect } from "expect"; +import { testBin } from "../helpers/test-bin.js"; +import portsMap from "../ports-map.js"; -const { describe, it } = require("node:test"); -const { expect } = require("expect"); -const { testBin } = require("../helpers/test-bin"); -const port = require("../ports-map")["cli-client"]; +const port = portsMap["cli-client"]; describe('"client" CLI option', () => { it('should work using "--client-web-socket-transport ws"', async () => { diff --git a/test/cli/colors.test.js b/test/cli/colors.test.js index 8ed4ab9db1..625dbb558e 100644 --- a/test/cli/colors.test.js +++ b/test/cli/colors.test.js @@ -1,18 +1,19 @@ -"use strict"; +import { describe, it } from "node:test"; +import { fileURLToPath } from "node:url"; +import { expect } from "expect"; +import { normalizeStderr, testBin } from "../helpers/test-bin.js"; +import portsMap from "../ports-map.js"; -const { describe, it } = require("node:test"); -const { expect } = require("expect"); -const { normalizeStderr, testBin } = require("../helpers/test-bin"); -const port = require("../ports-map")["cli-colors"]; +const port = portsMap["cli-colors"]; -const colorsDefaultStats = require.resolve( - "../fixtures/cli-colors-default-stats/webpack.config", +const colorsDefaultStats = fileURLToPath( + import.meta.resolve("../fixtures/cli-colors-default-stats/webpack.config.js"), ); -const colorsDisabled = require.resolve( - "../fixtures/cli-colors-disabled/webpack.config", +const colorsDisabled = fileURLToPath( + import.meta.resolve("../fixtures/cli-colors-disabled/webpack.config.js"), ); -const colorsEnabled = require.resolve( - "../fixtures/cli-colors-enabled/webpack.config", +const colorsEnabled = fileURLToPath( + import.meta.resolve("../fixtures/cli-colors-enabled/webpack.config.js"), ); describe("colors", () => { diff --git a/test/cli/compress-option.test.js b/test/cli/compress-option.test.js index b6a83baabb..a34b5d2890 100644 --- a/test/cli/compress-option.test.js +++ b/test/cli/compress-option.test.js @@ -1,9 +1,9 @@ -"use strict"; +import { describe, it } from "node:test"; +import { expect } from "expect"; +import { testBin } from "../helpers/test-bin.js"; +import portsMap from "../ports-map.js"; -const { describe, it } = require("node:test"); -const { expect } = require("expect"); -const { testBin } = require("../helpers/test-bin"); -const port = require("../ports-map")["cli-compress"]; +const port = portsMap["cli-compress"]; describe('"compress" CLI option', () => { it('should work using "--compress"', async () => { diff --git a/test/cli/historyApiFallback-option.test.js b/test/cli/historyApiFallback-option.test.js index ab2f344667..75000dc6aa 100644 --- a/test/cli/historyApiFallback-option.test.js +++ b/test/cli/historyApiFallback-option.test.js @@ -1,9 +1,9 @@ -"use strict"; +import { describe, it } from "node:test"; +import { expect } from "expect"; +import { normalizeStderr, testBin } from "../helpers/test-bin.js"; +import portsMap from "../ports-map.js"; -const { describe, it } = require("node:test"); -const { expect } = require("expect"); -const { normalizeStderr, testBin } = require("../helpers/test-bin"); -const port = require("../ports-map")["cli-history-api-fallback"]; +const port = portsMap["cli-history-api-fallback"]; describe('"historyApiFallback" CLI option', () => { it('should work using "--history-api-fallback"', async (t) => { diff --git a/test/cli/host-option.test.js b/test/cli/host-option.test.js index 2d6d83932d..ed95571e5b 100644 --- a/test/cli/host-option.test.js +++ b/test/cli/host-option.test.js @@ -1,12 +1,12 @@ -"use strict"; - -const os = require("node:os"); -const { describe, it } = require("node:test"); -const { expect } = require("expect"); -const { spyOn } = require("jest-mock"); -const Server = require("../../lib/Server"); -const { normalizeStderr, testBin } = require("../helpers/test-bin"); -const port = require("../ports-map")["cli-host"]; +import os from "node:os"; +import { describe, it } from "node:test"; +import { expect } from "expect"; +import { spyOn } from "jest-mock"; +import Server from "../../lib/Server.js"; +import { normalizeStderr, testBin } from "../helpers/test-bin.js"; +import portsMap from "../ports-map.js"; + +const port = portsMap["cli-host"]; const localIPv4 = Server.findIp("v4", false); const localIPv6 = Server.findIp("v6", false); diff --git a/test/cli/hot-option.test.js b/test/cli/hot-option.test.js index 6e62e3a2ff..818f4105c3 100644 --- a/test/cli/hot-option.test.js +++ b/test/cli/hot-option.test.js @@ -1,9 +1,9 @@ -"use strict"; +import { describe, it } from "node:test"; +import { expect } from "expect"; +import { testBin } from "../helpers/test-bin.js"; +import portsMap from "../ports-map.js"; -const { describe, it } = require("node:test"); -const { expect } = require("expect"); -const { testBin } = require("../helpers/test-bin"); -const port = require("../ports-map")["cli-hot"]; +const port = portsMap["cli-hot"]; describe('"hot" CLI option', () => { it('should work using "--hot"', async () => { diff --git a/test/cli/ipc-option.test.js b/test/cli/ipc-option.test.js index 8d4dbe40b8..e6a42d17c8 100644 --- a/test/cli/ipc-option.test.js +++ b/test/cli/ipc-option.test.js @@ -1,10 +1,8 @@ -"use strict"; - -const os = require("node:os"); -const path = require("node:path"); -const { describe, it } = require("node:test"); -const { expect } = require("expect"); -const { normalizeStderr, testBin } = require("../helpers/test-bin"); +import os from "node:os"; +import path from "node:path"; +import { describe, it } from "node:test"; +import { expect } from "expect"; +import { normalizeStderr, testBin } from "../helpers/test-bin.js"; describe('"ipc" CLI option', () => { it('should work using "--ipc"', async (t) => { diff --git a/test/cli/liveReload-option.test.js b/test/cli/liveReload-option.test.js index 1725910ab5..46bcdb24bf 100644 --- a/test/cli/liveReload-option.test.js +++ b/test/cli/liveReload-option.test.js @@ -1,9 +1,9 @@ -"use strict"; +import { describe, it } from "node:test"; +import { expect } from "expect"; +import { testBin } from "../helpers/test-bin.js"; +import portsMap from "../ports-map.js"; -const { describe, it } = require("node:test"); -const { expect } = require("expect"); -const { testBin } = require("../helpers/test-bin"); -const port = require("../ports-map")["cli-live-reload"]; +const port = portsMap["cli-live-reload"]; describe('"liveReload" CLI option', () => { it('should work using "--live-reload"', async () => { diff --git a/test/cli/open-option.test.js b/test/cli/open-option.test.js index c017a2f3f5..8c5f39bbca 100644 --- a/test/cli/open-option.test.js +++ b/test/cli/open-option.test.js @@ -1,9 +1,9 @@ -"use strict"; +import { describe, it } from "node:test"; +import { expect } from "expect"; +import { testBin } from "../helpers/test-bin.js"; +import portsMap from "../ports-map.js"; -const { describe, it } = require("node:test"); -const { expect } = require("expect"); -const { testBin } = require("../helpers/test-bin"); -const port = require("../ports-map")["cli-open"]; +const port = portsMap["cli-open"]; describe('"open" CLI option', () => { it('should work using "--open"', async () => { diff --git a/test/cli/port-option.test.js b/test/cli/port-option.test.js index 05361d83ca..861b63b568 100644 --- a/test/cli/port-option.test.js +++ b/test/cli/port-option.test.js @@ -1,9 +1,9 @@ -"use strict"; +import { describe, it } from "node:test"; +import { expect } from "expect"; +import { normalizeStderr, testBin } from "../helpers/test-bin.js"; +import portsMap from "../ports-map.js"; -const { describe, it } = require("node:test"); -const { expect } = require("expect"); -const { normalizeStderr, testBin } = require("../helpers/test-bin"); -const port = require("../ports-map")["cli-port-option"]; +const port = portsMap["cli-port-option"]; describe('"port" CLI option', () => { it('should work using "--port "', async (t) => { diff --git a/test/cli/server-option.test.js b/test/cli/server-option.test.js index 5d36a5726e..11b8fee83f 100644 --- a/test/cli/server-option.test.js +++ b/test/cli/server-option.test.js @@ -1,12 +1,14 @@ -"use strict"; - -const path = require("node:path"); -const { beforeEach, describe, it } = require("node:test"); -const { expect } = require("expect"); -const { rimraf } = require("rimraf"); -const Server = require("../../lib/Server"); -const { normalizeStderr, testBin } = require("../helpers/test-bin"); -const port = require("../ports-map")["cli-server"]; +import path from "node:path"; +import { fileURLToPath } from "node:url"; +import { beforeEach, describe, it } from "node:test"; +import { expect } from "expect"; +import { rimraf } from "rimraf"; +import Server from "../../lib/Server.js"; +import { normalizeStderr, testBin } from "../helpers/test-bin.js"; +import portsMap from "../ports-map.js"; + +const __dirname = path.dirname(fileURLToPath(import.meta.url)); +const port = portsMap["cli-server"]; const httpsCertificateDirectory = path.resolve( __dirname, diff --git a/test/cli/static-option.test.js b/test/cli/static-option.test.js index e968c48c44..5a0152f8ad 100644 --- a/test/cli/static-option.test.js +++ b/test/cli/static-option.test.js @@ -1,9 +1,9 @@ -"use strict"; +import { describe, it } from "node:test"; +import { expect } from "expect"; +import { normalizeStderr, testBin } from "../helpers/test-bin.js"; +import portsMap from "../ports-map.js"; -const { describe, it } = require("node:test"); -const { expect } = require("expect"); -const { normalizeStderr, testBin } = require("../helpers/test-bin"); -const port = require("../ports-map")["cli-static"]; +const port = portsMap["cli-static"]; describe('"static" CLI option', () => { it('should work using "--static"', async (t) => { diff --git a/test/cli/watchFiles-option.test.js b/test/cli/watchFiles-option.test.js index f95752b11b..63de599754 100644 --- a/test/cli/watchFiles-option.test.js +++ b/test/cli/watchFiles-option.test.js @@ -1,10 +1,12 @@ -"use strict"; - -const path = require("node:path"); -const { describe, it } = require("node:test"); -const { expect } = require("expect"); -const { normalizeStderr, testBin } = require("../helpers/test-bin"); -const port = require("../ports-map")["cli-watch-files"]; +import path from "node:path"; +import { fileURLToPath } from "node:url"; +import { describe, it } from "node:test"; +import { expect } from "expect"; +import { normalizeStderr, testBin } from "../helpers/test-bin.js"; +import portsMap from "../ports-map.js"; + +const __dirname = path.dirname(fileURLToPath(import.meta.url)); +const port = portsMap["cli-watch-files"]; describe('"watchFiles" CLI option', () => { it('should work using "--watch-files "', async (t) => { diff --git a/test/cli/webSocketServer-option.test.js b/test/cli/webSocketServer-option.test.js index 1e614a6cdb..1d968c72a3 100644 --- a/test/cli/webSocketServer-option.test.js +++ b/test/cli/webSocketServer-option.test.js @@ -1,9 +1,9 @@ -"use strict"; +import { describe, it } from "node:test"; +import { expect } from "expect"; +import { testBin } from "../helpers/test-bin.js"; +import portsMap from "../ports-map.js"; -const { describe, it } = require("node:test"); -const { expect } = require("expect"); -const { testBin } = require("../helpers/test-bin"); -const port = require("../ports-map")["cli-web-socket-server"]; +const port = portsMap["cli-web-socket-server"]; describe('"webSocketServer" CLI option', () => { it('should work using "--web-socket-server-type ws"', async () => { diff --git a/test/client/ReactErrorBoundary.test.js b/test/client/ReactErrorBoundary.test.js index 37080a73e9..bcbd8552bf 100644 --- a/test/client/ReactErrorBoundary.test.js +++ b/test/client/ReactErrorBoundary.test.js @@ -1,11 +1,9 @@ -"use strict"; +import "../helpers/jsdom-setup.js"; -require("../helpers/jsdom-setup"); - -const { afterEach, beforeEach, describe, it, mock } = require("node:test"); -const { expect } = require("expect"); -const { spyOn } = require("jest-mock"); -const { createOverlay } = require("../../client-src/overlay"); +import { afterEach, beforeEach, describe, it, mock } from "node:test"; +import { expect } from "expect"; +import { spyOn } from "jest-mock"; +import { createOverlay } from "../../client-src/overlay.js"; describe("createOverlay", () => { beforeEach(() => { diff --git a/test/client/bundle.test.js b/test/client/bundle.test.js index 0df082287a..897d404d66 100644 --- a/test/client/bundle.test.js +++ b/test/client/bundle.test.js @@ -1,13 +1,13 @@ -"use strict"; +import { after, before, describe, it } from "node:test"; +import * as acorn from "acorn"; +import { expect } from "expect"; +import request from "supertest"; +import webpack from "webpack"; +import Server from "../../lib/Server.js"; +import config from "../fixtures/simple-config/webpack.config.js"; +import portsMap from "../ports-map.js"; -const { after, before, describe, it } = require("node:test"); -const acorn = require("acorn"); -const { expect } = require("expect"); -const request = require("supertest"); -const webpack = require("webpack"); -const Server = require("../../lib/Server"); -const config = require("../fixtures/simple-config/webpack.config"); -const port = require("../ports-map").bundle; +const port = portsMap.bundle; describe("bundle", () => { describe("main.js bundled output", () => { diff --git a/test/client/clients/WebsocketClient.test.js b/test/client/clients/WebsocketClient.test.js index 89bef19143..b1cbaa8f48 100644 --- a/test/client/clients/WebsocketClient.test.js +++ b/test/client/clients/WebsocketClient.test.js @@ -1,24 +1,23 @@ -"use strict"; - -require("../../helpers/jsdom-setup"); - -const http = require("node:http"); -const { after, before, describe, it } = require("node:test"); -const { expect } = require("expect"); -const express = require("express"); -const { spyOn } = require("jest-mock"); -const ws = require("ws"); +import "../../helpers/jsdom-setup.js"; + +import http from "node:http"; +import { after, before, describe, it } from "node:test"; +import { expect } from "expect"; +import express from "express"; +import { spyOn } from "jest-mock"; +import ws from "ws"; +import WebSocketClient from "../../../client-src/clients/WebSocketClient.js"; +import { log } from "../../../client-src/utils/log.js"; +import portsMap from "../../ports-map.js"; // jsdom's built-in WebSocket stays in CONNECTING for unreachable URLs (good // for silencing other client tests) but doesn't fully drive open/close // against a real local server. Use Node's `ws` library here so this test -// can talk to the express+ws server below. +// can talk to the express+ws server below. WebSocketClient only reads the +// global at construction time, so assigning after import is safe. globalThis.WebSocket = ws; -const WebSocketClient = - require("../../../client-src/clients/WebSocketClient").default; -const { log } = require("../../../client-src/utils/log"); -const port = require("../../ports-map")["web-socket-client"]; +const port = portsMap["web-socket-client"]; describe("WebsocketClient", () => { let socketServer; diff --git a/test/client/index.test.js b/test/client/index.test.js index 14bacbb46f..f659350500 100644 --- a/test/client/index.test.js +++ b/test/client/index.test.js @@ -1,21 +1,8 @@ -"use strict"; - -require("../helpers/jsdom-setup"); - -const { afterEach, beforeEach, describe, it, mock } = require("node:test"); -const { expect } = require("expect"); -const { fn } = require("jest-mock"); - -/** - * Clear all client-src/* entries from require.cache so a fresh require() - * re-evaluates client-src/index.js with the active mock.module() mocks. - * @returns {void} - */ -function clearClientCache() { - for (const key of Object.keys(require.cache)) { - if (key.includes("/client-src/")) delete require.cache[key]; - } -} +import "../helpers/jsdom-setup.js"; + +import { afterEach, beforeEach, describe, it, mock } from "node:test"; +import { expect } from "expect"; +import { fn } from "jest-mock"; describe("index", () => { let log; @@ -83,7 +70,6 @@ describe("index", () => { globalThis.__resourceQuery = "?mock-url"; globalThis.__webpack_hash__ = "mock-hash"; - clearClientCache(); installMocks(); // issue: https://github.com/jsdom/jsdom/issues/2112 @@ -91,10 +77,9 @@ describe("index", () => { globalThis.location = { ...locationValue, reload: fn() }; // Use dynamic import with a cache-busting query string to force a fresh - // module evaluation each test (ESM modules aren't invalidated by deleting - // entries from require.cache). - const indexUrl = require.resolve("../../client-src"); - await import(`file://${indexUrl}?t=${Date.now()}-${Math.random()}`); + // module evaluation each test. + const indexUrl = import.meta.resolve("../../client-src/index.js"); + await import(`${indexUrl}?t=${Date.now()}-${Math.random()}`); [[, onSocketMessage]] = socket.mock.calls; }); @@ -102,7 +87,6 @@ describe("index", () => { globalThis.__resourceQuery = resourceQueryValue; Object.assign(globalThis, locationValue); restoreMocks(); - clearClientCache(); }); it("should set arguments into socket function", (t) => { @@ -213,8 +197,8 @@ describe("index", () => { async function reloadClient() { overlay.send.mockReset(); socket.mockReset(); - const indexUrl = require.resolve("../../client-src"); - await import(`file://${indexUrl}?t=${Date.now()}-${Math.random()}`); + const indexUrl = import.meta.resolve("../../client-src/index.js"); + await import(`${indexUrl}?t=${Date.now()}-${Math.random()}`); [[, onSocketMessage]] = socket.mock.calls; } diff --git a/test/client/socket-helper.test.js b/test/client/socket-helper.test.js index 2ee40e1c7c..e7b496b859 100644 --- a/test/client/socket-helper.test.js +++ b/test/client/socket-helper.test.js @@ -1,10 +1,8 @@ -"use strict"; +import "../helpers/jsdom-setup.js"; -require("../helpers/jsdom-setup"); - -const { beforeEach, describe, it, mock } = require("node:test"); -const { expect } = require("expect"); -const { fn } = require("jest-mock"); +import { beforeEach, describe, it, mock } from "node:test"; +import { expect } from "expect"; +import { fn } from "jest-mock"; /** * Build a fresh mock WebSocketClient class. Each `new MockClient(url)` @@ -29,9 +27,6 @@ function createMockClient() { describe("socket", () => { beforeEach(() => { delete globalThis.__webpack_dev_server_client__; - for (const key of Object.keys(require.cache)) { - if (key.includes("/client-src/")) delete require.cache[key]; - } }); it("should default to WebsocketClient when no __webpack_dev_server_client__ set", async (t) => { @@ -74,11 +69,13 @@ describe("socket", () => { } }); - it("should use __webpack_dev_server_client__ when set", (t) => { + it("should use __webpack_dev_server_client__ when set", async (t) => { const MockClient = createMockClient(); globalThis.__webpack_dev_server_client__ = MockClient; - const socket = require("../../client-src/socket").default; + const socket = ( + await import(`../../client-src/socket.js?t=${Date.now()}-${Math.random()}`) + ).default; const mockHandler = fn(); @@ -104,15 +101,18 @@ describe("socket", () => { t.assert.snapshot(mockHandler.mock.calls); }); - it("should export initialized client", () => { + it("should export initialized client", async () => { const MockClient = createMockClient(); globalThis.__webpack_dev_server_client__ = MockClient; - const socket = require("../../client-src/socket").default; + const socketMod = await import( + `../../client-src/socket.js?t=${Date.now()}-${Math.random()}` + ); + const socket = socketMod.default; socket("my.url", {}); - const initializedInstance = require("../../client-src/socket").client; + const initializedInstance = socketMod.client; expect(initializedInstance).not.toBeNull(); expect(typeof initializedInstance.onClose).toBe("function"); diff --git a/test/client/utils/createSocketURL.test.js b/test/client/utils/createSocketURL.test.js index 00c766173d..71a9c84b7b 100644 --- a/test/client/utils/createSocketURL.test.js +++ b/test/client/utils/createSocketURL.test.js @@ -1,9 +1,7 @@ -"use strict"; +import { describe, it } from "node:test"; +import { expect } from "expect"; -const { describe, it } = require("node:test"); -const { expect } = require("expect"); - -require("../../helpers/jsdom-setup"); +import "../../helpers/jsdom-setup.js"; describe("'createSocketURL' function", () => { globalThis.__webpack_hash__ = "hash"; @@ -106,7 +104,7 @@ describe("'createSocketURL' function", () => { ]; for (const [__resourceQuery, location, expected] of samples) { - it(`should return '${expected}' socket URL when '__resourceQuery' is '${__resourceQuery}' and 'self.location' is '${location}'`, () => { + it(`should return '${expected}' socket URL when '__resourceQuery' is '${__resourceQuery}' and 'self.location' is '${location}'`, async () => { globalThis.__resourceQuery = __resourceQuery; if (__resourceQuery === null) { @@ -116,7 +114,12 @@ describe("'createSocketURL' function", () => { }); } - const client = require("../../../client-src/index"); + // Force a fresh evaluation each iteration so top-level state in + // client-src doesn't bleed between cases. + const indexUrl = import.meta.resolve("../../../client-src/index.js"); + const client = await import( + `${indexUrl}?t=${Date.now()}-${Math.random()}` + ); const { createSocketURL } = client; const { parseURL } = client; @@ -138,10 +141,5 @@ describe("'createSocketURL' function", () => { expect(createSocketURL(parsedURL)).toBe(expected); }); - - // Reset between cases so top-level state in client-src doesn't bleed. - for (const key of Object.keys(require.cache)) { - if (key.includes("/client-src/")) delete require.cache[key]; - } } }); diff --git a/test/client/utils/getCurrentScriptSource.test.js b/test/client/utils/getCurrentScriptSource.test.js index bd1f94420b..058c5a60c8 100644 --- a/test/client/utils/getCurrentScriptSource.test.js +++ b/test/client/utils/getCurrentScriptSource.test.js @@ -1,19 +1,19 @@ -"use strict"; +import { afterEach, beforeEach, describe, it } from "node:test"; +import { expect } from "expect"; -const { afterEach, beforeEach, describe, it } = require("node:test"); -const { expect } = require("expect"); - -require("../../helpers/jsdom-setup"); +import "../../helpers/jsdom-setup.js"; describe("'getCurrentScriptSource' function", () => { let getCurrentScriptSource; - beforeEach(() => { + beforeEach(async () => { globalThis.__webpack_hash__ = "mock-hash"; globalThis.__resourceQuery = "?protocol=ws&hostname=0.0.0.0"; - getCurrentScriptSource = - require("../../../client-src/index").getCurrentScriptSource; + const indexUrl = import.meta.resolve("../../../client-src/index.js"); + ({ getCurrentScriptSource } = await import( + `${indexUrl}?t=${Date.now()}-${Math.random()}` + )); }); afterEach(() => { diff --git a/test/client/utils/log.test.js b/test/client/utils/log.test.js index 451ef88a65..aa7337698e 100644 --- a/test/client/utils/log.test.js +++ b/test/client/utils/log.test.js @@ -1,10 +1,8 @@ -"use strict"; +import "../../helpers/jsdom-setup.js"; -require("../../helpers/jsdom-setup"); - -const { afterEach, beforeEach, describe, it, mock } = require("node:test"); -const { expect } = require("expect"); -const { fn } = require("jest-mock"); +import { afterEach, beforeEach, describe, it, mock } from "node:test"; +import { expect } from "expect"; +import { fn } from "jest-mock"; describe("'log' function", () => { let logger; @@ -17,20 +15,14 @@ describe("'log' function", () => { }; // Mock the intermediate module that log.js imports directly. Mocking the // deeper webpack runtime through the re-export chain doesn't propagate; - // mocking the file log.js actually requires does. + // mocking the file log.js actually imports does. loggerMockCtx = mock.module("../../../client-src/modules/logger/index.js", { defaultExport: logger, }); - for (const key of Object.keys(require.cache)) { - if (key.includes("/client-src/")) delete require.cache[key]; - } }); afterEach(() => { loggerMockCtx.restore(); - for (const key of Object.keys(require.cache)) { - if (key.includes("/client-src/")) delete require.cache[key]; - } }); /** @@ -38,8 +30,8 @@ describe("'log' function", () => { * @returns {Promise} the freshly evaluated log module */ function freshLogModule() { - const url = require.resolve("../../../client-src/utils/log"); - return import(`file://${url}?t=${Date.now()}-${Math.random()}`); + const url = import.meta.resolve("../../../client-src/utils/log.js"); + return import(`${url}?t=${Date.now()}-${Math.random()}`); } it("should set info as the default level and create logger", async () => { diff --git a/test/client/utils/sendMessage.test.js b/test/client/utils/sendMessage.test.js index 8b3d59b337..69ed0179fa 100644 --- a/test/client/utils/sendMessage.test.js +++ b/test/client/utils/sendMessage.test.js @@ -1,11 +1,9 @@ -"use strict"; +import "../../helpers/jsdom-setup.js"; -require("../../helpers/jsdom-setup"); - -const { describe, it } = require("node:test"); -const { expect } = require("expect"); -const { spyOn } = require("jest-mock"); -const sendMessage = require("../../../client-src/utils/sendMessage").default; +import { describe, it } from "node:test"; +import { expect } from "expect"; +import { spyOn } from "jest-mock"; +import sendMessage from "../../../client-src/utils/sendMessage.js"; describe("'sendMessage' function", () => { it("should run self.postMessage", (t) => { diff --git a/test/e2e/allowed-hosts.test.js b/test/e2e/allowed-hosts.test.js index 47f403eaf4..e3831264f6 100644 --- a/test/e2e/allowed-hosts.test.js +++ b/test/e2e/allowed-hosts.test.js @@ -1,14 +1,14 @@ -"use strict"; +import { afterEach, beforeEach, describe, it } from "node:test"; -const { afterEach, beforeEach, describe, it } = require("node:test"); +import express from "express"; +import { createProxyMiddleware } from "http-proxy-middleware"; +import webpack from "webpack"; +import Server from "../../lib/Server.js"; +import config from "../fixtures/client-config/webpack.config.js"; +import runBrowser from "../helpers/run-browser.js"; +import portsMap from "../ports-map.js"; -const express = require("express"); -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"); -const [port1, port2] = require("../ports-map")["allowed-hosts"]; +const [port1, port2] = portsMap["allowed-hosts"]; const webSocketServers = ["ws"]; diff --git a/test/e2e/api.test.js b/test/e2e/api.test.js index f32094d8d0..46bb459d1e 100644 --- a/test/e2e/api.test.js +++ b/test/e2e/api.test.js @@ -1,15 +1,15 @@ -"use strict"; - -const path = require("node:path"); -const { afterEach, beforeEach, describe, it, mock } = require("node:test"); -const { expect } = require("expect"); -const { fn } = require("jest-mock"); -const webpack = require("webpack"); -const Server = require("../../lib/Server"); -const config = require("../fixtures/client-config/webpack.config"); -const runBrowser = require("../helpers/run-browser"); -const sessionSubscribe = require("../helpers/session-subscribe"); -const port = require("../ports-map").api; +import path from "node:path"; +import { afterEach, beforeEach, describe, it, mock } from "node:test"; +import { expect } from "expect"; +import { fn } from "jest-mock"; +import webpack from "webpack"; +import Server from "../../lib/Server.js"; +import config from "../fixtures/client-config/webpack.config.js"; +import runBrowser from "../helpers/run-browser.js"; +import sessionSubscribe from "../helpers/session-subscribe.js"; +import portsMap from "../ports-map.js"; + +const port = portsMap.api; describe("API", () => { describe("WEBPACK_SERVE environment variable", () => { @@ -24,7 +24,6 @@ describe("API", () => { process.env = { ...OLD_ENV }; delete process.env.WEBPACK_SERVE; - delete require.cache[require.resolve("../../lib/Server")]; ({ page, browser } = await runBrowser()); @@ -49,7 +48,10 @@ describe("API", () => { pageErrors.push(error); }); - const WebpackDevServer = require("../../lib/Server"); + const serverUrl = import.meta.resolve("../../lib/Server.js"); + const { default: WebpackDevServer } = await import( + `${serverUrl}?t=${Date.now()}-${Math.random()}` + ); const compiler = webpack(config); server = new WebpackDevServer({ port }, compiler); diff --git a/test/e2e/app.test.js b/test/e2e/app.test.js index 19d9b09b8f..964c56b597 100644 --- a/test/e2e/app.test.js +++ b/test/e2e/app.test.js @@ -1,15 +1,24 @@ -"use strict"; - -const fs = require("node:fs"); -const path = require("node:path"); -const { afterEach, beforeEach, describe, it } = require("node:test"); -const { expect } = require("expect"); -const webpack = require("webpack"); -const wdm = require("webpack-dev-middleware"); -const Server = require("../../lib/Server"); -const config = require("../fixtures/client-config/webpack.config"); -const runBrowser = require("../helpers/run-browser"); -const port = require("../ports-map").app; +import fs from "node:fs"; +import { createSecureServer } from "node:http2"; +import { createServer as createHttpsServer } from "node:https"; +import path from "node:path"; +import { afterEach, beforeEach, describe, it } from "node:test"; +import { fileURLToPath } from "node:url"; +import { createAdaptorServer } from "@hono/node-server"; +import connect from "connect"; +import { expect } from "expect"; +import express from "express"; +import { Hono } from "hono"; +import webpack from "webpack"; +import wdm from "webpack-dev-middleware"; +import Server from "../../lib/Server.js"; +import config from "../fixtures/client-config/webpack.config.js"; +import runBrowser from "../helpers/run-browser.js"; +import portsMap from "../ports-map.js"; + +const __dirname = path.dirname(fileURLToPath(import.meta.url)); + +const port = portsMap.app; const staticDirectory = path.resolve( __dirname, @@ -17,17 +26,17 @@ const staticDirectory = path.resolve( ); const apps = [ - ["express", () => require("express")(), "http"], - ["express", () => require("express")(), "https"], - ["connect", () => require("connect")(), "http"], - ["connect", () => require("connect")(), "https"], - ["connect", () => require("connect")(), "http2"], - ["connect (async)", () => require("connect")(), "http"], + ["express", () => express(), "http"], + ["express", () => express(), "https"], + ["connect", () => connect(), "http"], + ["connect", () => connect(), "https"], + ["connect", () => connect(), "http2"], + ["connect (async)", () => connect(), "http"], [ "hono", - () => new (require("hono").Hono)(), + () => new Hono(), (options, app) => - require("@hono/node-server").createAdaptorServer({ + createAdaptorServer({ fetch: app.fetch, }), (_, devServer) => [ @@ -39,11 +48,11 @@ const apps = [ ], [ "hono", - () => new (require("hono").Hono)(), + () => new Hono(), (_, app) => - require("@hono/node-server").createAdaptorServer({ + createAdaptorServer({ fetch: app.fetch, - createServer: require("node:https").createServer, + createServer: createHttpsServer, serverOptions: { key: fs.readFileSync( path.resolve(__dirname, "../fixtures/ssl/localhost-privkey.pem"), @@ -62,12 +71,12 @@ const apps = [ ], [ "hono", - () => new (require("hono").Hono)(), + () => new Hono(), { type: (options, app) => - require("@hono/node-server").createAdaptorServer({ + createAdaptorServer({ fetch: app.fetch, - createServer: require("node:http2").createSecureServer, + createServer: createSecureServer, serverOptions: options, }), options: { diff --git a/test/e2e/bonjour.test.js b/test/e2e/bonjour.test.js index 5b2711e23b..cf98a94e95 100644 --- a/test/e2e/bonjour.test.js +++ b/test/e2e/bonjour.test.js @@ -1,14 +1,14 @@ -"use strict"; - -const os = require("node:os"); -const { afterEach, beforeEach, describe, it, mock } = require("node:test"); -const { expect } = require("expect"); -const { fn } = require("jest-mock"); -const webpack = require("webpack"); -const Server = require("../../lib/Server"); -const config = require("../fixtures/simple-config/webpack.config"); -const runBrowser = require("../helpers/run-browser"); -const port = require("../ports-map").bonjour; +import os from "node:os"; +import { afterEach, beforeEach, describe, it, mock } from "node:test"; +import { expect } from "expect"; +import { fn } from "jest-mock"; +import webpack from "webpack"; +import Server from "../../lib/Server.js"; +import config from "../fixtures/simple-config/webpack.config.js"; +import runBrowser from "../helpers/run-browser.js"; +import portsMap from "../ports-map.js"; + +const port = portsMap.bonjour; describe("bonjour option", () => { let mockPublish; diff --git a/test/e2e/built-in-routes.test.js b/test/e2e/built-in-routes.test.js index 85f5825e97..9432839afb 100644 --- a/test/e2e/built-in-routes.test.js +++ b/test/e2e/built-in-routes.test.js @@ -1,13 +1,13 @@ -"use strict"; - -const { afterEach, beforeEach, describe, it } = require("node:test"); -const { expect } = require("expect"); -const webpack = require("webpack"); -const Server = require("../../lib/Server"); -const config = require("../fixtures/client-config/webpack.config"); -const multiConfig = require("../fixtures/multi-public-path-config/webpack.config"); -const runBrowser = require("../helpers/run-browser"); -const port = require("../ports-map").routes; +import { afterEach, beforeEach, describe, it } from "node:test"; +import { expect } from "expect"; +import webpack from "webpack"; +import Server from "../../lib/Server.js"; +import config from "../fixtures/client-config/webpack.config.js"; +import multiConfig from "../fixtures/multi-public-path-config/webpack.config.js"; +import runBrowser from "../helpers/run-browser.js"; +import portsMap from "../ports-map.js"; + +const port = portsMap.routes; describe("Built in routes", () => { describe("with simple config", () => { diff --git a/test/e2e/client-reconnect.test.js b/test/e2e/client-reconnect.test.js index e39a482df1..6aff8d1726 100644 --- a/test/e2e/client-reconnect.test.js +++ b/test/e2e/client-reconnect.test.js @@ -1,12 +1,12 @@ -"use strict"; +import { afterEach, beforeEach, describe, it } from "node:test"; -const { afterEach, beforeEach, describe, it } = require("node:test"); +import webpack from "webpack"; +import Server from "../../lib/Server.js"; +import config from "../fixtures/simple-config/webpack.config.js"; +import runBrowser from "../helpers/run-browser.js"; +import portsMap from "../ports-map.js"; -const webpack = require("webpack"); -const Server = require("../../lib/Server"); -const config = require("../fixtures/simple-config/webpack.config"); -const runBrowser = require("../helpers/run-browser"); -const port = require("../ports-map")["client-reconnect-option"]; +const port = portsMap["client-reconnect-option"]; describe("client.reconnect option", () => { describe("specified as true", () => { diff --git a/test/e2e/client.test.js b/test/e2e/client.test.js index eab2ce7051..9d6a64a9d9 100644 --- a/test/e2e/client.test.js +++ b/test/e2e/client.test.js @@ -1,13 +1,14 @@ -"use strict"; - -const { afterEach, beforeEach, describe, it } = require("node:test"); -const { expect } = require("expect"); -const webpack = require("webpack"); -const Server = require("../../lib/Server"); -const config = require("../fixtures/client-config/webpack.config"); -const runBrowser = require("../helpers/run-browser"); -const sessionSubscribe = require("../helpers/session-subscribe"); -const port = require("../ports-map")["client-option"]; +import { afterEach, beforeEach, describe, it } from "node:test"; +import { fileURLToPath } from "node:url"; +import { expect } from "expect"; +import webpack from "webpack"; +import Server from "../../lib/Server.js"; +import config from "../fixtures/client-config/webpack.config.js"; +import runBrowser from "../helpers/run-browser.js"; +import sessionSubscribe from "../helpers/session-subscribe.js"; +import portsMap from "../ports-map.js"; + +const port = portsMap["client-option"]; describe("client option", () => { describe("default behaviour", () => { @@ -246,14 +247,16 @@ describe("client option", () => { class OverrideServer extends Server { getClientEntry() { - return require.resolve( - "../fixtures/custom-client/CustomClientEntry.js", + return fileURLToPath( + import.meta.resolve("../fixtures/custom-client/CustomClientEntry.js"), ); } getClientHotEntry() { - return require.resolve( - "../fixtures/custom-client/CustomClientHotEntry.js", + return fileURLToPath( + import.meta.resolve( + "../fixtures/custom-client/CustomClientHotEntry.js", + ), ); } } @@ -304,8 +307,8 @@ describe("client option", () => { { title: 'as a path ("ws")', client: { - webSocketTransport: require.resolve( - "../../client-src/clients/WebSocketClient", + webSocketTransport: fileURLToPath( + import.meta.resolve("../../client-src/clients/WebSocketClient.js"), ), }, webSocketServer: "ws", diff --git a/test/e2e/compress.test.js b/test/e2e/compress.test.js index d938eb88db..70eb51d094 100644 --- a/test/e2e/compress.test.js +++ b/test/e2e/compress.test.js @@ -1,12 +1,12 @@ -"use strict"; +import { afterEach, beforeEach, describe, it } from "node:test"; -const { afterEach, beforeEach, describe, it } = require("node:test"); +import webpack from "webpack"; +import Server from "../../lib/Server.js"; +import config from "../fixtures/simple-config-other/webpack.config.js"; +import runBrowser from "../helpers/run-browser.js"; +import portsMap from "../ports-map.js"; -const webpack = require("webpack"); -const Server = require("../../lib/Server"); -const config = require("../fixtures/simple-config-other/webpack.config"); -const runBrowser = require("../helpers/run-browser"); -const port = require("../ports-map")["compress-option"]; +const port = portsMap["compress-option"]; describe("compress option", () => { describe("enabled by default when not specified", () => { diff --git a/test/e2e/cross-origin-request.test.js b/test/e2e/cross-origin-request.test.js index 76bb7ed71c..e1bef2e3a0 100644 --- a/test/e2e/cross-origin-request.test.js +++ b/test/e2e/cross-origin-request.test.js @@ -1,12 +1,12 @@ -"use strict"; +import { describe, it } from "node:test"; +import { expect } from "expect"; +import webpack from "webpack"; +import Server from "../../lib/Server.js"; +import config from "../fixtures/client-config/webpack.config.js"; +import runBrowser from "../helpers/run-browser.js"; +import portsMap from "../ports-map.js"; -const { describe, it } = require("node:test"); -const { expect } = require("expect"); -const webpack = require("webpack"); -const Server = require("../../lib/Server"); -const config = require("../fixtures/client-config/webpack.config"); -const runBrowser = require("../helpers/run-browser"); -const [port1, port2] = require("../ports-map")["cross-origin-request"]; +const [port1, port2] = portsMap["cross-origin-request"]; describe("cross-origin requests", () => { const devServerPort = port1; @@ -24,7 +24,7 @@ describe("cross-origin requests", () => { await server.start(); // Start a separate server for serving the HTML file - const http = require("node:http"); + import http from "node:http"; const htmlServer = http.createServer((req, res) => { res.writeHead(200, { "Content-Type": "text/html" }); @@ -78,7 +78,7 @@ describe("cross-origin requests", () => { await server.start(); // Start a separate server for serving the HTML file - const http = require("node:http"); + import http from "node:http"; const htmlServer = http.createServer((req, res) => { res.writeHead(200, { "Content-Type": "text/html" }); @@ -129,7 +129,7 @@ describe("cross-origin requests", () => { await server.start(); // Start a separate server for serving the HTML file - const http = require("node:http"); + import http from "node:http"; const htmlServer = http.createServer((req, res) => { res.writeHead(200, { "Content-Type": "text/html" }); @@ -180,7 +180,7 @@ describe("cross-origin requests", () => { await server.start(); // Start a separate server for serving the HTML file - const http = require("node:http"); + import http from "node:http"; const htmlServer = http.createServer((req, res) => { res.writeHead(200, { "Content-Type": "text/html" }); diff --git a/test/e2e/entry.test.js b/test/e2e/entry.test.js index b7d9fa673f..b1fa5eb26d 100644 --- a/test/e2e/entry.test.js +++ b/test/e2e/entry.test.js @@ -1,13 +1,13 @@ -"use strict"; +import path from "node:path"; +import { describe, it } from "node:test"; -const path = require("node:path"); -const { describe, it } = require("node:test"); +import webpack from "webpack"; +import Server from "../../lib/Server.js"; +import config from "../fixtures/client-config/webpack.config.js"; +import runBrowser from "../helpers/run-browser.js"; +import portsMap from "../ports-map.js"; -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").entry; +const port = portsMap.entry; const HOT_ENABLED_MESSAGE = "[webpack-dev-server] Server started: Hot Module Replacement enabled, Live Reloading enabled, Progress disabled, Overlay enabled."; diff --git a/test/e2e/headers.test.js b/test/e2e/headers.test.js index bbd195fa26..ccd29ba352 100644 --- a/test/e2e/headers.test.js +++ b/test/e2e/headers.test.js @@ -1,13 +1,13 @@ -"use strict"; - -const { afterEach, beforeEach, describe, it } = require("node:test"); -const { expect } = require("expect"); -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"); -const port = require("../ports-map")["headers-option"]; +import { afterEach, beforeEach, describe, it } from "node:test"; +import { expect } from "expect"; +import request from "supertest"; +import webpack from "webpack"; +import Server from "../../lib/Server.js"; +import config from "../fixtures/simple-config/webpack.config.js"; +import runBrowser from "../helpers/run-browser.js"; +import portsMap from "../ports-map.js"; + +const port = portsMap["headers-option"]; describe("headers option", () => { describe("as a string", () => { diff --git a/test/e2e/history-api-fallback.test.js b/test/e2e/history-api-fallback.test.js index 9c992e70dd..9dc10f49ab 100644 --- a/test/e2e/history-api-fallback.test.js +++ b/test/e2e/history-api-fallback.test.js @@ -1,16 +1,16 @@ -"use strict"; - -const path = require("node:path"); -const { afterEach, beforeEach, describe, it } = require("node:test"); -const { expect } = require("expect"); -const { spyOn } = require("jest-mock"); -const webpack = require("webpack"); -const Server = require("../../lib/Server"); -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"]; +import path from "node:path"; +import { afterEach, beforeEach, describe, it } from "node:test"; +import { expect } from "expect"; +import { spyOn } from "jest-mock"; +import webpack from "webpack"; +import Server from "../../lib/Server.js"; +import config2 from "../fixtures/historyapifallback-2-config/webpack.config.js"; +import config3 from "../fixtures/historyapifallback-3-config/webpack.config.js"; +import config from "../fixtures/historyapifallback-config/webpack.config.js"; +import runBrowser from "../helpers/run-browser.js"; +import portsMap from "../ports-map.js"; + +const port = portsMap["history-api-fallback-option"]; describe("historyApiFallback option", () => { describe("as boolean", () => { diff --git a/test/e2e/host.test.js b/test/e2e/host.test.js index d7a875a75e..2aca81935f 100644 --- a/test/e2e/host.test.js +++ b/test/e2e/host.test.js @@ -1,13 +1,13 @@ -"use strict"; - -const http = require("node:http"); -const { describe, it } = require("node:test"); -const { expect } = require("expect"); -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").host; +import http from "node:http"; +import { describe, it } from "node:test"; +import { expect } from "expect"; +import webpack from "webpack"; +import Server from "../../lib/Server.js"; +import config from "../fixtures/client-config/webpack.config.js"; +import runBrowser from "../helpers/run-browser.js"; +import portsMap from "../ports-map.js"; + +const port = portsMap.host; const ipv4 = Server.findIp("v4", false); const ipv6 = Server.findIp("v6", false); diff --git a/test/e2e/hot-and-live-reload.test.js b/test/e2e/hot-and-live-reload.test.js index 7b56ea840b..422a540286 100644 --- a/test/e2e/hot-and-live-reload.test.js +++ b/test/e2e/hot-and-live-reload.test.js @@ -1,19 +1,22 @@ -"use strict"; - -const path = require("node:path"); -const { afterEach, beforeEach, describe, it } = require("node:test"); -const { expect } = require("expect"); -const fs = require("graceful-fs"); -const { fn, spyOn } = require("jest-mock"); -const webpack = require("webpack"); -const WebSocket = require("ws"); -const Server = require("../../lib/Server"); -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"]; +import path from "node:path"; +import { afterEach, beforeEach, describe, it } from "node:test"; +import { fileURLToPath } from "node:url"; +import { expect } from "expect"; +import fs from "graceful-fs"; +import { fn, spyOn } from "jest-mock"; +import webpack from "webpack"; +import WebSocket from "ws"; +import Server from "../../lib/Server.js"; +import config from "../fixtures/client-config/webpack.config.js"; +import multiCompilerConfig from "../fixtures/multi-compiler-one-configuration/webpack.config.js"; +import reloadConfig from "../fixtures/reload-config/webpack.config.js"; +import HTMLGeneratorPlugin from "../helpers/html-generator-plugin.js"; +import runBrowser from "../helpers/run-browser.js"; +import portsMap from "../ports-map.js"; + +const __dirname = path.dirname(fileURLToPath(import.meta.url)); + +const port = portsMap["hot-and-live-reload"]; const cssFilePath = path.resolve( __dirname, @@ -162,8 +165,8 @@ describe("hot and live reload", () => { title: "should work with manual client setup", webpackOptions: { entry: [ - require.resolve("../../client-src/index.js"), - require.resolve("../fixtures/reload-config/foo.js"), + fileURLToPath(import.meta.resolve("../../client-src/index.js")), + fileURLToPath(import.meta.resolve("../fixtures/reload-config/foo.js")), ], }, options: { @@ -179,8 +182,8 @@ describe("hot and live reload", () => { webpackOptions: { entry: [ "webpack/hot/dev-server", - `${require.resolve("../../client-src/index.js")}?hot=true`, - require.resolve("../fixtures/reload-config/foo.js"), + `${fileURLToPath(import.meta.resolve("../../client-src/index.js"))}?hot=true`, + fileURLToPath(import.meta.resolve("../fixtures/reload-config/foo.js")), ], plugins: [ new webpack.HotModuleReplacementPlugin(), @@ -198,8 +201,8 @@ describe("hot and live reload", () => { "should work with manual client setup and allow to disable hot module replacement", webpackOptions: { entry: [ - `${require.resolve("../../client-src/index.js")}?hot=false`, - require.resolve("../fixtures/reload-config/foo.js"), + `${fileURLToPath(import.meta.resolve("../../client-src/index.js"))}?hot=false`, + fileURLToPath(import.meta.resolve("../fixtures/reload-config/foo.js")), ], }, options: { @@ -213,8 +216,8 @@ describe("hot and live reload", () => { "should work with manual client setup and allow to enable live reload", webpackOptions: { entry: [ - `${require.resolve("../../client-src/index.js")}?live-reload=true`, - require.resolve("../fixtures/reload-config/foo.js"), + `${fileURLToPath(import.meta.resolve("../../client-src/index.js"))}?live-reload=true`, + fileURLToPath(import.meta.resolve("../fixtures/reload-config/foo.js")), ], }, options: { @@ -228,8 +231,8 @@ describe("hot and live reload", () => { "should work with manual client setup and allow to disable live reload", webpackOptions: { entry: [ - `${require.resolve("../../client-src/index.js")}?live-reload=false`, - require.resolve("../fixtures/reload-config/foo.js"), + `${fileURLToPath(import.meta.resolve("../../client-src/index.js"))}?live-reload=false`, + fileURLToPath(import.meta.resolve("../fixtures/reload-config/foo.js")), ], }, options: { diff --git a/test/e2e/ipc.test.js b/test/e2e/ipc.test.js index cf82afa22a..553db82a84 100644 --- a/test/e2e/ipc.test.js +++ b/test/e2e/ipc.test.js @@ -1,18 +1,18 @@ -"use strict"; - -const http = require("node:http"); -const net = require("node:net"); -const os = require("node:os"); -const path = require("node:path"); -const { describe, it } = require("node:test"); -const { expect } = require("expect"); -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"); -const sessionSubscribe = require("../helpers/session-subscribe"); -const port1 = require("../ports-map").ipc; +import http from "node:http"; +import net from "node:net"; +import os from "node:os"; +import path from "node:path"; +import { describe, it } from "node:test"; +import { expect } from "expect"; +import httpProxy from "http-proxy"; +import webpack from "webpack"; +import Server from "../../lib/Server.js"; +import config from "../fixtures/client-config/webpack.config.js"; +import runBrowser from "../helpers/run-browser.js"; +import sessionSubscribe from "../helpers/session-subscribe.js"; +import portsMap from "../ports-map.js"; + +const port1 = portsMap.ipc; const webSocketServers = ["ws"]; diff --git a/test/e2e/lazy-compilation.test.js b/test/e2e/lazy-compilation.test.js index c0a4c89b63..161850eb87 100644 --- a/test/e2e/lazy-compilation.test.js +++ b/test/e2e/lazy-compilation.test.js @@ -1,13 +1,13 @@ -"use strict"; +import { describe, it } from "node:test"; -const { describe, it } = require("node:test"); +import webpack from "webpack"; +import Server from "../../lib/Server.js"; +import lazyCompilationMultipleEntriesConfig from "../fixtures/lazy-compilation-multiple-entries/webpack.config.js"; +import lazyCompilationSingleEntryConfig from "../fixtures/lazy-compilation-single-entry/webpack.config.js"; +import runBrowser from "../helpers/run-browser.js"; +import portsMap from "../ports-map.js"; -const webpack = require("webpack"); -const Server = require("../../lib/Server"); -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"]; +const port = portsMap["lazy-compilation"]; describe("lazy compilation", () => { // TODO freezes because webpack doesn't close `eventsource`, uncomment once fixed upstream diff --git a/test/e2e/logging.test.js b/test/e2e/logging.test.js index c97ee8395a..8555a8d468 100644 --- a/test/e2e/logging.test.js +++ b/test/e2e/logging.test.js @@ -1,15 +1,15 @@ -"use strict"; +import path from "node:path"; +import { describe, it } from "node:test"; -const path = require("node:path"); -const { describe, it } = require("node:test"); +import fs from "graceful-fs"; +import webpack from "webpack"; +import Server from "../../lib/Server.js"; +import config from "../fixtures/client-config/webpack.config.js"; +import HTMLGeneratorPlugin from "../helpers/html-generator-plugin.js"; +import runBrowser from "../helpers/run-browser.js"; +import portsMap from "../ports-map.js"; -const fs = require("graceful-fs"); -const webpack = require("webpack"); -const Server = require("../../lib/Server"); -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; +const port = portsMap.logging; describe("logging", () => { const webSocketServers = [{ webSocketServer: "ws" }]; diff --git a/test/e2e/mime-types.test.js b/test/e2e/mime-types.test.js index 5dfe513fbc..4509f3e10f 100644 --- a/test/e2e/mime-types.test.js +++ b/test/e2e/mime-types.test.js @@ -1,12 +1,12 @@ -"use strict"; +import { afterEach, beforeEach, describe, it } from "node:test"; -const { afterEach, beforeEach, describe, it } = require("node:test"); +import webpack from "webpack"; +import Server from "../../lib/Server.js"; +import config from "../fixtures/mime-types-config/webpack.config.js"; +import runBrowser from "../helpers/run-browser.js"; +import portsMap from "../ports-map.js"; -const webpack = require("webpack"); -const Server = require("../../lib/Server"); -const config = require("../fixtures/mime-types-config/webpack.config"); -const runBrowser = require("../helpers/run-browser"); -const port = require("../ports-map")["mime-types-option"]; +const port = portsMap["mime-types-option"]; describe("mimeTypes option", () => { describe("as an object with a remapped type", () => { diff --git a/test/e2e/module-federation.test.js b/test/e2e/module-federation.test.js index 73ed96ef7b..20ba1bf1e7 100644 --- a/test/e2e/module-federation.test.js +++ b/test/e2e/module-federation.test.js @@ -1,16 +1,16 @@ -"use strict"; - -const { afterEach, beforeEach, describe, it } = require("node:test"); -const { expect } = require("expect"); -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 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"]; +import { afterEach, beforeEach, describe, it } from "node:test"; +import { expect } from "expect"; +import requireFromString from "require-from-string"; +import webpack from "webpack"; +import Server from "../../lib/Server.js"; +import simpleConfig from "../fixtures/module-federation-config/webpack.config.js"; +import multiConfig from "../fixtures/module-federation-config/webpack.multi.config.js"; +import objectEntryConfig from "../fixtures/module-federation-config/webpack.object-entry.config.js"; +import pluginConfig from "../fixtures/module-federation-config/webpack.plugin.js"; +import runBrowser from "../helpers/run-browser.js"; +import portsMap from "../ports-map.js"; + +const port = portsMap["module-federation"]; describe("Module federation", () => { describe("should work with simple multi-entry config", () => { diff --git a/test/e2e/multi-compiler.test.js b/test/e2e/multi-compiler.test.js index a5f5d893c8..bf25fb8f8b 100644 --- a/test/e2e/multi-compiler.test.js +++ b/test/e2e/multi-compiler.test.js @@ -1,16 +1,16 @@ -"use strict"; - -const path = require("node:path"); -const { describe, it } = require("node:test"); -const { expect } = require("expect"); -const fs = require("graceful-fs"); -const webpack = require("webpack"); -const Server = require("../../lib/Server"); -const oneWebTargetConfiguration = require("../fixtures/multi-compiler-one-configuration/webpack.config"); -const twoWebTargetConfiguration = require("../fixtures/multi-compiler-two-configurations/webpack.config"); -const universalConfiguration = require("../fixtures/universal-compiler-config/webpack.config"); -const runBrowser = require("../helpers/run-browser"); -const port = require("../ports-map")["multi-compiler"]; +import path from "node:path"; +import { describe, it } from "node:test"; +import { expect } from "expect"; +import fs from "graceful-fs"; +import webpack from "webpack"; +import Server from "../../lib/Server.js"; +import oneWebTargetConfiguration from "../fixtures/multi-compiler-one-configuration/webpack.config.js"; +import twoWebTargetConfiguration from "../fixtures/multi-compiler-two-configurations/webpack.config.js"; +import universalConfiguration from "../fixtures/universal-compiler-config/webpack.config.js"; +import runBrowser from "../helpers/run-browser.js"; +import portsMap from "../ports-map.js"; + +const port = portsMap["multi-compiler"]; describe("multi compiler", () => { it("should work with one web target configuration and do nothing", async (t) => { diff --git a/test/e2e/on-listening.test.js b/test/e2e/on-listening.test.js index 14c5ac231a..5edabb77e0 100644 --- a/test/e2e/on-listening.test.js +++ b/test/e2e/on-listening.test.js @@ -1,12 +1,12 @@ -"use strict"; - -const { afterEach, beforeEach, describe, it } = require("node:test"); -const { expect } = require("expect"); -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")["on-listening-option"]; +import { afterEach, beforeEach, describe, it } from "node:test"; +import { expect } from "expect"; +import webpack from "webpack"; +import Server from "../../lib/Server.js"; +import config from "../fixtures/client-config/webpack.config.js"; +import runBrowser from "../helpers/run-browser.js"; +import portsMap from "../ports-map.js"; + +const port = portsMap["on-listening-option"]; describe("onListening option", () => { let compiler; diff --git a/test/e2e/options-middleware.test.js b/test/e2e/options-middleware.test.js index 064fa44032..9419c720a4 100644 --- a/test/e2e/options-middleware.test.js +++ b/test/e2e/options-middleware.test.js @@ -1,13 +1,13 @@ -"use strict"; - -const { describe, it } = require("node:test"); -const { expect } = require("expect"); -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"); -const port = require("../ports-map")["options-request-response"]; +import { describe, it } from "node:test"; +import { expect } from "expect"; +import Express from "express"; +import webpack from "webpack"; +import Server from "../../lib/Server.js"; +import config from "../fixtures/client-config/webpack.config.js"; +import runBrowser from "../helpers/run-browser.js"; +import portsMap from "../ports-map.js"; + +const port = portsMap["options-request-response"]; const createWaiting = () => { let resolve; diff --git a/test/e2e/overlay.test.js b/test/e2e/overlay.test.js index f7bdbbba72..7295146c55 100644 --- a/test/e2e/overlay.test.js +++ b/test/e2e/overlay.test.js @@ -1,18 +1,18 @@ -"use strict"; - -const path = require("node:path"); -const { describe, it, mock } = require("node:test"); -const { expect } = require("expect"); -const fs = require("graceful-fs"); -const { fn } = require("jest-mock"); -const prettier = require("prettier"); -const waitForExpect = require("wait-for-expect"); -const webpack = require("webpack"); -const Server = require("../../lib/Server"); -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; +import path from "node:path"; +import { describe, it, mock } from "node:test"; +import { expect } from "expect"; +import fs from "graceful-fs"; +import { fn } from "jest-mock"; +import prettier from "prettier"; +import waitForExpect from "wait-for-expect"; +import webpack from "webpack"; +import Server from "../../lib/Server.js"; +import trustedTypesConfig from "../fixtures/overlay-config/trusted-types.webpack.config.js"; +import config from "../fixtures/overlay-config/webpack.config.js"; +import runBrowser from "../helpers/run-browser.js"; +import portsMap from "../ports-map.js"; + +const port = portsMap.overlay; class ErrorPlugin { constructor(message, skipCounter) { diff --git a/test/e2e/port.test.js b/test/e2e/port.test.js index c179eea6df..4930453eca 100644 --- a/test/e2e/port.test.js +++ b/test/e2e/port.test.js @@ -1,12 +1,12 @@ -"use strict"; - -const { describe, it } = require("node:test"); -const { expect } = require("expect"); -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"); +import { describe, it } from "node:test"; +import { expect } from "expect"; +import webpack from "webpack"; +import Server from "../../lib/Server.js"; +import config from "../fixtures/client-config/webpack.config.js"; +import runBrowser from "../helpers/run-browser.js"; +import portsMap from "../ports-map.js"; + +const { port } = portsMap; describe("port", () => { const ports = [ diff --git a/test/e2e/progress.test.js b/test/e2e/progress.test.js index d5e378acb3..0f9b17e26a 100644 --- a/test/e2e/progress.test.js +++ b/test/e2e/progress.test.js @@ -1,14 +1,14 @@ -"use strict"; - -const path = require("node:path"); -const { describe, it } = require("node:test"); -const { expect } = require("expect"); -const fs = require("graceful-fs"); -const webpack = require("webpack"); -const Server = require("../../lib/Server"); -const reloadConfig = require("../fixtures/reload-config-2/webpack.config"); -const runBrowser = require("../helpers/run-browser"); -const port = require("../ports-map").progress; +import path from "node:path"; +import { describe, it } from "node:test"; +import { expect } from "expect"; +import fs from "graceful-fs"; +import webpack from "webpack"; +import Server from "../../lib/Server.js"; +import reloadConfig from "../fixtures/reload-config-2/webpack.config.js"; +import runBrowser from "../helpers/run-browser.js"; +import portsMap from "../ports-map.js"; + +const port = portsMap.progress; const cssFilePath = path.resolve( __dirname, diff --git a/test/e2e/range-header.test.js b/test/e2e/range-header.test.js index c33ebc8e5e..45722b7372 100644 --- a/test/e2e/range-header.test.js +++ b/test/e2e/range-header.test.js @@ -1,12 +1,12 @@ -"use strict"; - -const { after, before, describe, it } = require("node:test"); -const { expect } = require("expect"); -const request = require("supertest"); -const webpack = require("webpack"); -const Server = require("../../lib/Server"); -const config = require("../fixtures/static-config/webpack.config"); -const port = require("../ports-map")["range-header"]; +import { after, before, describe, it } from "node:test"; +import { expect } from "expect"; +import request from "supertest"; +import webpack from "webpack"; +import Server from "../../lib/Server.js"; +import config from "../fixtures/static-config/webpack.config.js"; +import portsMap from "../ports-map.js"; + +const port = portsMap["range-header"]; describe("'Range' header", () => { let compiler; diff --git a/test/e2e/server-and-client-transport.test.js b/test/e2e/server-and-client-transport.test.js index 5403dbfe90..553fa8eff2 100644 --- a/test/e2e/server-and-client-transport.test.js +++ b/test/e2e/server-and-client-transport.test.js @@ -1,14 +1,15 @@ -"use strict"; - -const { describe, it } = require("node:test"); -const { expect } = require("expect"); -const webpack = require("webpack"); -const Server = require("../../lib/Server"); -const WebsocketServer = require("../../lib/servers/WebsocketServer"); -const defaultConfig = require("../fixtures/provide-plugin-default/webpack.config"); -const wsConfig = require("../fixtures/provide-plugin-ws-config/webpack.config"); -const runBrowser = require("../helpers/run-browser"); -const port = require("../ports-map")["server-and-client-transport"]; +import { describe, it } from "node:test"; +import { fileURLToPath } from "node:url"; +import { expect } from "expect"; +import webpack from "webpack"; +import Server from "../../lib/Server.js"; +import WebsocketServer from "../../lib/servers/WebsocketServer.js"; +import defaultConfig from "../fixtures/provide-plugin-default/webpack.config.js"; +import wsConfig from "../fixtures/provide-plugin-ws-config/webpack.config.js"; +import runBrowser from "../helpers/run-browser.js"; +import portsMap from "../ports-map.js"; + +const port = portsMap["server-and-client-transport"]; describe("server and client transport", () => { it('should use default web socket server ("ws")', async (t) => { @@ -202,7 +203,7 @@ describe("server and client transport", () => { client: { webSocketTransport: "ws", }, - webSocketServer: require.resolve("../../lib/servers/WebsocketServer"), + webSocketServer: fileURLToPath(import.meta.resolve("../../lib/servers/WebsocketServer.js")), }; const server = new Server(devServerOptions, compiler); @@ -241,7 +242,7 @@ describe("server and client transport", () => { webSocketTransport: "ws", }, webSocketServer: { - type: require.resolve("../../lib/servers/WebsocketServer"), + type: fileURLToPath(import.meta.resolve("../../lib/servers/WebsocketServer.js")), }, }; const server = new Server(devServerOptions, compiler); diff --git a/test/e2e/server.test.js b/test/e2e/server.test.js index bee4ca3b2a..a25d5d4cac 100644 --- a/test/e2e/server.test.js +++ b/test/e2e/server.test.js @@ -1,20 +1,20 @@ -"use strict"; - -const https = require("node:https"); -const path = require("node:path"); -const { afterEach, beforeEach, describe, it } = require("node:test"); -const { expect } = require("expect"); -const fs = require("graceful-fs"); -const { spyOn } = require("jest-mock"); -const request = require("supertest"); -const webpack = require("webpack"); -const Server = require("../../lib/Server"); -const config = require("../fixtures/static-config/webpack.config"); -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"]; +import https from "node:https"; +import path from "node:path"; +import { afterEach, beforeEach, describe, it } from "node:test"; +import { expect } from "expect"; +import fs from "graceful-fs"; +import { spyOn } from "jest-mock"; +import request from "supertest"; +import webpack from "webpack"; +import Server from "../../lib/Server.js"; +import config from "../fixtures/static-config/webpack.config.js"; +import { skipTestOnWindows } from "../helpers/conditional-test.js"; +import customHTTP from "../helpers/custom-http.js"; +import normalizeOptions from "../helpers/normalize-options.js"; +import runBrowser from "../helpers/run-browser.js"; +import portsMap from "../ports-map.js"; + +const port = portsMap["server-option"]; const httpsCertificateDirectory = path.resolve( __dirname, diff --git a/test/e2e/setup-exit-signals.test.js b/test/e2e/setup-exit-signals.test.js index a4cd43509a..6fbad84f4f 100644 --- a/test/e2e/setup-exit-signals.test.js +++ b/test/e2e/setup-exit-signals.test.js @@ -1,13 +1,13 @@ -"use strict"; - -const { afterEach, beforeEach, describe, it } = require("node:test"); -const { expect } = require("expect"); -const { spyOn } = require("jest-mock"); -const webpack = require("webpack"); -const Server = require("../../lib/Server"); -const config = require("../fixtures/simple-config/webpack.config"); -const runBrowser = require("../helpers/run-browser"); -const port = require("../ports-map")["setup-exit-signals-option"]; +import { afterEach, beforeEach, describe, it } from "node:test"; +import { expect } from "expect"; +import { spyOn } from "jest-mock"; +import webpack from "webpack"; +import Server from "../../lib/Server.js"; +import config from "../fixtures/simple-config/webpack.config.js"; +import runBrowser from "../helpers/run-browser.js"; +import portsMap from "../ports-map.js"; + +const port = portsMap["setup-exit-signals-option"]; describe("setupExitSignals option", () => { describe("should handle 'SIGINT' and 'SIGTERM' signals", () => { diff --git a/test/e2e/setup-middlewares.test.js b/test/e2e/setup-middlewares.test.js index 6b0426711f..e41e5ab676 100644 --- a/test/e2e/setup-middlewares.test.js +++ b/test/e2e/setup-middlewares.test.js @@ -1,12 +1,12 @@ -"use strict"; +import { afterEach, beforeEach, describe, it } from "node:test"; -const { afterEach, beforeEach, describe, it } = require("node:test"); +import webpack from "webpack"; +import Server from "../../lib/Server.js"; +import config from "../fixtures/client-config/webpack.config.js"; +import runBrowser from "../helpers/run-browser.js"; +import portsMap from "../ports-map.js"; -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")["setup-middlewares-option"]; +const port = portsMap["setup-middlewares-option"]; describe("setupMiddlewares option", () => { let compiler; diff --git a/test/e2e/static-directory.test.js b/test/e2e/static-directory.test.js index 480cb2a85a..b10ffb19db 100644 --- a/test/e2e/static-directory.test.js +++ b/test/e2e/static-directory.test.js @@ -1,16 +1,16 @@ -"use strict"; - -const path = require("node:path"); -const { afterEach, beforeEach, describe, it } = require("node:test"); -const { expect } = require("expect"); -const fs = require("graceful-fs"); -const { spyOn } = require("jest-mock"); -const webpack = require("webpack"); -const Server = require("../../lib/Server"); -const config = require("../fixtures/static-config/webpack.config"); -const runBrowser = require("../helpers/run-browser"); -const testServer = require("../helpers/test-server"); -const port = require("../ports-map")["static-directory-option"]; +import path from "node:path"; +import { afterEach, beforeEach, describe, it } from "node:test"; +import { expect } from "expect"; +import fs from "graceful-fs"; +import { spyOn } from "jest-mock"; +import webpack from "webpack"; +import Server from "../../lib/Server.js"; +import config from "../fixtures/static-config/webpack.config.js"; +import runBrowser from "../helpers/run-browser.js"; +import * as testServer from "../helpers/test-server.js"; +import portsMap from "../ports-map.js"; + +const port = portsMap["static-directory-option"]; const staticDirectory = path.resolve(__dirname, "../fixtures/static-config"); const publicDirectory = path.resolve(staticDirectory, "public"); diff --git a/test/e2e/static-public-path.test.js b/test/e2e/static-public-path.test.js index c080d880e6..22fdcb8785 100644 --- a/test/e2e/static-public-path.test.js +++ b/test/e2e/static-public-path.test.js @@ -1,14 +1,14 @@ -"use strict"; - -const path = require("node:path"); -const { afterEach, beforeEach, describe, it } = require("node:test"); -const { expect } = require("expect"); -const { spyOn } = require("jest-mock"); -const webpack = require("webpack"); -const Server = require("../../lib/Server"); -const config = require("../fixtures/static-config/webpack.config"); -const runBrowser = require("../helpers/run-browser"); -const port = require("../ports-map")["static-public-path-option"]; +import path from "node:path"; +import { afterEach, beforeEach, describe, it } from "node:test"; +import { expect } from "expect"; +import { spyOn } from "jest-mock"; +import webpack from "webpack"; +import Server from "../../lib/Server.js"; +import config from "../fixtures/static-config/webpack.config.js"; +import runBrowser from "../helpers/run-browser.js"; +import portsMap from "../ports-map.js"; + +const port = portsMap["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 fa42603a27..caf9514524 100644 --- a/test/e2e/stats.test.js +++ b/test/e2e/stats.test.js @@ -1,14 +1,14 @@ -"use strict"; +import { describe, test } from "node:test"; -const { describe, test } = require("node:test"); +import { spyOn } from "jest-mock"; +import webpack from "webpack"; +import Server from "../../lib/Server.js"; +import config from "../fixtures/client-config/webpack.config.js"; +import HTMLGeneratorPlugin from "../helpers/html-generator-plugin.js"; +import runBrowser from "../helpers/run-browser.js"; +import portsMap from "../ports-map.js"; -const { spyOn } = require("jest-mock"); -const webpack = require("webpack"); -const Server = require("../../lib/Server"); -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").stats; +const port = portsMap.stats; spyOn(globalThis.console, "log").mockImplementation(); diff --git a/test/e2e/target.test.js b/test/e2e/target.test.js index 1b902a591b..1a8a34f9f1 100644 --- a/test/e2e/target.test.js +++ b/test/e2e/target.test.js @@ -1,19 +1,19 @@ -"use strict"; - -const path = require("node:path"); -const { describe, it } = require("node:test"); -const { expect } = require("expect"); -const webpack = require("webpack"); -const Server = require("../../lib/Server"); -const config = require("../fixtures/client-config/webpack.config"); +import path from "node:path"; +import { describe, it } from "node:test"; +import { expect } from "expect"; +import webpack from "webpack"; +import Server from "../../lib/Server.js"; +import config from "../fixtures/client-config/webpack.config.js"; // Set up jsdom before loading fixtures that use browser APIs like Worker -require("../helpers/jsdom-setup"); +import "../helpers/jsdom-setup.js"; + +import workerConfig from "../fixtures/worker-config/webpack.config.js"; +import workerConfigDevServerFalse from "../fixtures/worker-config-dev-server-false/webpack.config.js"; +import runBrowser from "../helpers/run-browser.js"; +import portsMap from "../ports-map.js"; -const workerConfig = require("../fixtures/worker-config/webpack.config"); -const workerConfigDevServerFalse = require("../fixtures/worker-config-dev-server-false/webpack.config"); -const runBrowser = require("../helpers/run-browser"); -const port = require("../ports-map").target; +const port = portsMap.target; const sortByTerm = (data, term) => data.sort((a, b) => (a.indexOf(term) < b.indexOf(term) ? -1 : 1)); diff --git a/test/e2e/watch-files.test.js b/test/e2e/watch-files.test.js index c95170139c..7b9cff8415 100644 --- a/test/e2e/watch-files.test.js +++ b/test/e2e/watch-files.test.js @@ -1,14 +1,14 @@ -"use strict"; - -const path = require("node:path"); -const { afterEach, beforeEach, describe, it } = require("node:test"); -const { expect } = require("expect"); -const fs = require("graceful-fs"); -const webpack = require("webpack"); -const Server = require("../../lib/Server"); -const config = require("../fixtures/watch-files-config/webpack.config"); -const runBrowser = require("../helpers/run-browser"); -const port = require("../ports-map")["watch-files-option"]; +import path from "node:path"; +import { afterEach, beforeEach, describe, it } from "node:test"; +import { expect } from "expect"; +import fs from "graceful-fs"; +import webpack from "webpack"; +import Server from "../../lib/Server.js"; +import config from "../fixtures/watch-files-config/webpack.config.js"; +import runBrowser from "../helpers/run-browser.js"; +import portsMap from "../ports-map.js"; + +const port = portsMap["watch-files-option"]; const watchDir = path.resolve( __dirname, diff --git a/test/e2e/web-socket-communication.test.js b/test/e2e/web-socket-communication.test.js index 43adb64875..3154838789 100644 --- a/test/e2e/web-socket-communication.test.js +++ b/test/e2e/web-socket-communication.test.js @@ -1,14 +1,14 @@ -"use strict"; - -const { describe, it } = require("node:test"); -const { expect } = require("expect"); -const webpack = require("webpack"); -const WebSocket = require("ws"); -const Server = require("../../lib/Server"); -const WebsocketServer = require("../../lib/servers/WebsocketServer"); -const config = require("../fixtures/client-config/webpack.config"); -const runBrowser = require("../helpers/run-browser"); -const port = require("../ports-map")["web-socket-communication"]; +import { describe, it } from "node:test"; +import { expect } from "expect"; +import webpack from "webpack"; +import WebSocket from "ws"; +import Server from "../../lib/Server.js"; +import WebsocketServer from "../../lib/servers/WebsocketServer.js"; +import config from "../fixtures/client-config/webpack.config.js"; +import runBrowser from "../helpers/run-browser.js"; +import portsMap from "../ports-map.js"; + +const port = portsMap["web-socket-communication"]; describe("web socket communication", () => { const webSocketServers = ["ws"]; diff --git a/test/e2e/web-socket-server-url.test.js b/test/e2e/web-socket-server-url.test.js index fe399668c3..e2adc837ff 100644 --- a/test/e2e/web-socket-server-url.test.js +++ b/test/e2e/web-socket-server-url.test.js @@ -1,15 +1,15 @@ -"use strict"; - -const { describe, it } = require("node:test"); -const { expect } = require("expect"); -const express = require("express"); -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"); -const sessionSubscribe = require("../helpers/session-subscribe"); -const [port1, port2] = require("../ports-map")["web-socket-server-url"]; +import { describe, it } from "node:test"; +import { expect } from "expect"; +import express from "express"; +import { createProxyMiddleware } from "http-proxy-middleware"; +import webpack from "webpack"; +import Server from "../../lib/Server.js"; +import config from "../fixtures/client-config/webpack.config.js"; +import runBrowser from "../helpers/run-browser.js"; +import sessionSubscribe from "../helpers/session-subscribe.js"; +import portsMap from "../ports-map.js"; + +const [port1, port2] = portsMap["web-socket-server-url"]; const webSocketServers = ["ws"]; diff --git a/test/e2e/web-socket-server.test.js b/test/e2e/web-socket-server.test.js index 80cbbeb34d..1a0856b5e9 100644 --- a/test/e2e/web-socket-server.test.js +++ b/test/e2e/web-socket-server.test.js @@ -1,13 +1,13 @@ -"use strict"; +import { describe, it } from "node:test"; +import { expect } from "expect"; +import webpack from "webpack"; +import Server from "../../lib/Server.js"; +import config from "../fixtures/client-config/webpack.config.js"; +import runBrowser from "../helpers/run-browser.js"; +import sessionSubscribe from "../helpers/session-subscribe.js"; +import portsMap from "../ports-map.js"; -const { describe, it } = require("node:test"); -const { expect } = require("expect"); -const webpack = require("webpack"); -const Server = require("../../lib/Server"); -const config = require("../fixtures/client-config/webpack.config"); -const runBrowser = require("../helpers/run-browser"); -const sessionSubscribe = require("../helpers/session-subscribe"); -const port = require("../ports-map")["web-socket-server-test"]; +const port = portsMap["web-socket-server-test"]; describe("web socket server", () => { it("should work allow to disable", async (t) => { diff --git a/test/server/open-option.test.js b/test/server/open-option.test.js index 7a973b70b6..e8379918c9 100644 --- a/test/server/open-option.test.js +++ b/test/server/open-option.test.js @@ -1,12 +1,12 @@ -"use strict"; - -const { afterEach, beforeEach, describe, it, mock } = require("node:test"); -const { expect } = require("expect"); -const { fn, spyOn } = require("jest-mock"); -const webpack = require("webpack"); -const Server = require("../../lib/Server"); -const config = require("../fixtures/simple-config/webpack.config"); -const port = require("../ports-map")["open-option"]; +import { afterEach, beforeEach, describe, it, mock } from "node:test"; +import { expect } from "expect"; +import { fn, spyOn } from "jest-mock"; +import webpack from "webpack"; +import Server from "../../lib/Server.js"; +import config from "../fixtures/simple-config/webpack.config.js"; +import portsMap from "../ports-map.js"; + +const port = portsMap["open-option"]; const internalIPv4 = Server.findIp("v4", false); diff --git a/test/server/proxy-option.test.js b/test/server/proxy-option.test.js index 81cb0bd49c..0e56837641 100644 --- a/test/server/proxy-option.test.js +++ b/test/server/proxy-option.test.js @@ -1,18 +1,22 @@ -"use strict"; - -const path = require("node:path"); -const { after, before, beforeEach, describe, it } = require("node:test"); -const { expect } = require("expect"); -const express = require("express"); -const { spyOn } = require("jest-mock"); -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"]; +import path from "node:path"; +import { after, before, beforeEach, describe, it } from "node:test"; +import { fileURLToPath } from "node:url"; +import express from "express"; +import { expect } from "expect"; +import { spyOn } from "jest-mock"; +import request from "supertest"; +import webpack from "webpack"; +import WebSocket from "ws"; +import Server from "../../lib/Server.js"; +import config from "../fixtures/proxy-config/webpack.config.js"; +import portsMap from "../ports-map.js"; + +const __dirname = path.dirname(fileURLToPath(import.meta.url)); const WebSocketServer = WebSocket.Server; + +const [port1, port2, port3, port4] = portsMap["proxy-option"]; + const staticDirectory = path.resolve(__dirname, "../fixtures/proxy-config"); const proxyOptionPathsAsProperties = [ From 9f1b3e99f1c1190670e6552933130531b8b310a1 Mon Sep 17 00:00:00 2001 From: Sebastian Beltran Date: Mon, 11 May 2026 10:31:09 -0500 Subject: [PATCH 07/29] refactor: migrate test files to use fileURLToPath for __dirname --- test/e2e/api.test.js | 2 ++ test/e2e/entry.test.js | 2 ++ test/e2e/history-api-fallback.test.js | 2 ++ test/e2e/logging.test.js | 2 ++ test/e2e/multi-compiler.test.js | 2 ++ test/e2e/overlay.test.js | 2 ++ test/e2e/progress.test.js | 2 ++ test/e2e/server.test.js | 2 ++ test/e2e/static-directory.test.js | 2 ++ test/e2e/static-public-path.test.js | 2 ++ test/e2e/target.test.js | 2 ++ test/e2e/watch-files.test.js | 2 ++ 12 files changed, 24 insertions(+) diff --git a/test/e2e/api.test.js b/test/e2e/api.test.js index 46bb459d1e..c29a9a5bdb 100644 --- a/test/e2e/api.test.js +++ b/test/e2e/api.test.js @@ -1,4 +1,5 @@ import path from "node:path"; +import { fileURLToPath } from "node:url"; import { afterEach, beforeEach, describe, it, mock } from "node:test"; import { expect } from "expect"; import { fn } from "jest-mock"; @@ -9,6 +10,7 @@ import runBrowser from "../helpers/run-browser.js"; import sessionSubscribe from "../helpers/session-subscribe.js"; import portsMap from "../ports-map.js"; +const __dirname = path.dirname(fileURLToPath(import.meta.url)); const port = portsMap.api; describe("API", () => { diff --git a/test/e2e/entry.test.js b/test/e2e/entry.test.js index b1fa5eb26d..061d436d0d 100644 --- a/test/e2e/entry.test.js +++ b/test/e2e/entry.test.js @@ -1,4 +1,5 @@ import path from "node:path"; +import { fileURLToPath } from "node:url"; import { describe, it } from "node:test"; import webpack from "webpack"; @@ -7,6 +8,7 @@ import config from "../fixtures/client-config/webpack.config.js"; import runBrowser from "../helpers/run-browser.js"; import portsMap from "../ports-map.js"; +const __dirname = path.dirname(fileURLToPath(import.meta.url)); const port = portsMap.entry; const HOT_ENABLED_MESSAGE = diff --git a/test/e2e/history-api-fallback.test.js b/test/e2e/history-api-fallback.test.js index 9dc10f49ab..309e9111c9 100644 --- a/test/e2e/history-api-fallback.test.js +++ b/test/e2e/history-api-fallback.test.js @@ -1,4 +1,5 @@ import path from "node:path"; +import { fileURLToPath } from "node:url"; import { afterEach, beforeEach, describe, it } from "node:test"; import { expect } from "expect"; import { spyOn } from "jest-mock"; @@ -10,6 +11,7 @@ import config from "../fixtures/historyapifallback-config/webpack.config.js"; import runBrowser from "../helpers/run-browser.js"; import portsMap from "../ports-map.js"; +const __dirname = path.dirname(fileURLToPath(import.meta.url)); const port = portsMap["history-api-fallback-option"]; describe("historyApiFallback option", () => { diff --git a/test/e2e/logging.test.js b/test/e2e/logging.test.js index 8555a8d468..deb97fc273 100644 --- a/test/e2e/logging.test.js +++ b/test/e2e/logging.test.js @@ -1,4 +1,5 @@ import path from "node:path"; +import { fileURLToPath } from "node:url"; import { describe, it } from "node:test"; import fs from "graceful-fs"; @@ -9,6 +10,7 @@ import HTMLGeneratorPlugin from "../helpers/html-generator-plugin.js"; import runBrowser from "../helpers/run-browser.js"; import portsMap from "../ports-map.js"; +const __dirname = path.dirname(fileURLToPath(import.meta.url)); const port = portsMap.logging; describe("logging", () => { diff --git a/test/e2e/multi-compiler.test.js b/test/e2e/multi-compiler.test.js index bf25fb8f8b..8d793d2f42 100644 --- a/test/e2e/multi-compiler.test.js +++ b/test/e2e/multi-compiler.test.js @@ -1,4 +1,5 @@ import path from "node:path"; +import { fileURLToPath } from "node:url"; import { describe, it } from "node:test"; import { expect } from "expect"; import fs from "graceful-fs"; @@ -10,6 +11,7 @@ import universalConfiguration from "../fixtures/universal-compiler-config/webpac import runBrowser from "../helpers/run-browser.js"; import portsMap from "../ports-map.js"; +const __dirname = path.dirname(fileURLToPath(import.meta.url)); const port = portsMap["multi-compiler"]; describe("multi compiler", () => { diff --git a/test/e2e/overlay.test.js b/test/e2e/overlay.test.js index 7295146c55..59f1e83240 100644 --- a/test/e2e/overlay.test.js +++ b/test/e2e/overlay.test.js @@ -1,4 +1,5 @@ import path from "node:path"; +import { fileURLToPath } from "node:url"; import { describe, it, mock } from "node:test"; import { expect } from "expect"; import fs from "graceful-fs"; @@ -12,6 +13,7 @@ import config from "../fixtures/overlay-config/webpack.config.js"; import runBrowser from "../helpers/run-browser.js"; import portsMap from "../ports-map.js"; +const __dirname = path.dirname(fileURLToPath(import.meta.url)); const port = portsMap.overlay; class ErrorPlugin { diff --git a/test/e2e/progress.test.js b/test/e2e/progress.test.js index 0f9b17e26a..149839ca64 100644 --- a/test/e2e/progress.test.js +++ b/test/e2e/progress.test.js @@ -1,4 +1,5 @@ import path from "node:path"; +import { fileURLToPath } from "node:url"; import { describe, it } from "node:test"; import { expect } from "expect"; import fs from "graceful-fs"; @@ -8,6 +9,7 @@ import reloadConfig from "../fixtures/reload-config-2/webpack.config.js"; import runBrowser from "../helpers/run-browser.js"; import portsMap from "../ports-map.js"; +const __dirname = path.dirname(fileURLToPath(import.meta.url)); const port = portsMap.progress; const cssFilePath = path.resolve( diff --git a/test/e2e/server.test.js b/test/e2e/server.test.js index a25d5d4cac..2cfeaae73d 100644 --- a/test/e2e/server.test.js +++ b/test/e2e/server.test.js @@ -1,5 +1,6 @@ import https from "node:https"; import path from "node:path"; +import { fileURLToPath } from "node:url"; import { afterEach, beforeEach, describe, it } from "node:test"; import { expect } from "expect"; import fs from "graceful-fs"; @@ -14,6 +15,7 @@ import normalizeOptions from "../helpers/normalize-options.js"; import runBrowser from "../helpers/run-browser.js"; import portsMap from "../ports-map.js"; +const __dirname = path.dirname(fileURLToPath(import.meta.url)); const port = portsMap["server-option"]; const httpsCertificateDirectory = path.resolve( diff --git a/test/e2e/static-directory.test.js b/test/e2e/static-directory.test.js index b10ffb19db..a5df7daba7 100644 --- a/test/e2e/static-directory.test.js +++ b/test/e2e/static-directory.test.js @@ -1,4 +1,5 @@ import path from "node:path"; +import { fileURLToPath } from "node:url"; import { afterEach, beforeEach, describe, it } from "node:test"; import { expect } from "expect"; import fs from "graceful-fs"; @@ -10,6 +11,7 @@ import runBrowser from "../helpers/run-browser.js"; import * as testServer from "../helpers/test-server.js"; import portsMap from "../ports-map.js"; +const __dirname = path.dirname(fileURLToPath(import.meta.url)); const port = portsMap["static-directory-option"]; const staticDirectory = path.resolve(__dirname, "../fixtures/static-config"); diff --git a/test/e2e/static-public-path.test.js b/test/e2e/static-public-path.test.js index 22fdcb8785..42f367d0cd 100644 --- a/test/e2e/static-public-path.test.js +++ b/test/e2e/static-public-path.test.js @@ -1,4 +1,5 @@ import path from "node:path"; +import { fileURLToPath } from "node:url"; import { afterEach, beforeEach, describe, it } from "node:test"; import { expect } from "expect"; import { spyOn } from "jest-mock"; @@ -8,6 +9,7 @@ import config from "../fixtures/static-config/webpack.config.js"; import runBrowser from "../helpers/run-browser.js"; import portsMap from "../ports-map.js"; +const __dirname = path.dirname(fileURLToPath(import.meta.url)); const port = portsMap["static-public-path-option"]; const staticDirectory = path.resolve(__dirname, "../fixtures/static-config"); diff --git a/test/e2e/target.test.js b/test/e2e/target.test.js index 1a8a34f9f1..929c62c026 100644 --- a/test/e2e/target.test.js +++ b/test/e2e/target.test.js @@ -1,4 +1,5 @@ import path from "node:path"; +import { fileURLToPath } from "node:url"; import { describe, it } from "node:test"; import { expect } from "expect"; import webpack from "webpack"; @@ -13,6 +14,7 @@ import workerConfigDevServerFalse from "../fixtures/worker-config-dev-server-fal import runBrowser from "../helpers/run-browser.js"; import portsMap from "../ports-map.js"; +const __dirname = path.dirname(fileURLToPath(import.meta.url)); const port = portsMap.target; const sortByTerm = (data, term) => diff --git a/test/e2e/watch-files.test.js b/test/e2e/watch-files.test.js index 7b9cff8415..30110d83af 100644 --- a/test/e2e/watch-files.test.js +++ b/test/e2e/watch-files.test.js @@ -1,4 +1,5 @@ import path from "node:path"; +import { fileURLToPath } from "node:url"; import { afterEach, beforeEach, describe, it } from "node:test"; import { expect } from "expect"; import fs from "graceful-fs"; @@ -8,6 +9,7 @@ import config from "../fixtures/watch-files-config/webpack.config.js"; import runBrowser from "../helpers/run-browser.js"; import portsMap from "../ports-map.js"; +const __dirname = path.dirname(fileURLToPath(import.meta.url)); const port = portsMap["watch-files-option"]; const watchDir = path.resolve( From 2dfb6d45258ee99b723b83ba0f2a13472d1f17be Mon Sep 17 00:00:00 2001 From: Sebastian Beltran Date: Mon, 11 May 2026 10:40:19 -0500 Subject: [PATCH 08/29] refactor: remove duplicate import of http in cross-origin request tests --- test/e2e/cross-origin-request.test.js | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/test/e2e/cross-origin-request.test.js b/test/e2e/cross-origin-request.test.js index e1bef2e3a0..c761470895 100644 --- a/test/e2e/cross-origin-request.test.js +++ b/test/e2e/cross-origin-request.test.js @@ -1,3 +1,4 @@ +import http from "node:http"; import { describe, it } from "node:test"; import { expect } from "expect"; import webpack from "webpack"; @@ -24,7 +25,6 @@ describe("cross-origin requests", () => { await server.start(); // Start a separate server for serving the HTML file - import http from "node:http"; const htmlServer = http.createServer((req, res) => { res.writeHead(200, { "Content-Type": "text/html" }); @@ -78,7 +78,6 @@ describe("cross-origin requests", () => { await server.start(); // Start a separate server for serving the HTML file - import http from "node:http"; const htmlServer = http.createServer((req, res) => { res.writeHead(200, { "Content-Type": "text/html" }); @@ -129,7 +128,6 @@ describe("cross-origin requests", () => { await server.start(); // Start a separate server for serving the HTML file - import http from "node:http"; const htmlServer = http.createServer((req, res) => { res.writeHead(200, { "Content-Type": "text/html" }); @@ -180,7 +178,6 @@ describe("cross-origin requests", () => { await server.start(); // Start a separate server for serving the HTML file - import http from "node:http"; const htmlServer = http.createServer((req, res) => { res.writeHead(200, { "Content-Type": "text/html" }); From 899db46f390495f934c9a0b39a861036692de72b Mon Sep 17 00:00:00 2001 From: Sebastian Beltran Date: Mon, 11 May 2026 11:01:51 -0500 Subject: [PATCH 09/29] refactor: update library type to module and enable outputModule experiment in webpack config --- client-src/webpack.config.js | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/client-src/webpack.config.js b/client-src/webpack.config.js index 5aa430209b..e806f668c2 100644 --- a/client-src/webpack.config.js +++ b/client-src/webpack.config.js @@ -7,18 +7,16 @@ const __dirname = path.dirname(fileURLToPath(import.meta.url)); const library = { library: { - // type: "module", - type: "commonjs", + type: "module", }, }; const baseForModules = { devtool: false, mode: "development", - // TODO enable this in future after fix bug with `eval` in webpack - // experiments: { - // outputModule: true, - // }, + experiments: { + outputModule: true, + }, output: { path: path.resolve(__dirname, "../client/modules"), ...library, From dd31f4f167a7273da6481d6806491fedac32c56c Mon Sep 17 00:00:00 2001 From: Sebastian Beltran Date: Mon, 11 May 2026 22:41:37 -0500 Subject: [PATCH 10/29] refactor: update client transport implementation checks and adjust module federation test assertions --- lib/Server.js | 6 ++++++ .../server-and-client-transport.test.js.snap.webpack5 | 6 +++--- test/e2e/module-federation.test.js | 8 ++++---- 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/lib/Server.js b/lib/Server.js index 6dfdf90c23..3de45eaed3 100644 --- a/lib/Server.js +++ b/lib/Server.js @@ -1495,6 +1495,12 @@ class Server { clientImplementation = fileURLToPath( import.meta.resolve(clientTransport), ); + if ( + path.isAbsolute(clientTransport) && + !fs.existsSync(clientImplementation) + ) { + clientImplementationFound = false; + } } catch { clientImplementationFound = false; } diff --git a/test/e2e/__snapshots__/server-and-client-transport.test.js.snap.webpack5 b/test/e2e/__snapshots__/server-and-client-transport.test.js.snap.webpack5 index 9a6e519f00..3ee013ede0 100644 --- a/test/e2e/__snapshots__/server-and-client-transport.test.js.snap.webpack5 +++ b/test/e2e/__snapshots__/server-and-client-transport.test.js.snap.webpack5 @@ -1,13 +1,13 @@ exports[`server and client transport > should throw an error on invalid path to client transport 1`] = ` -"client.webSocketTransport must be a string denoting a default implementation (e.g. 'ws') or a full path to a JS file via require.resolve(...) which exports a class " +"client.webSocketTransport must be a string denoting a default implementation (e.g. 'ws') or a resolvable module specifier or absolute file path which exports a class " `; exports[`server and client transport > should throw an error on invalid path to server transport 1`] = ` -"webSocketServer (webSocketServer.type) must be a string denoting a default implementation (e.g. 'ws'), a full path to a JS file which exports a class extending BaseServer (webpack-dev-server/lib/servers/BaseServer.js) via require.resolve(...), or the class itself which extends BaseServer" +"webSocketServer (webSocketServer.type) must be a string denoting a default implementation (e.g. 'ws'), a resolvable module specifier or absolute file path which exports a class extending BaseServer (webpack-dev-server/lib/servers/BaseServer.js), or the class itself which extends BaseServer" `; exports[`server and client transport > should throw an error on wrong path 1`] = ` -"webSocketServer (webSocketServer.type) must be a string denoting a default implementation (e.g. 'ws'), a full path to a JS file which exports a class extending BaseServer (webpack-dev-server/lib/servers/BaseServer.js) via require.resolve(...), or the class itself which extends BaseServer" +"webSocketServer (webSocketServer.type) must be a string denoting a default implementation (e.g. 'ws'), a resolvable module specifier or absolute file path which exports a class extending BaseServer (webpack-dev-server/lib/servers/BaseServer.js), or the class itself which extends BaseServer" `; exports[`server and client transport > should use "ws" transport and "ws" web socket server 1`] = ` diff --git a/test/e2e/module-federation.test.js b/test/e2e/module-federation.test.js index 20ba1bf1e7..18c26a67c3 100644 --- a/test/e2e/module-federation.test.js +++ b/test/e2e/module-federation.test.js @@ -61,7 +61,7 @@ describe("Module federation", () => { exports = requireFromString(textContent); }).not.toThrow(); - expect(exports).toBe("entry2"); + expect(exports.default).toBe("entry2"); t.assert.snapshot(consoleMessages.map((message) => message.text())); @@ -117,7 +117,7 @@ describe("Module federation", () => { exports = requireFromString(textContent); }).not.toThrow(); - expect(exports).toBe("entry2"); + expect(exports.default).toBe("entry2"); t.assert.snapshot(consoleMessages.map((message) => message.text())); @@ -147,7 +147,7 @@ describe("Module federation", () => { exports = requireFromString(textContent); }).not.toThrow(); - expect(exports).toBe("entry1"); + expect(exports.default).toBe("entry1"); t.assert.snapshot(consoleMessages.map((message) => message.text())); @@ -203,7 +203,7 @@ describe("Module federation", () => { exports = requireFromString(textContent); }).not.toThrow(); - expect(exports).toBe("entry2"); + expect(exports.default).toBe("entry2"); t.assert.snapshot(consoleMessages.map((message) => message.text())); From 5daa8f785c0605a342877fdfb7bce5e6da06a77e Mon Sep 17 00:00:00 2001 From: Sebastian Beltran Date: Mon, 11 May 2026 23:41:55 -0500 Subject: [PATCH 11/29] refactor: enhance client transport handling with pathToFileURL for absolute paths --- lib/Server.js | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/lib/Server.js b/lib/Server.js index 3de45eaed3..f1ac9cd803 100644 --- a/lib/Server.js +++ b/lib/Server.js @@ -1,3 +1,4 @@ +import { createRequire } from "node:module"; import net from "node:net"; import os from "node:os"; import path from "node:path"; @@ -7,6 +8,8 @@ import ipaddr from "ipaddr.js"; import { validate } from "schema-utils"; import schema from "./options.json" with { type: "json" }; +const require = createRequire(import.meta.url); + /** @type {typeof import("webpack") | undefined} */ let webpackPeer; try { @@ -1492,15 +1495,7 @@ class Server { ); } else { try { - clientImplementation = fileURLToPath( - import.meta.resolve(clientTransport), - ); - if ( - path.isAbsolute(clientTransport) && - !fs.existsSync(clientImplementation) - ) { - clientImplementationFound = false; - } + clientImplementation = require.resolve(clientTransport); } catch { clientImplementationFound = false; } @@ -1549,12 +1544,13 @@ class Server { .default; } else { try { - const mod = await import( + const mod = require( /** @type {string} */ ( /** @type {WebSocketServerConfiguration} */ (this.options.webSocketServer).type - ) + ), ); + implementation = mod.default || mod; } catch { implementationFound = false; @@ -2415,7 +2411,8 @@ class Server { (this.app), ); } else { - const mod = await import(/** @type {string} */ (type)); + const mod = require(/** @type {string} */ (type)); + const serverType = mod.default || mod; /** @type {S | undefined} */ From 43dfed2374f625768992eed2043143de6cb07a41 Mon Sep 17 00:00:00 2001 From: Sebastian Beltran Date: Thu, 14 May 2026 19:04:19 -0500 Subject: [PATCH 12/29] fixup! --- test/client/clients/WebsocketClient.test.js | 6 +++--- test/e2e/api.test.js | 6 +++--- test/server/proxy-option.test.js | 4 +--- 3 files changed, 7 insertions(+), 9 deletions(-) diff --git a/test/client/clients/WebsocketClient.test.js b/test/client/clients/WebsocketClient.test.js index b1cbaa8f48..ad60e95c70 100644 --- a/test/client/clients/WebsocketClient.test.js +++ b/test/client/clients/WebsocketClient.test.js @@ -5,7 +5,7 @@ import { after, before, describe, it } from "node:test"; import { expect } from "expect"; import express from "express"; import { spyOn } from "jest-mock"; -import ws from "ws"; +import WebSocket, { WebSocketServer } from "ws"; import WebSocketClient from "../../../client-src/clients/WebSocketClient.js"; import { log } from "../../../client-src/utils/log.js"; import portsMap from "../../ports-map.js"; @@ -15,7 +15,7 @@ import portsMap from "../../ports-map.js"; // against a real local server. Use Node's `ws` library here so this test // can talk to the express+ws server below. WebSocketClient only reads the // global at construction time, so assigning after import is safe. -globalThis.WebSocket = ws; +globalThis.WebSocket = WebSocket; const port = portsMap["web-socket-client"]; @@ -32,7 +32,7 @@ describe("WebsocketClient", () => { server = http.createServer(app); server.listen(port, "localhost", () => { - socketServer = new ws.Server({ + socketServer = new WebSocketServer({ server, path: "/ws-server", }); diff --git a/test/e2e/api.test.js b/test/e2e/api.test.js index c29a9a5bdb..b1a0ab6b4f 100644 --- a/test/e2e/api.test.js +++ b/test/e2e/api.test.js @@ -1,12 +1,12 @@ import path from "node:path"; -import { fileURLToPath } from "node:url"; import { afterEach, beforeEach, describe, it, mock } from "node:test"; +import { fileURLToPath } from "node:url"; import { expect } from "expect"; import { fn } from "jest-mock"; import webpack from "webpack"; import Server from "../../lib/Server.js"; import config from "../fixtures/client-config/webpack.config.js"; -import runBrowser from "../helpers/run-browser.js"; +import runBrowser, { runPage } from "../helpers/run-browser.js"; import sessionSubscribe from "../helpers/session-subscribe.js"; import portsMap from "../ports-map.js"; @@ -246,7 +246,7 @@ describe("API", () => { await server.start(); - const secondPage = await runBrowser.runPage(browser); + const secondPage = await runPage(browser); try { const secondPageErrors = []; diff --git a/test/server/proxy-option.test.js b/test/server/proxy-option.test.js index 0e56837641..9cbcb82268 100644 --- a/test/server/proxy-option.test.js +++ b/test/server/proxy-option.test.js @@ -6,15 +6,13 @@ import { expect } from "expect"; import { spyOn } from "jest-mock"; import request from "supertest"; import webpack from "webpack"; -import WebSocket from "ws"; +import WebSocket, { WebSocketServer } from "ws"; import Server from "../../lib/Server.js"; import config from "../fixtures/proxy-config/webpack.config.js"; import portsMap from "../ports-map.js"; const __dirname = path.dirname(fileURLToPath(import.meta.url)); -const WebSocketServer = WebSocket.Server; - const [port1, port2, port3, port4] = portsMap["proxy-option"]; const staticDirectory = path.resolve(__dirname, "../fixtures/proxy-config"); From 010b741c3f6a4752ea3f624fd8ac72e80951ee28 Mon Sep 17 00:00:00 2001 From: Sebastian Beltran Date: Thu, 14 May 2026 19:10:54 -0500 Subject: [PATCH 13/29] fixup! --- client-src/clients/WebSocketClient.js | 2 +- client-src/globals.d.ts | 2 +- client-src/overlay.js | 2 +- client-src/utils/sendMessage.js | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/client-src/clients/WebSocketClient.js b/client-src/clients/WebSocketClient.js index de7e0ea6a1..b9d1711031 100644 --- a/client-src/clients/WebSocketClient.js +++ b/client-src/clients/WebSocketClient.js @@ -1,6 +1,6 @@ import { log } from "../utils/log.js"; -/** @typedef {import("../index").EXPECTED_ANY} EXPECTED_ANY */ +/** @typedef {import("../index.js").EXPECTED_ANY} EXPECTED_ANY */ /** * @implements {CommunicationClient} diff --git a/client-src/globals.d.ts b/client-src/globals.d.ts index a6aeff9c99..bdf8a44f49 100644 --- a/client-src/globals.d.ts +++ b/client-src/globals.d.ts @@ -20,5 +20,5 @@ declare module "ansi-html-community" { function setColors(colors: Record): void; } - export = ansiHtmlCommunity; + export default ansiHtmlCommunity; } diff --git a/client-src/overlay.js b/client-src/overlay.js index 0de01e9834..7eb7726302 100644 --- a/client-src/overlay.js +++ b/client-src/overlay.js @@ -3,7 +3,7 @@ import ansiHTML from "ansi-html-community"; -/** @typedef {import("./index").EXPECTED_ANY} EXPECTED_ANY */ +/** @typedef {import("./index.js").EXPECTED_ANY} EXPECTED_ANY */ /** * @type {(input: string, position: number) => number | undefined} diff --git a/client-src/utils/sendMessage.js b/client-src/utils/sendMessage.js index 3da67069e0..4e4e7dc793 100644 --- a/client-src/utils/sendMessage.js +++ b/client-src/utils/sendMessage.js @@ -1,6 +1,6 @@ /* global WorkerGlobalScope */ -/** @typedef {import("../index").EXPECTED_ANY} EXPECTED_ANY */ +/** @typedef {import("../index.js").EXPECTED_ANY} EXPECTED_ANY */ // Send messages to the outside, so plugins can consume it. /** From 3b30cf46c4f47df0c2a8acb1ff07dd29cffa0fe2 Mon Sep 17 00:00:00 2001 From: Sebastian Beltran Date: Thu, 14 May 2026 19:46:39 -0500 Subject: [PATCH 14/29] refactor: improve lazy loading of webpack peer dependency and update addAdditionalEntries to async --- lib/Server.js | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/lib/Server.js b/lib/Server.js index f1ac9cd803..bd05c3d07a 100644 --- a/lib/Server.js +++ b/lib/Server.js @@ -10,12 +10,18 @@ import schema from "./options.json" with { type: "json" }; const require = createRequire(import.meta.url); -/** @type {typeof import("webpack") | undefined} */ +/** @type {Promise | undefined} */ let webpackPeer; -try { - webpackPeer = (await import("webpack")).default; -} catch { - // webpack is an optional peer dependency + +/** + * Lazily load the optional `webpack` peer dependency. + * @returns {Promise} resolved webpack module, or undefined when not installed + */ +function loadWebpackPeer() { + webpackPeer ??= import("webpack") + .then((m) => m.default) + .catch(() => undefined); + return webpackPeer; } /** @typedef {import("schema-utils").Schema} Schema */ @@ -575,8 +581,9 @@ class Server { /** * @private * @param {Compiler} compiler compiler + * @returns {Promise} */ - addAdditionalEntries(compiler) { + async addAdditionalEntries(compiler) { /** * @type {string[]} */ @@ -749,7 +756,9 @@ class Server { const webpack = compiler.webpack || - /** @type {NonNullable} */ (webpackPeer); + /** @type {NonNullable>>} */ ( + await loadWebpackPeer() + ); // use a hook to add entries if available for (const additionalEntry of additionalEntries) { @@ -1660,11 +1669,13 @@ class Server { continue; } - this.addAdditionalEntries(compiler); + await this.addAdditionalEntries(compiler); const webpack = compiler.webpack || - /** @type {NonNullable} */ (webpackPeer); + /** @type {NonNullable>>} */ ( + await loadWebpackPeer() + ); new webpack.ProvidePlugin({ __webpack_dev_server_client__: this.getClientTransport(), From 05a27ecf1c846458dd5bea54c867499ad8789829 Mon Sep 17 00:00:00 2001 From: Sebastian Beltran Date: Thu, 14 May 2026 19:58:47 -0500 Subject: [PATCH 15/29] fixup! --- eslint.config.mjs | 5 ++ test/client/socket-helper.test.js | 4 +- test/e2e/hot-and-live-reload.test.js | 20 ++++-- test/e2e/server-and-client-transport.test.js | 8 ++- .../webpack.config.js | 3 +- .../webpack.config.js | 3 +- .../webpack.config.js | 3 +- .../webpack.config.js | 3 +- .../mime-types-config/webpack.config.js | 3 +- test/server/proxy-option.test.js | 2 +- test/validate-options.test.js | 64 +++++++++++-------- 11 files changed, 76 insertions(+), 42 deletions(-) diff --git a/eslint.config.mjs b/eslint.config.mjs index 6d19bb4671..d1f1a38253 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -26,6 +26,11 @@ export default defineConfig([ { files: ["test/**/*"], extends: [configs["universal-recommended"]], + languageOptions: { + // ES2025 needed so `import/*` rules can parse lib/Server.js (uses + // import attributes). eslint-config-webpack pins ecmaVersion to 2024. + ecmaVersion: "latest", + }, rules: { // Tests use experimental node:test APIs intentionally // (mock.module, mock.timers, snapshot.*). The package's engines field diff --git a/test/client/socket-helper.test.js b/test/client/socket-helper.test.js index e7b496b859..a8371a5546 100644 --- a/test/client/socket-helper.test.js +++ b/test/client/socket-helper.test.js @@ -74,7 +74,9 @@ describe("socket", () => { globalThis.__webpack_dev_server_client__ = MockClient; const socket = ( - await import(`../../client-src/socket.js?t=${Date.now()}-${Math.random()}`) + await import( + `../../client-src/socket.js?t=${Date.now()}-${Math.random()}` + ) ).default; const mockHandler = fn(); diff --git a/test/e2e/hot-and-live-reload.test.js b/test/e2e/hot-and-live-reload.test.js index 422a540286..2fd17195e0 100644 --- a/test/e2e/hot-and-live-reload.test.js +++ b/test/e2e/hot-and-live-reload.test.js @@ -166,7 +166,9 @@ describe("hot and live reload", () => { webpackOptions: { entry: [ fileURLToPath(import.meta.resolve("../../client-src/index.js")), - fileURLToPath(import.meta.resolve("../fixtures/reload-config/foo.js")), + fileURLToPath( + import.meta.resolve("../fixtures/reload-config/foo.js"), + ), ], }, options: { @@ -183,7 +185,9 @@ describe("hot and live reload", () => { entry: [ "webpack/hot/dev-server", `${fileURLToPath(import.meta.resolve("../../client-src/index.js"))}?hot=true`, - fileURLToPath(import.meta.resolve("../fixtures/reload-config/foo.js")), + fileURLToPath( + import.meta.resolve("../fixtures/reload-config/foo.js"), + ), ], plugins: [ new webpack.HotModuleReplacementPlugin(), @@ -202,7 +206,9 @@ describe("hot and live reload", () => { webpackOptions: { entry: [ `${fileURLToPath(import.meta.resolve("../../client-src/index.js"))}?hot=false`, - fileURLToPath(import.meta.resolve("../fixtures/reload-config/foo.js")), + fileURLToPath( + import.meta.resolve("../fixtures/reload-config/foo.js"), + ), ], }, options: { @@ -217,7 +223,9 @@ describe("hot and live reload", () => { webpackOptions: { entry: [ `${fileURLToPath(import.meta.resolve("../../client-src/index.js"))}?live-reload=true`, - fileURLToPath(import.meta.resolve("../fixtures/reload-config/foo.js")), + fileURLToPath( + import.meta.resolve("../fixtures/reload-config/foo.js"), + ), ], }, options: { @@ -232,7 +240,9 @@ describe("hot and live reload", () => { webpackOptions: { entry: [ `${fileURLToPath(import.meta.resolve("../../client-src/index.js"))}?live-reload=false`, - fileURLToPath(import.meta.resolve("../fixtures/reload-config/foo.js")), + fileURLToPath( + import.meta.resolve("../fixtures/reload-config/foo.js"), + ), ], }, options: { diff --git a/test/e2e/server-and-client-transport.test.js b/test/e2e/server-and-client-transport.test.js index 553fa8eff2..5e7f1e7542 100644 --- a/test/e2e/server-and-client-transport.test.js +++ b/test/e2e/server-and-client-transport.test.js @@ -203,7 +203,9 @@ describe("server and client transport", () => { client: { webSocketTransport: "ws", }, - webSocketServer: fileURLToPath(import.meta.resolve("../../lib/servers/WebsocketServer.js")), + webSocketServer: fileURLToPath( + import.meta.resolve("../../lib/servers/WebsocketServer.js"), + ), }; const server = new Server(devServerOptions, compiler); @@ -242,7 +244,9 @@ describe("server and client transport", () => { webSocketTransport: "ws", }, webSocketServer: { - type: fileURLToPath(import.meta.resolve("../../lib/servers/WebsocketServer.js")), + type: fileURLToPath( + import.meta.resolve("../../lib/servers/WebsocketServer.js"), + ), }, }; const server = new Server(devServerOptions, compiler); diff --git a/test/fixtures/historyapifallback-3-config/webpack.config.js b/test/fixtures/historyapifallback-3-config/webpack.config.js index 635fb6ad4c..62cc3f85e0 100644 --- a/test/fixtures/historyapifallback-3-config/webpack.config.js +++ b/test/fixtures/historyapifallback-3-config/webpack.config.js @@ -1,7 +1,8 @@ import path from "node:path"; import { fileURLToPath } from "node:url"; -const __dirname = path.dirname(fileURLToPath(import.meta.url));const moduleRuleForHTML = { +const __dirname = path.dirname(fileURLToPath(import.meta.url)); +const moduleRuleForHTML = { test: /\.html$/, type: "asset/resource", generator: { diff --git a/test/fixtures/historyapifallback-config/webpack.config.js b/test/fixtures/historyapifallback-config/webpack.config.js index 03f0045481..40e845bb1d 100644 --- a/test/fixtures/historyapifallback-config/webpack.config.js +++ b/test/fixtures/historyapifallback-config/webpack.config.js @@ -1,7 +1,8 @@ import path from "node:path"; import { fileURLToPath } from "node:url"; -const __dirname = path.dirname(fileURLToPath(import.meta.url));const moduleRuleForHTML = { +const __dirname = path.dirname(fileURLToPath(import.meta.url)); +const moduleRuleForHTML = { test: /\.html$/, type: "asset/resource", generator: { diff --git a/test/fixtures/lazy-compilation-multiple-entries/webpack.config.js b/test/fixtures/lazy-compilation-multiple-entries/webpack.config.js index f3ce49d37b..7c699a32b0 100644 --- a/test/fixtures/lazy-compilation-multiple-entries/webpack.config.js +++ b/test/fixtures/lazy-compilation-multiple-entries/webpack.config.js @@ -1,7 +1,8 @@ import path from "node:path"; import { fileURLToPath } from "node:url"; -const __dirname = path.dirname(fileURLToPath(import.meta.url));const oneHTMLContent = ` +const __dirname = path.dirname(fileURLToPath(import.meta.url)); +const oneHTMLContent = ` diff --git a/test/fixtures/lazy-compilation-single-entry/webpack.config.js b/test/fixtures/lazy-compilation-single-entry/webpack.config.js index 9222f6e6da..9bbbe3c7f4 100644 --- a/test/fixtures/lazy-compilation-single-entry/webpack.config.js +++ b/test/fixtures/lazy-compilation-single-entry/webpack.config.js @@ -1,7 +1,8 @@ import path from "node:path"; import { fileURLToPath } from "node:url"; -const __dirname = path.dirname(fileURLToPath(import.meta.url));const HTMLContent = ` +const __dirname = path.dirname(fileURLToPath(import.meta.url)); +const HTMLContent = ` diff --git a/test/fixtures/mime-types-config/webpack.config.js b/test/fixtures/mime-types-config/webpack.config.js index 0dcbb43634..c1ef4a1520 100644 --- a/test/fixtures/mime-types-config/webpack.config.js +++ b/test/fixtures/mime-types-config/webpack.config.js @@ -1,7 +1,8 @@ import path from "node:path"; import { fileURLToPath } from "node:url"; -const __dirname = path.dirname(fileURLToPath(import.meta.url));const moduleRuleForCustom = { +const __dirname = path.dirname(fileURLToPath(import.meta.url)); +const moduleRuleForCustom = { test: /\.custom$/, type: "asset/resource", generator: { diff --git a/test/server/proxy-option.test.js b/test/server/proxy-option.test.js index 9cbcb82268..e5c1e6b5d7 100644 --- a/test/server/proxy-option.test.js +++ b/test/server/proxy-option.test.js @@ -1,8 +1,8 @@ import path from "node:path"; import { after, before, beforeEach, describe, it } from "node:test"; import { fileURLToPath } from "node:url"; -import express from "express"; import { expect } from "expect"; +import express from "express"; import { spyOn } from "jest-mock"; import request from "supertest"; import webpack from "webpack"; diff --git a/test/validate-options.test.js b/test/validate-options.test.js index 312860ac3c..4fe34a9bf6 100644 --- a/test/validate-options.test.js +++ b/test/validate-options.test.js @@ -274,18 +274,18 @@ const tests = { { type: "https", options: { - ca: fs.readFileSync( - path.join(httpsCertificateDirectory, "ca.pem"), - ).toString(), - pfx: fs.readFileSync( - path.join(httpsCertificateDirectory, "server.pfx"), - ).toString(), - key: fs.readFileSync( - path.join(httpsCertificateDirectory, "server.key"), - ).toString(), - cert: fs.readFileSync( - path.join(httpsCertificateDirectory, "server.crt"), - ).toString(), + ca: fs + .readFileSync(path.join(httpsCertificateDirectory, "ca.pem")) + .toString(), + pfx: fs + .readFileSync(path.join(httpsCertificateDirectory, "server.pfx")) + .toString(), + key: fs + .readFileSync(path.join(httpsCertificateDirectory, "server.key")) + .toString(), + cert: fs + .readFileSync(path.join(httpsCertificateDirectory, "server.crt")) + .toString(), passphrase: "webpack-dev-server", }, }, @@ -293,24 +293,24 @@ const tests = { type: "https", options: { ca: [ - fs.readFileSync( - path.join(httpsCertificateDirectory, "ca.pem"), - ).toString(), + fs + .readFileSync(path.join(httpsCertificateDirectory, "ca.pem")) + .toString(), ], pfx: [ - fs.readFileSync( - path.join(httpsCertificateDirectory, "server.pfx"), - ).toString(), + fs + .readFileSync(path.join(httpsCertificateDirectory, "server.pfx")) + .toString(), ], key: [ - fs.readFileSync( - path.join(httpsCertificateDirectory, "server.key"), - ).toString(), + fs + .readFileSync(path.join(httpsCertificateDirectory, "server.key")) + .toString(), ], cert: [ - fs.readFileSync( - path.join(httpsCertificateDirectory, "server.crt"), - ).toString(), + fs + .readFileSync(path.join(httpsCertificateDirectory, "server.crt")) + .toString(), ], passphrase: "webpack-dev-server", }, @@ -319,8 +319,12 @@ const tests = { 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")), + pfx: fs.readFileSync( + path.join(httpsCertificateDirectory, "server.pfx"), + ), + key: fs.readFileSync( + path.join(httpsCertificateDirectory, "server.key"), + ), cert: fs.readFileSync( path.join(httpsCertificateDirectory, "server.crt"), ), @@ -359,8 +363,12 @@ const tests = { options: { minVersion: "TLSv1.1", ca: fs.readFileSync(path.join(httpsCertificateDirectory, "ca.pem")), - pfx: fs.readFileSync(path.join(httpsCertificateDirectory, "server.pfx")), - key: fs.readFileSync(path.join(httpsCertificateDirectory, "server.key")), + pfx: fs.readFileSync( + path.join(httpsCertificateDirectory, "server.pfx"), + ), + key: fs.readFileSync( + path.join(httpsCertificateDirectory, "server.key"), + ), cert: fs.readFileSync( path.join(httpsCertificateDirectory, "server.crt"), ), From 4aaecfc4543f1265427c8e02576e51806edfe9e1 Mon Sep 17 00:00:00 2001 From: Sebastian Beltran Date: Thu, 14 May 2026 20:05:01 -0500 Subject: [PATCH 16/29] refactor: update lazy initialization of webpack dev middleware to async --- lib/Server.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/Server.js b/lib/Server.js index bd05c3d07a..e3d35ad8e5 100644 --- a/lib/Server.js +++ b/lib/Server.js @@ -2352,13 +2352,13 @@ class Server { middlewares = this.options.setupMiddlewares(middlewares, this); } - const { default: webpackDevMiddleware } = await import( - "webpack-dev-middleware" - ); - // Lazy init webpack dev middleware - const lazyInitDevMiddleware = () => { + const lazyInitDevMiddleware = async () => { if (!this.middleware) { + const { default: webpackDevMiddleware } = await import( + "webpack-dev-middleware" + ); + // middleware for serving webpack bundle /** @type {import("webpack-dev-middleware").API} */ this.middleware = webpackDevMiddleware( @@ -2375,7 +2375,7 @@ class Server { const item = /** @type {MiddlewareObject} */ (i); if (typeof item.middleware === "undefined") { - item.middleware = lazyInitDevMiddleware(); + item.middleware = await lazyInitDevMiddleware(); } } } From c705bef1463f484c6938d6226eaad1476e0f02e9 Mon Sep 17 00:00:00 2001 From: Sebastian Beltran Date: Thu, 14 May 2026 20:14:18 -0500 Subject: [PATCH 17/29] refactor: update TypeScript configuration to target ES2024 and improve type definitions --- tsconfig.json | 5 ++--- types/lib/Server.d.ts | 1 + 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tsconfig.json b/tsconfig.json index f8f19ec5cb..8e5e60299a 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,15 +1,14 @@ { "compilerOptions": { - "target": "ES2022", + "target": "ES2024", "module": "nodenext", "moduleResolution": "nodenext", - "lib": ["es2022", "dom"], + "lib": ["es2024", "dom"], "allowJs": true, "checkJs": true, "strict": true, "types": ["node"], "resolveJsonModule": true, - "allowSyntheticDefaultImports": true, "esModuleInterop": true }, "include": ["./bin/**/*", "./lib/**/*"] diff --git a/types/lib/Server.d.ts b/types/lib/Server.d.ts index 678da2b5b1..f963e8be60 100644 --- a/types/lib/Server.d.ts +++ b/types/lib/Server.d.ts @@ -1535,6 +1535,7 @@ declare class Server< /** * @private * @param {Compiler} compiler compiler + * @returns {Promise} */ private addAdditionalEntries; /** From 1f97c8890a67dbcf90033db93c4cee82e60aa9ae Mon Sep 17 00:00:00 2001 From: Sebastian Beltran Date: Thu, 14 May 2026 20:21:43 -0500 Subject: [PATCH 18/29] fixup! --- test/cli/basic.test.js | 2 +- test/cli/server-option.test.js | 2 +- test/cli/watchFiles-option.test.js | 2 +- test/e2e/entry.test.js | 2 +- test/e2e/history-api-fallback.test.js | 2 +- test/e2e/logging.test.js | 2 +- test/e2e/multi-compiler.test.js | 2 +- test/e2e/overlay.test.js | 124 +++++++++++++------------- test/e2e/progress.test.js | 2 +- test/e2e/server.test.js | 2 +- test/e2e/static-directory.test.js | 2 +- test/e2e/static-public-path.test.js | 2 +- test/e2e/target.test.js | 2 +- test/e2e/watch-files.test.js | 2 +- 14 files changed, 75 insertions(+), 75 deletions(-) diff --git a/test/cli/basic.test.js b/test/cli/basic.test.js index b5c851721c..988b020884 100644 --- a/test/cli/basic.test.js +++ b/test/cli/basic.test.js @@ -1,6 +1,6 @@ import path from "node:path"; -import { fileURLToPath } from "node:url"; import { describe, it } from "node:test"; +import { fileURLToPath } from "node:url"; import util from "node:util"; import execa from "execa"; import { expect } from "expect"; diff --git a/test/cli/server-option.test.js b/test/cli/server-option.test.js index 11b8fee83f..fa6902fd62 100644 --- a/test/cli/server-option.test.js +++ b/test/cli/server-option.test.js @@ -1,6 +1,6 @@ import path from "node:path"; -import { fileURLToPath } from "node:url"; import { beforeEach, describe, it } from "node:test"; +import { fileURLToPath } from "node:url"; import { expect } from "expect"; import { rimraf } from "rimraf"; import Server from "../../lib/Server.js"; diff --git a/test/cli/watchFiles-option.test.js b/test/cli/watchFiles-option.test.js index 63de599754..c5cf49d289 100644 --- a/test/cli/watchFiles-option.test.js +++ b/test/cli/watchFiles-option.test.js @@ -1,6 +1,6 @@ import path from "node:path"; -import { fileURLToPath } from "node:url"; import { describe, it } from "node:test"; +import { fileURLToPath } from "node:url"; import { expect } from "expect"; import { normalizeStderr, testBin } from "../helpers/test-bin.js"; import portsMap from "../ports-map.js"; diff --git a/test/e2e/entry.test.js b/test/e2e/entry.test.js index 061d436d0d..e8f488e2b0 100644 --- a/test/e2e/entry.test.js +++ b/test/e2e/entry.test.js @@ -1,6 +1,6 @@ import path from "node:path"; -import { fileURLToPath } from "node:url"; import { describe, it } from "node:test"; +import { fileURLToPath } from "node:url"; import webpack from "webpack"; import Server from "../../lib/Server.js"; diff --git a/test/e2e/history-api-fallback.test.js b/test/e2e/history-api-fallback.test.js index 309e9111c9..b60401cf48 100644 --- a/test/e2e/history-api-fallback.test.js +++ b/test/e2e/history-api-fallback.test.js @@ -1,6 +1,6 @@ import path from "node:path"; -import { fileURLToPath } from "node:url"; import { afterEach, beforeEach, describe, it } from "node:test"; +import { fileURLToPath } from "node:url"; import { expect } from "expect"; import { spyOn } from "jest-mock"; import webpack from "webpack"; diff --git a/test/e2e/logging.test.js b/test/e2e/logging.test.js index deb97fc273..33457fb8ab 100644 --- a/test/e2e/logging.test.js +++ b/test/e2e/logging.test.js @@ -1,6 +1,6 @@ import path from "node:path"; -import { fileURLToPath } from "node:url"; import { describe, it } from "node:test"; +import { fileURLToPath } from "node:url"; import fs from "graceful-fs"; import webpack from "webpack"; diff --git a/test/e2e/multi-compiler.test.js b/test/e2e/multi-compiler.test.js index 8d793d2f42..34a5e2eff4 100644 --- a/test/e2e/multi-compiler.test.js +++ b/test/e2e/multi-compiler.test.js @@ -1,6 +1,6 @@ import path from "node:path"; -import { fileURLToPath } from "node:url"; import { describe, it } from "node:test"; +import { fileURLToPath } from "node:url"; import { expect } from "expect"; import fs from "graceful-fs"; import webpack from "webpack"; diff --git a/test/e2e/overlay.test.js b/test/e2e/overlay.test.js index 59f1e83240..61c4329881 100644 --- a/test/e2e/overlay.test.js +++ b/test/e2e/overlay.test.js @@ -1,10 +1,10 @@ import path from "node:path"; -import { fileURLToPath } from "node:url"; import { describe, it, mock } from "node:test"; +import { fileURLToPath } from "node:url"; import { expect } from "expect"; import fs from "graceful-fs"; import { fn } from "jest-mock"; -import prettier from "prettier"; +import { format } from "prettier"; import waitForExpect from "wait-for-expect"; import webpack from "webpack"; import Server from "../../lib/Server.js"; @@ -105,12 +105,12 @@ describe("overlay", () => { ); t.assert.snapshot( - await prettier.format(pageHtml, { + await format(pageHtml, { parser: "html", }), ); t.assert.snapshot( - await prettier.format(overlayHtml, { + await format(overlayHtml, { parser: "html", }), ); @@ -150,12 +150,12 @@ describe("overlay", () => { ); t.assert.snapshot( - await prettier.format(pageHtml, { + await format(pageHtml, { parser: "html", }), ); t.assert.snapshot( - await prettier.format(overlayHtml, { + await format(overlayHtml, { parser: "html", }), ); @@ -199,12 +199,12 @@ describe("overlay", () => { ); t.assert.snapshot( - await prettier.format(pageHtml, { + await format(pageHtml, { parser: "html", }), ); t.assert.snapshot( - await prettier.format(overlayHtml, { + await format(overlayHtml, { parser: "html", }), ); @@ -246,12 +246,12 @@ describe("overlay", () => { ); t.assert.snapshot( - await prettier.format(pageHtml, { + await format(pageHtml, { parser: "html", }), ); t.assert.snapshot( - await prettier.format(overlayHtml, { + await format(overlayHtml, { parser: "html", }), ); @@ -292,12 +292,12 @@ describe("overlay", () => { ); t.assert.snapshot( - await prettier.format(pageHtml, { + await format(pageHtml, { parser: "html", }), ); t.assert.snapshot( - await prettier.format(overlayHtml, { + await format(overlayHtml, { parser: "html", }), ); @@ -328,7 +328,7 @@ describe("overlay", () => { expect(overlayHandle).toBeNull(); t.assert.snapshot( - await prettier.format(pageHtml, { + await format(pageHtml, { parser: "html", }), ); @@ -352,12 +352,12 @@ describe("overlay", () => { ); t.assert.snapshot( - await prettier.format(pageHtml, { + await format(pageHtml, { parser: "html", }), ); t.assert.snapshot( - await prettier.format(overlayHtml, { + await format(overlayHtml, { parser: "html", }), ); @@ -373,7 +373,7 @@ describe("overlay", () => { expect(overlayHandle).toBeNull(); t.assert.snapshot( - await prettier.format(pageHtml, { + await format(pageHtml, { parser: "html", }), ); @@ -404,7 +404,7 @@ describe("overlay", () => { expect(overlayHandle).toBeNull(); t.assert.snapshot( - await prettier.format(pageHtml, { + await format(pageHtml, { parser: "html", }), ); @@ -428,12 +428,12 @@ describe("overlay", () => { ); t.assert.snapshot( - await prettier.format(pageHtml, { + await format(pageHtml, { parser: "html", }), ); t.assert.snapshot( - await prettier.format(overlayHtml, { + await format(overlayHtml, { parser: "html", }), ); @@ -452,12 +452,12 @@ describe("overlay", () => { overlayHtml = await overlayFrame.evaluate(() => document.body.outerHTML); t.assert.snapshot( - await prettier.format(pageHtml, { + await format(pageHtml, { parser: "html", }), ); t.assert.snapshot( - await prettier.format(overlayHtml, { + await format(overlayHtml, { parser: "html", }), ); @@ -473,7 +473,7 @@ describe("overlay", () => { expect(overlayHandle).toBeNull(); t.assert.snapshot( - await prettier.format(pageHtml, { + await format(pageHtml, { parser: "html", }), ); @@ -504,7 +504,7 @@ describe("overlay", () => { expect(overlayHandle).toBeNull(); t.assert.snapshot( - await prettier.format(pageHtml, { + await format(pageHtml, { parser: "html", }), ); @@ -528,12 +528,12 @@ describe("overlay", () => { ); t.assert.snapshot( - await prettier.format(pageHtml, { + await format(pageHtml, { parser: "html", }), ); t.assert.snapshot( - await prettier.format(overlayHtml, { + await format(overlayHtml, { parser: "html", }), ); @@ -555,7 +555,7 @@ describe("overlay", () => { expect(overlayHandle).toBeNull(); t.assert.snapshot( - await prettier.format(pageHtml, { + await format(pageHtml, { parser: "html", }), ); @@ -648,7 +648,7 @@ describe("overlay", () => { expect(overlayHandle).toBeNull(); t.assert.snapshot( - await prettier.format(pageHtml, { + await format(pageHtml, { parser: "html", }), ); @@ -690,7 +690,7 @@ describe("overlay", () => { expect(overlayHandle).toBeNull(); t.assert.snapshot( - await prettier.format(pageHtml, { + await format(pageHtml, { parser: "html", }), ); @@ -779,12 +779,12 @@ describe("overlay", () => { ); t.assert.snapshot( - await prettier.format(pageHtml, { + await format(pageHtml, { parser: "html", }), ); t.assert.snapshot( - await prettier.format(overlayHtml, { + await format(overlayHtml, { parser: "html", }), ); @@ -827,12 +827,12 @@ describe("overlay", () => { ); t.assert.snapshot( - await prettier.format(pageHtml, { + await format(pageHtml, { parser: "html", }), ); t.assert.snapshot( - await prettier.format(overlayHtml, { + await format(overlayHtml, { parser: "html", }), ); @@ -877,12 +877,12 @@ describe("overlay", () => { ); t.assert.snapshot( - await prettier.format(pageHtml, { + await format(pageHtml, { parser: "html", }), ); t.assert.snapshot( - await prettier.format(overlayHtml, { + await format(overlayHtml, { parser: "html", }), ); @@ -927,12 +927,12 @@ describe("overlay", () => { ); t.assert.snapshot( - await prettier.format(pageHtml, { + await format(pageHtml, { parser: "html", }), ); t.assert.snapshot( - await prettier.format(overlayHtml, { + await format(overlayHtml, { parser: "html", }), ); @@ -972,7 +972,7 @@ describe("overlay", () => { expect(overlayHandle).toBeNull(); t.assert.snapshot( - await prettier.format(pageHtml, { + await format(pageHtml, { parser: "html", }), ); @@ -1014,7 +1014,7 @@ describe("overlay", () => { expect(overlayHandle).toBeNull(); t.assert.snapshot( - await prettier.format(pageHtml, { + await format(pageHtml, { parser: "html", }), ); @@ -1104,12 +1104,12 @@ describe("overlay", () => { ); t.assert.snapshot( - await prettier.format(pageHtml, { + await format(pageHtml, { parser: "html", }), ); t.assert.snapshot( - await prettier.format(overlayHtml, { + await format(overlayHtml, { parser: "html", }), ); @@ -1152,12 +1152,12 @@ describe("overlay", () => { ); t.assert.snapshot( - await prettier.format(pageHtml, { + await format(pageHtml, { parser: "html", }), ); t.assert.snapshot( - await prettier.format(overlayHtml, { + await format(overlayHtml, { parser: "html", }), ); @@ -1213,12 +1213,12 @@ describe("overlay", () => { ), ).toHaveLength(0); t.assert.snapshot( - await prettier.format(pageHtml, { + await format(pageHtml, { parser: "html", }), ); t.assert.snapshot( - await prettier.format(overlayHtml, { + await format(overlayHtml, { parser: "html", }), ); @@ -1284,12 +1284,12 @@ describe("overlay", () => { ), ).toHaveLength(0); t.assert.snapshot( - await prettier.format(pageHtml, { + await format(pageHtml, { parser: "html", }), ); t.assert.snapshot( - await prettier.format(overlayHtml, { + await format(overlayHtml, { parser: "html", }), ); @@ -1330,7 +1330,7 @@ describe("overlay", () => { const overlayHandle = await page.$("#webpack-dev-server-client-overlay"); expect(overlayHandle).toBeNull(); t.assert.snapshot( - await prettier.format(pageHtml, { + await format(pageHtml, { parser: "html", }), ); @@ -1375,12 +1375,12 @@ describe("overlay", () => { ); t.assert.snapshot( - await prettier.format(pageHtml, { + await format(pageHtml, { parser: "html", }), ); t.assert.snapshot( - await prettier.format(overlayHtml, { + await format(overlayHtml, { parser: "html", }), ); @@ -1425,12 +1425,12 @@ describe("overlay", () => { ); t.assert.snapshot( - await prettier.format(pageHtml, { + await format(pageHtml, { parser: "html", }), ); t.assert.snapshot( - await prettier.format(overlayHtml, { + await format(overlayHtml, { parser: "html", }), ); @@ -1474,12 +1474,12 @@ describe("overlay", () => { ); t.assert.snapshot( - await prettier.format(pageHtml, { + await format(pageHtml, { parser: "html", }), ); t.assert.snapshot( - await prettier.format(overlayHtml, { + await format(overlayHtml, { parser: "html", }), ); @@ -1501,7 +1501,7 @@ describe("overlay", () => { ); t.assert.snapshot( - await prettier.format(pageHtmlAfterClose, { + await format(pageHtmlAfterClose, { parser: "html", }), ); @@ -1555,12 +1555,12 @@ describe("overlay", () => { ); t.assert.snapshot( - await prettier.format(pageHtml, { + await format(pageHtml, { parser: "html", }), ); t.assert.snapshot( - await prettier.format(overlayHtml, { + await format(overlayHtml, { parser: "html", }), ); @@ -1614,12 +1614,12 @@ describe("overlay", () => { ); t.assert.snapshot( - await prettier.format(pageHtml, { + await format(pageHtml, { parser: "html", }), ); t.assert.snapshot( - await prettier.format(overlayHtml, { + await format(overlayHtml, { parser: "html", }), ); @@ -1664,7 +1664,7 @@ describe("overlay", () => { ); t.assert.snapshot( - await prettier.format(overlayHtml, { + await format(overlayHtml, { parser: "html", }), ); @@ -1753,7 +1753,7 @@ describe("overlay", () => { ); t.assert.snapshot( - await prettier.format(overlayHtml, { + await format(overlayHtml, { parser: "html", }), ); @@ -1894,12 +1894,12 @@ describe("overlay", () => { ); t.assert.snapshot( - await prettier.format(pageHtml, { + await format(pageHtml, { parser: "html", }), ); t.assert.snapshot( - await prettier.format( + await format( overlayHtml.replace( /", diff --git a/test/e2e/progress.test.js b/test/e2e/progress.test.js index 149839ca64..c6d7d4dfa3 100644 --- a/test/e2e/progress.test.js +++ b/test/e2e/progress.test.js @@ -1,6 +1,6 @@ import path from "node:path"; -import { fileURLToPath } from "node:url"; import { describe, it } from "node:test"; +import { fileURLToPath } from "node:url"; import { expect } from "expect"; import fs from "graceful-fs"; import webpack from "webpack"; diff --git a/test/e2e/server.test.js b/test/e2e/server.test.js index 2cfeaae73d..a2df835d8a 100644 --- a/test/e2e/server.test.js +++ b/test/e2e/server.test.js @@ -1,7 +1,7 @@ import https from "node:https"; import path from "node:path"; -import { fileURLToPath } from "node:url"; import { afterEach, beforeEach, describe, it } from "node:test"; +import { fileURLToPath } from "node:url"; import { expect } from "expect"; import fs from "graceful-fs"; import { spyOn } from "jest-mock"; diff --git a/test/e2e/static-directory.test.js b/test/e2e/static-directory.test.js index a5df7daba7..a970cc2231 100644 --- a/test/e2e/static-directory.test.js +++ b/test/e2e/static-directory.test.js @@ -1,6 +1,6 @@ import path from "node:path"; -import { fileURLToPath } from "node:url"; import { afterEach, beforeEach, describe, it } from "node:test"; +import { fileURLToPath } from "node:url"; import { expect } from "expect"; import fs from "graceful-fs"; import { spyOn } from "jest-mock"; diff --git a/test/e2e/static-public-path.test.js b/test/e2e/static-public-path.test.js index 42f367d0cd..e472a0f0b7 100644 --- a/test/e2e/static-public-path.test.js +++ b/test/e2e/static-public-path.test.js @@ -1,6 +1,6 @@ import path from "node:path"; -import { fileURLToPath } from "node:url"; import { afterEach, beforeEach, describe, it } from "node:test"; +import { fileURLToPath } from "node:url"; import { expect } from "expect"; import { spyOn } from "jest-mock"; import webpack from "webpack"; diff --git a/test/e2e/target.test.js b/test/e2e/target.test.js index 929c62c026..e0578b5beb 100644 --- a/test/e2e/target.test.js +++ b/test/e2e/target.test.js @@ -1,6 +1,6 @@ import path from "node:path"; -import { fileURLToPath } from "node:url"; import { describe, it } from "node:test"; +import { fileURLToPath } from "node:url"; import { expect } from "expect"; import webpack from "webpack"; import Server from "../../lib/Server.js"; diff --git a/test/e2e/watch-files.test.js b/test/e2e/watch-files.test.js index 30110d83af..7eb8f799c0 100644 --- a/test/e2e/watch-files.test.js +++ b/test/e2e/watch-files.test.js @@ -1,6 +1,6 @@ import path from "node:path"; -import { fileURLToPath } from "node:url"; import { afterEach, beforeEach, describe, it } from "node:test"; +import { fileURLToPath } from "node:url"; import { expect } from "expect"; import fs from "graceful-fs"; import webpack from "webpack"; From fdc42164eae3569f9205577809b554c643fbd6cb Mon Sep 17 00:00:00 2001 From: Sebastian Beltran Date: Thu, 14 May 2026 20:37:06 -0500 Subject: [PATCH 19/29] refactor: simplify package installation check using require.resolve --- bin/webpack-dev-server.js | 35 ++++++++--------------------------- 1 file changed, 8 insertions(+), 27 deletions(-) diff --git a/bin/webpack-dev-server.js b/bin/webpack-dev-server.js index 16e76b136b..5e346d2ab4 100755 --- a/bin/webpack-dev-server.js +++ b/bin/webpack-dev-server.js @@ -3,12 +3,14 @@ /* eslint-disable no-console */ import cp from "node:child_process"; -import nodeModule from "node:module"; +import { createRequire } from "node:module"; import path from "node:path"; import readLine from "node:readline"; import { fileURLToPath, pathToFileURL } from "node:url"; import fs from "graceful-fs"; +const require = createRequire(import.meta.url); + /** * @param {string} command process to run * @param {string[]} args command line arguments @@ -43,33 +45,12 @@ const isInstalled = (packageName) => { return true; } - let dir = path.dirname(fileURLToPath(import.meta.url)); - - do { - try { - if ( - fs.statSync(path.join(dir, "node_modules", packageName)).isDirectory() - ) { - return true; - } - } catch { - // Nothing - } - } while (dir !== (dir = path.dirname(dir))); - - // https://github.com/nodejs/node/blob/v22.12.0/lib/internal/modules/cjs/loader.js#L1818 - // @ts-expect-error - for (const internalPath of nodeModule.globalPaths) { - try { - if (fs.statSync(path.join(internalPath, packageName)).isDirectory()) { - return true; - } - } catch { - // Nothing - } + try { + require.resolve(packageName); + return true; + } catch { + return false; } - - return false; }; /** From a6cd73f9fb8b33bc0587556c6d512e214e67cfda Mon Sep 17 00:00:00 2001 From: Sebastian Beltran Date: Thu, 14 May 2026 20:50:41 -0500 Subject: [PATCH 20/29] fix: update Node.js target version in Babel configuration to 22.15.0 --- babel.config.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/babel.config.js b/babel.config.js index 07a5ee415b..49ff61255b 100644 --- a/babel.config.js +++ b/babel.config.js @@ -22,7 +22,7 @@ export default (api) => { "@babel/preset-env", { targets: { - node: "22.25.0", + node: "22.15.0", }, }, ], From 37abbf3a70d15b4e39643daf42e70374e852e6b6 Mon Sep 17 00:00:00 2001 From: Sebastian Beltran Date: Sat, 16 May 2026 10:54:41 -0500 Subject: [PATCH 21/29] fixup! --- client-src/index.js | 2 +- client-src/overlay.js | 20 +- eslint.config.mjs | 14 - lib/Server.js | 26 +- lib/getPort.js | 2 +- package-lock.json | 1308 ++++++++++++++++++++------- package.json | 2 +- scripts/run-tests.mjs | 2 +- test/e2e/options-middleware.test.js | 2 +- test/e2e/target.test.js | 2 +- test/helpers/run-browser.js | 10 +- 11 files changed, 1034 insertions(+), 356 deletions(-) diff --git a/client-src/index.js b/client-src/index.js index 60527ef029..e8a650ea3d 100644 --- a/client-src/index.js +++ b/client-src/index.js @@ -9,7 +9,7 @@ import socket from "./socket.js"; import { log, setLogLevel } from "./utils/log.js"; import sendMessage from "./utils/sendMessage.js"; -// eslint-disable-next-line jsdoc/no-restricted-syntax +// eslint-disable-next-line jsdoc/reject-any-type /** @typedef {any} EXPECTED_ANY */ /** diff --git a/client-src/overlay.js b/client-src/overlay.js index 7eb7726302..db3bdf7227 100644 --- a/client-src/overlay.js +++ b/client-src/overlay.js @@ -79,16 +79,16 @@ function encode(text) { /** * @typedef {object} Context - * @property {'warning' | 'error'} level level - * @property {(string | Message)[]} messages messages - * @property {'build' | 'runtime'} messageSource message source + * @property {"warning" | "error"} level level + * @property {(string | Message)[]} messages messages + * @property {"build" | "runtime"} messageSource message source */ /** @typedef {{ type: string } & Record} Event */ /** * @typedef {object} Options - * @property {{ [state: string]: { on: Record }> } }} states states + * @property {{ [state: string]: { on: Record } }} states states * @property {Context} context context * @property {string} initial initial */ @@ -149,9 +149,9 @@ function createMachine({ states, context, initial }, { actions }) { /** * @typedef {object} ShowOverlayData - * @property {'warning' | 'error'} level level - * @property {(string | Message)[]} messages messages - * @property {'build' | 'runtime'} messageSource message source + * @property {"warning" | "error"} level level + * @property {(string | Message)[]} messages messages + * @property {"build" | "runtime"} messageSource message source */ /** @@ -390,7 +390,7 @@ const colors = { ansiHTML.setColors(colors); -/** @typedef {Error & { file?: string, moduleName?: string, moduleIdentifier?: string, loc?: string, message?: string; stack?: string | string[] }} Message */ +/** @typedef {Error & { file?: string, moduleName?: string, moduleIdentifier?: string, loc?: string, message?: string, stack?: string | string[] }} Message */ /** * @param {string} type type @@ -450,7 +450,7 @@ const createOverlay = (options) => { let containerElement; /** @type {HTMLDivElement | null | undefined} */ let headerElement; - /** @type {Array<(element: HTMLDivElement) => void>} */ + /** @type {(element: HTMLDivElement) => void[]} */ let onLoadQueue = []; /** @type {Omit | undefined} */ let overlayTrustedTypesPolicy; @@ -589,7 +589,7 @@ const createOverlay = (options) => { * @param {string} type type * @param {(string | Message)[]} messages messages * @param {undefined | false | string} trustedTypesPolicyName trusted types policy name - * @param {'build' | 'runtime'} messageSource message source + * @param {"build" | "runtime"} messageSource message source */ function show(type, messages, trustedTypesPolicyName, messageSource) { ensureOverlayExists(() => { diff --git a/eslint.config.mjs b/eslint.config.mjs index d1f1a38253..bb93d5feb3 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -7,11 +7,6 @@ export default defineConfig([ { extends: [config], ignores: ["client-src/**/*", "!client-src/webpack.config.js"], - languageOptions: { - // ES2025 needed for import attributes (`import(x, { with: ... })`). - // eslint-config-webpack pins ecmaVersion to 2024 for Node 22. - ecmaVersion: "latest", - }, rules: { // TODO fix me "prefer-destructuring": "off", @@ -26,16 +21,7 @@ export default defineConfig([ { files: ["test/**/*"], extends: [configs["universal-recommended"]], - languageOptions: { - // ES2025 needed so `import/*` rules can parse lib/Server.js (uses - // import attributes). eslint-config-webpack pins ecmaVersion to 2024. - ecmaVersion: "latest", - }, rules: { - // Tests use experimental node:test APIs intentionally - // (mock.module, mock.timers, snapshot.*). The package's engines field - // is wider than where these are stable, so silence the linter here. - "n/no-unsupported-features/node-builtins": "off", // Test callbacks (it/test/subtest arrow functions) don't need JSDoc. "jsdoc/require-jsdoc": "off", // Tests legitimately log diagnostics (retry attempts, etc.). diff --git a/lib/Server.js b/lib/Server.js index e3d35ad8e5..459dbeb99a 100644 --- a/lib/Server.js +++ b/lib/Server.js @@ -56,7 +56,7 @@ function loadWebpackPeer() { /** @typedef {import("express").Request} ExpressRequest */ /** @typedef {import("express").Response} ExpressResponse */ -// eslint-disable-next-line jsdoc/no-restricted-syntax +// eslint-disable-next-line jsdoc/reject-any-type /** @typedef {any} EXPECTED_ANY */ /** @typedef {(err?: EXPECTED_ANY) => void} NextFunction */ @@ -136,7 +136,7 @@ function loadWebpackPeer() { /** * @typedef {object} WebSocketServerConfiguration - * @property {( "ws" | string | (() => WebSocketServerConfiguration))=} type type + * @property {("ws" | string | (() => WebSocketServerConfiguration))=} type type * @property {Record=} options options */ @@ -153,7 +153,7 @@ function loadWebpackPeer() { */ /** - * @typedef {{ path?: HttpProxyMiddlewareOptionsFilter | undefined, context?: HttpProxyMiddlewareOptionsFilter | undefined } & HttpProxyMiddlewareOptions } ProxyConfigArrayItem + * @typedef {{ path?: HttpProxyMiddlewareOptionsFilter | undefined, context?: HttpProxyMiddlewareOptionsFilter | undefined } & HttpProxyMiddlewareOptions} ProxyConfigArrayItem */ /** @@ -203,7 +203,7 @@ function loadWebpackPeer() { */ /** - * @typedef {Array<{ key: string; value: string }> | Record} Headers + * @typedef {{ key: string, value: string }[] | Record} Headers */ /** @@ -216,7 +216,7 @@ function loadWebpackPeer() { */ /** - * @typedef {MiddlewareObject | MiddlewareHandler } Middleware + * @typedef {MiddlewareObject | MiddlewareHandler} Middleware */ /** @typedef {import("net").Server | import("tls").Server} BasicServer */ @@ -235,13 +235,13 @@ function loadWebpackPeer() { * @property {("auto" | "all" | string | string[])=} allowedHosts * @property {(boolean | ConnectHistoryApiFallbackOptions)=} historyApiFallback * @property {(boolean | Record | BonjourOptions)=} bonjour - * @property {(string | string[] | WatchFiles | Array)=} watchFiles - * @property {(boolean | string | Static | Array)=} static + * @property {(string | string[] | WatchFiles | (string | WatchFiles)[])=} watchFiles + * @property {(boolean | string | Static | (string | Static)[])=} static * @property {(ServerType | ServerConfiguration)=} server * @property {(() => Promise)=} app * @property {(boolean | "ws" | string | WebSocketServerConfiguration)=} webSocketServer * @property {ProxyConfigArray=} proxy - * @property {(boolean | string | Open | Array)=} open + * @property {(boolean | string | Open | (string | Open)[])=} open * @property {boolean=} setupExitSignals * @property {(boolean | ClientConfiguration)=} client * @property {(Headers | ((req: Request, res: Response, context: DevMiddlewareContext | undefined) => Headers))=} headers @@ -354,7 +354,7 @@ class Server { this.staticWatchers = []; /** * @private - * @type {{ name: string | symbol, listener: (...args: EXPECTED_ANY[]) => void}[] }} + * @type {{ name: string | symbol, listener: (...args: EXPECTED_ANY[]) => void }[]} } */ this.listeners = []; // Keep track of websocket proxies for external websocket upgrade. @@ -1074,7 +1074,7 @@ class Server { } const httpsProperties = - /** @type {Array} */ + /** @type {keyof ServerOptions[]} */ (["ca", "cert", "crl", "key", "pfx"]); for (const property_ of httpsProperties) { @@ -1439,7 +1439,7 @@ class Server { } /** - * @returns { { isColorSupported: () => boolean, colors: import("webpack").Colors } } colors support + * @returns {{ isColorSupported: () => boolean, colors: import("webpack").Colors }} colors support */ #getColors() { const compilerOptions = @@ -1868,7 +1868,7 @@ class Server { */ async setupMiddlewares() { /** - * @type {Array} + * @type {Middleware[]} */ let middlewares = []; @@ -3000,7 +3000,7 @@ class Server { /** * Extracts and normalizes the hostname from a header, removing brackets for IPv6. * @param {string} header header value - * @returns {string|null} hostname or null + * @returns {string | null} hostname or null */ #parseHostnameFromHeader = function (header) { if (!header) return null; diff --git a/lib/getPort.js b/lib/getPort.js index 032e41f31b..bb44cddb02 100644 --- a/lib/getPort.js +++ b/lib/getPort.js @@ -56,7 +56,7 @@ const checkAvailablePort = (basePort, host) => /** * @param {number} port port - * @param {Set} hosts hosts + * @param {Set} hosts hosts * @returns {Promise} resolved port */ const getAvailablePort = async (port, hosts) => { diff --git a/package-lock.json b/package-lock.json index 1e5ddc4db3..232b1596ec 100644 --- a/package-lock.json +++ b/package-lock.json @@ -64,7 +64,7 @@ "css-loader": "^7.1.1", "eslint": "^9.30.1", "eslint-config-prettier": "^10.1.5", - "eslint-config-webpack": "^4.4.0", + "eslint-config-webpack": "^4.9.6", "eslint-plugin-import": "^2.32.0", "eslint-plugin-jsdoc": "^51.3.4", "eslint-plugin-n": "^17.21.0", @@ -2907,10 +2907,20 @@ "node": ">=20.11.0" } }, + "node_modules/@es-joy/resolve.exports": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@es-joy/resolve.exports/-/resolve.exports-1.2.0.tgz", + "integrity": "sha512-Q9hjxWI5xBM+qW2enxfe8wDKdFWMfd0Z29k5ZJnuBqD/CasY5Zryj09aCA6owbGATWz+39p5uIdaHXpopOcG8g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + } + }, "node_modules/@eslint-community/eslint-utils": { - "version": "4.9.0", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.0.tgz", - "integrity": "sha512-ayVFHdtZ+hsq1t2Dy24wCmGXGe4q9Gu3smhLYALJrr473ZH27MsnSL+LKUlimp4BWJqMDMLmPpx/Q9R3OAlL4g==", + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.1.tgz", + "integrity": "sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==", "dev": true, "license": "MIT", "dependencies": { @@ -2940,9 +2950,9 @@ } }, "node_modules/@eslint-community/regexpp": { - "version": "4.12.1", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz", - "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==", + "version": "4.12.2", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.2.tgz", + "integrity": "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==", "dev": true, "license": "MIT", "engines": { @@ -2991,16 +3001,16 @@ } }, "node_modules/@eslint/core": { - "version": "0.15.2", - "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.15.2.tgz", - "integrity": "sha512-78Md3/Rrxh83gCxoUc0EiciuOHsIITzLy53m3d9UyiW8y9Dj2D29FeETqyKA+BRK76tnTp6RXWb3pCay8Oyomg==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-1.2.1.tgz", + "integrity": "sha512-MwcE1P+AZ4C6DWlpin/OmOA54mmIZ/+xZuJiQd4SyB29oAJjN30UW9wkKNptW2ctp4cEsvhlLY/CsQ1uoHDloQ==", "dev": true, "license": "Apache-2.0", "dependencies": { "@types/json-schema": "^7.0.15" }, "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "node": "^20.19.0 || ^22.13.0 || >=24" } }, "node_modules/@eslint/eslintrc": { @@ -3090,7 +3100,6 @@ "integrity": "sha512-S26Stp4zCy88tH94QbBv3XCuzRQiZ9yXofEILmglYTh/Ug/a9/umqvgFtYBAo3Lp0nsI/5/qH1CCrbdK3AP1Tw==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, @@ -3160,17 +3169,17 @@ } }, "node_modules/@eslint/plugin-kit": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.3.5.tgz", - "integrity": "sha512-Z5kJ+wU3oA7MMIqVR9tyZRtjYPr4OC004Q4Rw7pgOKUOKkJfZ3O24nz3WYfGRpMDNmcOi3TwQOmgm7B7Tpii0w==", + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.6.1.tgz", + "integrity": "sha512-iH1B076HoAshH1mLpHMgwdGeTs0CYwL0SPMkGuSebZrwBp16v415e9NZXg2jtrqPVQjf6IANe2Vtlr5KswtcZQ==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@eslint/core": "^0.15.2", + "@eslint/core": "^1.1.1", "levn": "^0.4.1" }, "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "node": "^20.19.0 || ^22.13.0 || >=24" } }, "node_modules/@exodus/bytes": { @@ -4072,15 +4081,28 @@ "dev": true, "license": "MIT" }, + "node_modules/@sindresorhus/base62": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/base62/-/base62-1.0.0.tgz", + "integrity": "sha512-TeheYy0ILzBEI/CO55CP6zJCSdSWeRtGnHy8U8dWSUH4I68iqTsy7HkMktR4xakThc9jotkPQUXT4ITdbV7cHA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/@stylistic/eslint-plugin": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin/-/eslint-plugin-5.3.1.tgz", - "integrity": "sha512-Ykums1VYonM0TgkD0VteVq9mrlO2FhF48MDJnPyv3MktIB2ydtuhlO0AfWm7xnW1kyf5bjOqA6xc7JjviuVTxg==", + "version": "5.10.0", + "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin/-/eslint-plugin-5.10.0.tgz", + "integrity": "sha512-nPK52ZHvot8Ju/0A4ucSX1dcPV2/1clx0kLcH5wDmrE4naKso7TUC/voUyU1O9OTKTrR6MYip6LP0ogEMQ9jPQ==", "dev": true, "license": "MIT", "dependencies": { - "@eslint-community/eslint-utils": "^4.7.0", - "@typescript-eslint/types": "^8.41.0", + "@eslint-community/eslint-utils": "^4.9.1", + "@typescript-eslint/types": "^8.56.0", "eslint-visitor-keys": "^4.2.1", "espree": "^10.4.0", "estraverse": "^5.3.0", @@ -4090,7 +4112,7 @@ "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "peerDependencies": { - "eslint": ">=9.0.0" + "eslint": "^9.0.0 || ^10.0.0" } }, "node_modules/@stylistic/eslint-plugin/node_modules/eslint-visitor-keys": { @@ -4245,6 +4267,16 @@ "@types/node": "*" } }, + "node_modules/@types/hast": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz", + "integrity": "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/unist": "*" + } + }, "node_modules/@types/html-minifier-terser": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz", @@ -4307,6 +4339,13 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/katex": { + "version": "0.16.8", + "resolved": "https://registry.npmjs.org/@types/katex/-/katex-0.16.8.tgz", + "integrity": "sha512-trgaNyfU+Xh2Tc+ABIb44a5AYUpicB3uwirOioeOkNPPbmgRNtcWyDeeFRzjPZENO9Vq8gvVqfhaaXWLlevVwg==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/mdast": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz", @@ -4471,21 +4510,21 @@ } }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.48.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.48.0.tgz", - "integrity": "sha512-XxXP5tL1txl13YFtrECECQYeZjBZad4fyd3cFV4a19LkAY/bIp9fev3US4S5fDVV2JaYFiKAZ/GRTOLer+mbyQ==", + "version": "8.59.3", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.59.3.tgz", + "integrity": "sha512-PwFvSKsXGShKGW6n5bZOhGHEcCZXM8HofLK9fNsEwZXzFRjoY+XT1Vsf1zgyXdwTr0ZYz1/2tkZ0DBTT9jZjhw==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { - "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "8.48.0", - "@typescript-eslint/type-utils": "8.48.0", - "@typescript-eslint/utils": "8.48.0", - "@typescript-eslint/visitor-keys": "8.48.0", - "graphemer": "^1.4.0", - "ignore": "^7.0.0", + "@eslint-community/regexpp": "^4.12.2", + "@typescript-eslint/scope-manager": "8.59.3", + "@typescript-eslint/type-utils": "8.59.3", + "@typescript-eslint/utils": "8.59.3", + "@typescript-eslint/visitor-keys": "8.59.3", + "ignore": "^7.0.5", "natural-compare": "^1.4.0", - "ts-api-utils": "^2.1.0" + "ts-api-utils": "^2.5.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -4495,9 +4534,9 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@typescript-eslint/parser": "^8.48.0", - "eslint": "^8.57.0 || ^9.0.0", - "typescript": ">=4.8.4 <6.0.0" + "@typescript-eslint/parser": "^8.59.3", + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" } }, "node_modules/@typescript-eslint/eslint-plugin/node_modules/ignore": { @@ -4511,18 +4550,18 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "8.48.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.48.0.tgz", - "integrity": "sha512-jCzKdm/QK0Kg4V4IK/oMlRZlY+QOcdjv89U2NgKHZk1CYTj82/RVSx1mV/0gqCVMJ/DA+Zf/S4NBWNF8GQ+eqQ==", + "version": "8.59.3", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.59.3.tgz", + "integrity": "sha512-HPwA+hVkfcriajbNvTmZv4VRauibay+cWArYUYq7u7W7PmGShMxbPxLvrwDme55a6d5alG3nrYfhyJ/G28XlLg==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@typescript-eslint/scope-manager": "8.48.0", - "@typescript-eslint/types": "8.48.0", - "@typescript-eslint/typescript-estree": "8.48.0", - "@typescript-eslint/visitor-keys": "8.48.0", - "debug": "^4.3.4" + "@typescript-eslint/scope-manager": "8.59.3", + "@typescript-eslint/types": "8.59.3", + "@typescript-eslint/typescript-estree": "8.59.3", + "@typescript-eslint/visitor-keys": "8.59.3", + "debug": "^4.4.3" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -4532,20 +4571,20 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0", - "typescript": ">=4.8.4 <6.0.0" + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" } }, "node_modules/@typescript-eslint/project-service": { - "version": "8.48.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.48.0.tgz", - "integrity": "sha512-Ne4CTZyRh1BecBf84siv42wv5vQvVmgtk8AuiEffKTUo3DrBaGYZueJSxxBZ8fjk/N3DrgChH4TOdIOwOwiqqw==", + "version": "8.59.3", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.59.3.tgz", + "integrity": "sha512-ECiUWa/KYRGDFUqTNehaRgzDshnJfkTABJxVemHk4ko22gcr0ukloKjWvyQ64g8YCV/UI47kN1dbmjf/GaQYng==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/tsconfig-utils": "^8.48.0", - "@typescript-eslint/types": "^8.48.0", - "debug": "^4.3.4" + "@typescript-eslint/tsconfig-utils": "^8.59.3", + "@typescript-eslint/types": "^8.59.3", + "debug": "^4.4.3" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -4555,18 +4594,18 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "typescript": ">=4.8.4 <6.0.0" + "typescript": ">=4.8.4 <6.1.0" } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "8.48.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.48.0.tgz", - "integrity": "sha512-uGSSsbrtJrLduti0Q1Q9+BF1/iFKaxGoQwjWOIVNJv0o6omrdyR8ct37m4xIl5Zzpkp69Kkmvom7QFTtue89YQ==", + "version": "8.59.3", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.59.3.tgz", + "integrity": "sha512-t2LvZnoEfzKtnPjgeEu41xw5gxq9mQVfYy4OoZ4Vlt0sk3JwxmhCca/AR7DwOiHrjWgjAj6as4AhRLKSDfvZIA==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.48.0", - "@typescript-eslint/visitor-keys": "8.48.0" + "@typescript-eslint/types": "8.59.3", + "@typescript-eslint/visitor-keys": "8.59.3" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -4577,9 +4616,9 @@ } }, "node_modules/@typescript-eslint/tsconfig-utils": { - "version": "8.48.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.48.0.tgz", - "integrity": "sha512-WNebjBdFdyu10sR1M4OXTt2OkMd5KWIL+LLfeH9KhgP+jzfDV/LI3eXzwJ1s9+Yc0Kzo2fQCdY/OpdusCMmh6w==", + "version": "8.59.3", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.59.3.tgz", + "integrity": "sha512-PcIJHjmaREXLgIAIzLnSY9VucEzz8FKXsRgFa1DmdGCK/5tJpW03TKJF01Q6VZd1lLdz2sIKPWaDUZN9dp//dw==", "dev": true, "license": "MIT", "engines": { @@ -4590,21 +4629,21 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "typescript": ">=4.8.4 <6.0.0" + "typescript": ">=4.8.4 <6.1.0" } }, "node_modules/@typescript-eslint/type-utils": { - "version": "8.48.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.48.0.tgz", - "integrity": "sha512-zbeVaVqeXhhab6QNEKfK96Xyc7UQuoFWERhEnj3mLVnUWrQnv15cJNseUni7f3g557gm0e46LZ6IJ4NJVOgOpw==", + "version": "8.59.3", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.59.3.tgz", + "integrity": "sha512-g71d8QD8UaiHGvrJwyIS1hCX5r63w6Jll+4VEYhEAHXTDIqX1JgxhTAbEHtKntL9kuc4jRo7/GWw5xfCepSccQ==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.48.0", - "@typescript-eslint/typescript-estree": "8.48.0", - "@typescript-eslint/utils": "8.48.0", - "debug": "^4.3.4", - "ts-api-utils": "^2.1.0" + "@typescript-eslint/types": "8.59.3", + "@typescript-eslint/typescript-estree": "8.59.3", + "@typescript-eslint/utils": "8.59.3", + "debug": "^4.4.3", + "ts-api-utils": "^2.5.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -4614,14 +4653,14 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0", - "typescript": ">=4.8.4 <6.0.0" + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" } }, "node_modules/@typescript-eslint/types": { - "version": "8.48.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.48.0.tgz", - "integrity": "sha512-cQMcGQQH7kwKoVswD1xdOytxQR60MWKM1di26xSUtxehaDs/32Zpqsu5WJlXTtTTqyAVK8R7hvsUnIXRS+bjvA==", + "version": "8.59.3", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.59.3.tgz", + "integrity": "sha512-ePFoH0g4ludssdRFqqDxQePCxU4WQyRa9+XVwjm7yLn0FKhMeoetC+qBEEI1Eyb1pGSDveTIT09Bvw2WhlGayg==", "dev": true, "license": "MIT", "engines": { @@ -4633,21 +4672,21 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "8.48.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.48.0.tgz", - "integrity": "sha512-ljHab1CSO4rGrQIAyizUS6UGHHCiAYhbfcIZ1zVJr5nMryxlXMVWS3duFPSKvSUbFPwkXMFk1k0EMIjub4sRRQ==", + "version": "8.59.3", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.59.3.tgz", + "integrity": "sha512-CbRjVRAf7Lr9Kr8RopKcbY45p2VfmmHrm0ygOCYFi7oU8q19m0Fs/6iHS7kNOmwpp+ob07ZVcAqlxUod9lYdmg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/project-service": "8.48.0", - "@typescript-eslint/tsconfig-utils": "8.48.0", - "@typescript-eslint/types": "8.48.0", - "@typescript-eslint/visitor-keys": "8.48.0", - "debug": "^4.3.4", - "minimatch": "^9.0.4", - "semver": "^7.6.0", + "@typescript-eslint/project-service": "8.59.3", + "@typescript-eslint/tsconfig-utils": "8.59.3", + "@typescript-eslint/types": "8.59.3", + "@typescript-eslint/visitor-keys": "8.59.3", + "debug": "^4.4.3", + "minimatch": "^10.2.2", + "semver": "^7.7.3", "tinyglobby": "^0.2.15", - "ts-api-utils": "^2.1.0" + "ts-api-utils": "^2.5.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -4657,39 +4696,52 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "typescript": ">=4.8.4 <6.0.0" + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "18 || 20 || >=22" } }, "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", - "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "version": "5.0.6", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.6.tgz", + "integrity": "sha512-kLpxurY4Z4r9sgMsyG0Z9uzsBlgiU/EFKhj/h91/8yHu0edo7XuixOIH3VcJ8kkxs6/jPzoI6U9Vj3WqbMQ94g==", "dev": true, "license": "MIT", "dependencies": { - "balanced-match": "^1.0.0" + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" } }, "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "version": "10.2.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz", + "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==", "dev": true, - "license": "ISC", + "license": "BlueOak-1.0.0", "dependencies": { - "brace-expansion": "^2.0.1" + "brace-expansion": "^5.0.5" }, "engines": { - "node": ">=16 || 14 >=14.17" + "node": "18 || 20 || >=22" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { - "version": "7.7.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", - "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.0.tgz", + "integrity": "sha512-AcM7dV/5ul4EekoQ29Agm5vri8JNqRyj39o0qpX6vDF2GZrtutZl5RwgD1XnZjiTAfncsJhMI48QQH3sN87YNA==", "dev": true, "license": "ISC", "bin": { @@ -4700,16 +4752,16 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "8.48.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.48.0.tgz", - "integrity": "sha512-yTJO1XuGxCsSfIVt1+1UrLHtue8xz16V8apzPYI06W0HbEbEWHxHXgZaAgavIkoh+GeV6hKKd5jm0sS6OYxWXQ==", + "version": "8.59.3", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.59.3.tgz", + "integrity": "sha512-JAvT14goBzRzzzZyqq3P9BLArIxTtQURUtFgQ/V7FO+eU+Gg6ES+5ymOPP1wRxXcxAYeivCk4uS3jCKWI1K8Zg==", "dev": true, "license": "MIT", "dependencies": { - "@eslint-community/eslint-utils": "^4.7.0", - "@typescript-eslint/scope-manager": "8.48.0", - "@typescript-eslint/types": "8.48.0", - "@typescript-eslint/typescript-estree": "8.48.0" + "@eslint-community/eslint-utils": "^4.9.1", + "@typescript-eslint/scope-manager": "8.59.3", + "@typescript-eslint/types": "8.59.3", + "@typescript-eslint/typescript-estree": "8.59.3" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -4719,19 +4771,19 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0", - "typescript": ">=4.8.4 <6.0.0" + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.48.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.48.0.tgz", - "integrity": "sha512-T0XJMaRPOH3+LBbAfzR2jalckP1MSG/L9eUtY0DEzUyVaXJ/t6zN0nR7co5kz0Jko/nkSYCBRkz1djvjajVTTg==", + "version": "8.59.3", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.59.3.tgz", + "integrity": "sha512-f1UQF7ggd42YiwI5wGrRaPsa+P0CINBlrkLPmGfpq/u/I/oVtecoEIfFR9ag/oa1sLOsRNZ6xehf6qMZhQGBDg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.48.0", - "eslint-visitor-keys": "^4.2.1" + "@typescript-eslint/types": "8.59.3", + "eslint-visitor-keys": "^5.0.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -4742,13 +4794,13 @@ } }, "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", - "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-5.0.1.tgz", + "integrity": "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==", "dev": true, "license": "Apache-2.0", "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "node": "^20.19.0 || ^22.13.0 || >=24" }, "funding": { "url": "https://opencollective.com/eslint" @@ -5185,6 +5237,27 @@ "dev": true, "license": "MIT" }, + "node_modules/array.prototype.findlast": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/array.prototype.findlast/-/array.prototype.findlast-1.2.5.tgz", + "integrity": "sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/array.prototype.findlastindex": { "version": "1.2.6", "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.6.tgz", @@ -5245,6 +5318,23 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/array.prototype.tosorted": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/array.prototype.tosorted/-/array.prototype.tosorted-1.1.4.tgz", + "integrity": "sha512-p6Fx8B7b7ZhL/gmUsAy0D15WhvDccw3mnGNbZpi3pmeJdxtWsj2jEaI4Y6oo3XiHfzuSgPwKc04MYt6KgvC/wA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.3", + "es-errors": "^1.3.0", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/arraybuffer.prototype.slice": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.4.tgz", @@ -5794,9 +5884,9 @@ "license": "MIT" }, "node_modules/builtin-modules": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-5.0.0.tgz", - "integrity": "sha512-bkXY9WsVpY7CvMhKSR6pZilZu9Ln5WDrKVBUXf2S443etkmEO4V58heTecXcUIsNsi4Rx8JUO4NfX1IcQl4deg==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-5.2.0.tgz", + "integrity": "sha512-02yxLeyxF4dNl6SlY6/5HfRSrSdZ/sCPoxy2kZNP5dZZX8LSAD9aE2gtJIUgWrsQTiMPl3mxESyrobSwvRGisQ==", "dev": true, "license": "MIT", "engines": { @@ -5840,15 +5930,15 @@ } }, "node_modules/call-bind": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz", - "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==", + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.9.tgz", + "integrity": "sha512-a/hy+pNsFUTR+Iz8TCJvXudKVLAnz/DyeSUo10I5yvFDQJBFU2s9uqQpoSrJlroHUKoKqzg+epxyP9lqFdzfBQ==", "dev": true, "license": "MIT", "dependencies": { - "call-bind-apply-helpers": "^1.0.0", - "es-define-property": "^1.0.0", - "get-intrinsic": "^1.2.4", + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "get-intrinsic": "^1.3.0", "set-function-length": "^1.2.2" }, "engines": { @@ -6055,9 +6145,9 @@ } }, "node_modules/ci-info": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.3.0.tgz", - "integrity": "sha512-l+2bNRMiQgcfILUi33labAZYIWlH1kWDp+ecNo5iisRKrbm0xcRyCww71/YU0Fkw0mAFpz9bJayXPjey6vkmaQ==", + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.4.0.tgz", + "integrity": "sha512-77PSwercCZU2Fc4sX94eF8k8Pxte6JAwL4/ICZLFjJLqegs7kCuAsqqj/70NQF6TvDpgFjkubQB2FW2ZZddvQg==", "dev": true, "funding": [ { @@ -8597,13 +8687,16 @@ } }, "node_modules/detect-indent": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-7.0.1.tgz", - "integrity": "sha512-Mc7QhQ8s+cLrnUfU/Ji94vG/r8M26m8f++vyres4ZoojaRDpZ1eSIh/EpzLNwlWuvzSZ3UbDFspjFvTDXe6e/g==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-7.0.2.tgz", + "integrity": "sha512-y+8xyqdGLL+6sh0tVeHcfP/QDd8gUgbasolJJpY7NgeQGSZ739bDtSiaiDgtoicy+mtYB81dKLxO9xRhCyIB3A==", "dev": true, "license": "MIT", "engines": { "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/detect-newline": { @@ -8992,9 +9085,9 @@ } }, "node_modules/es-abstract": { - "version": "1.24.0", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.24.0.tgz", - "integrity": "sha512-WSzPgsdLtTcQwm4CROfS5ju2Wa1QQcVeT37jFjYzdFz1r9ahadC8B8/a4qxJxM+09F18iumCdRmlr96ZYkQvEg==", + "version": "1.24.2", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.24.2.tgz", + "integrity": "sha512-2FpH9Q5i2RRwyEP1AylXe6nYLR5OhaJTZwmlcP0dL/+JCbgg7yyEo/sEK6HeGZRf3dFpWwThaRHVApXSkW3xeg==", "dev": true, "license": "MIT", "dependencies": { @@ -9078,6 +9171,34 @@ "node": ">= 0.4" } }, + "node_modules/es-iterator-helpers": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.3.2.tgz", + "integrity": "sha512-HVLACW1TppGYjJ8H6/jqH/pqOtKRw6wMlrB23xfExmFWxFquAIWCmwoLsOyN96K4a5KbmOf5At9ZUO3GZbetAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.9", + "call-bound": "^1.0.4", + "define-properties": "^1.2.1", + "es-abstract": "^1.24.2", + "es-errors": "^1.3.0", + "es-set-tostringtag": "^2.1.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.3.0", + "globalthis": "^1.0.4", + "gopd": "^1.2.0", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.2.0", + "has-symbols": "^1.1.0", + "internal-slot": "^1.1.0", + "iterator.prototype": "^1.1.5", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/es-module-lexer": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-2.0.0.tgz", @@ -9303,66 +9424,233 @@ } }, "node_modules/eslint-config-webpack": { - "version": "4.6.3", - "resolved": "https://registry.npmjs.org/eslint-config-webpack/-/eslint-config-webpack-4.6.3.tgz", - "integrity": "sha512-nKUWDmJ1SYwibd/zI5ntk6alKQ26e5ly0d5EQpDDRWtBJuBqvCyJtvphBtS0m58EsLLkQgCrSaWJVU4yGjSneg==", + "version": "4.9.6", + "resolved": "https://registry.npmjs.org/eslint-config-webpack/-/eslint-config-webpack-4.9.6.tgz", + "integrity": "sha512-4g1VqqOVgPrO/2bh17qNRKsQK26Aw1WF9mVTnvF+rNTDIUUTx+IaukXqXlumzwApQ1GfJlOsdLvT6WER1SPePg==", "dev": true, "license": "MIT", "dependencies": { - "detect-indent": "^7.0.1", - "jsonc-eslint-parser": "^2.4.0", - "semver": "^7.7.2", - "sort-package-json": "^3.4.0" + "@eslint/js": "^9.39.2", + "@eslint/markdown": "^8.0.1", + "@stylistic/eslint-plugin": "^5.10.0", + "detect-indent": "^7.0.2", + "eslint-config-prettier": "^10.1.8", + "eslint-plugin-import": "^2.32.0", + "eslint-plugin-jest": "^29.15.2", + "eslint-plugin-jsdoc": "^62.9.0", + "eslint-plugin-n": "^18.0.1", + "eslint-plugin-prettier": "^5.5.5", + "eslint-plugin-react": "^7.37.5", + "eslint-plugin-react-hooks": "^7.1.1", + "eslint-plugin-unicorn": "^64.0.0", + "globals": "^17.6.0", + "jsonc-eslint-parser": "^3.1.0", + "semver": "^7.8.0", + "sort-package-json": "^3.6.0", + "typescript-eslint": "^8.59.3" }, "engines": { "node": ">= 20.9.0" }, "peerDependencies": { - "@eslint/js": ">= 9.28.0", - "@eslint/markdown": ">= 7.1.0", - "@stylistic/eslint-plugin": ">= 4.4.1", "eslint": ">= 9.28.0", - "eslint-config-prettier": "^10.1.8", - "eslint-plugin-import": ">= 2.31.0", - "eslint-plugin-jest": ">= 28.12.0", - "eslint-plugin-jsdoc": ">= 50.7.1", - "eslint-plugin-n": ">= 17.19.0", - "eslint-plugin-prettier": ">= 5.5.3", - "eslint-plugin-react": ">= 7.37.5", - "eslint-plugin-unicorn": ">= 60.0.0", - "globals": ">= 16.2.0", - "prettier": ">= 3.5.3", - "typescript": ">= 5.0.0", - "typescript-eslint": ">= 8.34.0" + "typescript": ">=4.8.4 <7.0.0" }, "peerDependenciesMeta": { - "@eslint/markdown": { - "optional": true - }, - "eslint-plugin-jest": { - "optional": true - }, - "eslint-plugin-jsdoc": { - "optional": true - }, - "eslint-plugin-n": { + "typescript": { "optional": true - }, - "eslint-plugin-react": { + } + } + }, + "node_modules/eslint-config-webpack/node_modules/@es-joy/jsdoccomment": { + "version": "0.86.0", + "resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.86.0.tgz", + "integrity": "sha512-ukZmRQ81WiTpDWO6D/cTBM7XbrNtutHKvAVnZN/8pldAwLoJArGOvkNyxPTBGsPjsoaQBJxlH+tE2TNA/92Qgw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.8", + "@typescript-eslint/types": "^8.58.0", + "comment-parser": "1.4.6", + "esquery": "^1.7.0", + "jsdoc-type-pratt-parser": "~7.2.0" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + } + }, + "node_modules/eslint-config-webpack/node_modules/@eslint/js": { + "version": "9.39.4", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.39.4.tgz", + "integrity": "sha512-nE7DEIchvtiFTwBw4Lfbu59PG+kCofhjsKaCWzxTpt4lfRjRMqG6uMBzKXuEcyXhOHoUp9riAm7/aWYGhXZ9cw==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" + } + }, + "node_modules/eslint-config-webpack/node_modules/@eslint/markdown": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/@eslint/markdown/-/markdown-8.0.1.tgz", + "integrity": "sha512-WWKmld/EyNdEB8GMq7JMPX1SDWgyJAM1uhtCi5ySrqYQM4HQjmg11EX/q3ZpnpRXHfdccFtli3NBvvGaYjWyQw==", + "dev": true, + "license": "MIT", + "workspaces": [ + "examples/*" + ], + "dependencies": { + "@eslint/core": "^1.1.1", + "@eslint/plugin-kit": "^0.6.1", + "github-slugger": "^2.0.0", + "mdast-util-from-markdown": "^2.0.2", + "mdast-util-frontmatter": "^2.0.1", + "mdast-util-gfm": "^3.1.0", + "mdast-util-math": "^3.0.0", + "micromark-extension-frontmatter": "^2.0.0", + "micromark-extension-gfm": "^3.0.0", + "micromark-extension-math": "^3.1.0", + "micromark-util-normalize-identifier": "^2.0.1" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + } + }, + "node_modules/eslint-config-webpack/node_modules/comment-parser": { + "version": "1.4.6", + "resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.4.6.tgz", + "integrity": "sha512-ObxuY6vnbWTN6Od72xfwN9DbzC7Y2vv8u1Soi9ahRKL37gb6y1qk6/dgjs+3JWuXJHWvsg3BXIwzd/rkmAwavg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 12.0.0" + } + }, + "node_modules/eslint-config-webpack/node_modules/eslint-plugin-jsdoc": { + "version": "62.9.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-62.9.0.tgz", + "integrity": "sha512-PY7/X4jrVgoIDncUmITlUqK546Ltmx/Pd4Hdsu4CvSjryQZJI2mEV4vrdMufyTetMiZ5taNSqvK//BTgVUlNkA==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@es-joy/jsdoccomment": "~0.86.0", + "@es-joy/resolve.exports": "1.2.0", + "are-docs-informative": "^0.0.2", + "comment-parser": "1.4.6", + "debug": "^4.4.3", + "escape-string-regexp": "^4.0.0", + "espree": "^11.2.0", + "esquery": "^1.7.0", + "html-entities": "^2.6.0", + "object-deep-merge": "^2.0.0", + "parse-imports-exports": "^0.2.4", + "semver": "^7.7.4", + "spdx-expression-parse": "^4.0.0", + "to-valid-identifier": "^1.0.0" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "peerDependencies": { + "eslint": "^7.0.0 || ^8.0.0 || ^9.0.0 || ^10.0.0" + } + }, + "node_modules/eslint-config-webpack/node_modules/eslint-plugin-n": { + "version": "18.0.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-n/-/eslint-plugin-n-18.0.1.tgz", + "integrity": "sha512-q3ARhk+eZRc7myR0KHx+R3/GJeOHF+Ir6PK95Pu2tEX8Sl/4BIpmmVLva2kPrjC2gCmn6WHlHm+3yeo6Rxhycw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.5.0", + "enhanced-resolve": "^5.17.1", + "eslint-plugin-es-x": "^7.8.0", + "get-tsconfig": "^4.8.1", + "globals": "^15.11.0", + "globrex": "^0.1.2", + "ignore": "^5.3.2", + "semver": "^7.6.3" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://opencollective.com/eslint" + }, + "peerDependencies": { + "eslint": ">=8.57.1", + "ts-declaration-location": "^1.0.6", + "typescript": ">=5.0.0" + }, + "peerDependenciesMeta": { + "ts-declaration-location": { "optional": true }, "typescript": { "optional": true - }, - "typescript-eslint": { - "optional": true } } }, + "node_modules/eslint-config-webpack/node_modules/eslint-plugin-n/node_modules/globals": { + "version": "15.15.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-15.15.0.tgz", + "integrity": "sha512-7ACyT3wmyp3I61S4fG682L0VA2RGD9otkqGJIwNUMF1SWUombIIk+af1unuDYgMm082aHYwD+mzJvv9Iu8dsgg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint-config-webpack/node_modules/eslint-visitor-keys": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-5.0.1.tgz", + "integrity": "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-config-webpack/node_modules/espree": { + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-11.2.0.tgz", + "integrity": "sha512-7p3DrVEIopW1B1avAGLuCSh1jubc01H2JHc8B4qqGblmg5gI9yumBgACjWo4JlIc04ufug4xJ3SQI8HkS/Rgzw==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "acorn": "^8.16.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^5.0.1" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-config-webpack/node_modules/jsdoc-type-pratt-parser": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-7.2.0.tgz", + "integrity": "sha512-dh140MMgjyg3JhJZY/+iEzW+NO5xR2gpbDFKHqotCmexElVntw7GjWjt511+C/Ef02RU5TKYrJo/Xlzk+OLaTw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=20.0.0" + } + }, "node_modules/eslint-config-webpack/node_modules/semver": { - "version": "7.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", - "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.0.tgz", + "integrity": "sha512-AcM7dV/5ul4EekoQ29Agm5vri8JNqRyj39o0qpX6vDF2GZrtutZl5RwgD1XnZjiTAfncsJhMI48QQH3sN87YNA==", "dev": true, "license": "ISC", "bin": { @@ -9450,7 +9738,6 @@ "integrity": "sha512-whOE1HFo/qJDyX4SnXzP4N6zOWn79WhnCUY/iDR0mPfQZO8wcYE4JClzI2oZrhBnnMUCBCHZhO6VQyoBU95mZA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@rtsao/scc": "^1.1.0", "array-includes": "^3.1.9", @@ -9489,13 +9776,42 @@ "ms": "^2.1.1" } }, + "node_modules/eslint-plugin-jest": { + "version": "29.15.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-29.15.2.tgz", + "integrity": "sha512-kEN4r9RZl1xcsb4arGq89LrcVdOUFII/JSCwtTPJyv16mDwmPrcuEQwpxqZHeINvcsd7oK5O/rhdGlxFRaZwvQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/utils": "^8.0.0" + }, + "engines": { + "node": "^20.12.0 || ^22.0.0 || >=24.0.0" + }, + "peerDependencies": { + "@typescript-eslint/eslint-plugin": "^8.0.0", + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "jest": "*", + "typescript": ">=4.8.4 <7.0.0" + }, + "peerDependenciesMeta": { + "@typescript-eslint/eslint-plugin": { + "optional": true + }, + "jest": { + "optional": true + }, + "typescript": { + "optional": true + } + } + }, "node_modules/eslint-plugin-jsdoc": { "version": "51.4.1", "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-51.4.1.tgz", "integrity": "sha512-y4CA9OkachG8v5nAtrwvcvjIbdcKgSyS6U//IfQr4FZFFyeBFwZFf/tfSsMr46mWDJgidZjBTqoCRlXywfFBMg==", "dev": true, "license": "BSD-3-Clause", - "peer": true, "dependencies": { "@es-joy/jsdoccomment": "~0.52.0", "are-docs-informative": "^0.0.2", @@ -9534,7 +9850,6 @@ "integrity": "sha512-68PealUpYoHOBh332JLLD9Sj7OQUDkFpmcfqt8R9sySfFSeuGJjMTJQvCRRB96zO3A/PELRLkPrzsHmzEFQQ5A==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.5.0", "enhanced-resolve": "^5.17.1", @@ -9583,15 +9898,14 @@ } }, "node_modules/eslint-plugin-prettier": { - "version": "5.5.4", - "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.5.4.tgz", - "integrity": "sha512-swNtI95SToIz05YINMA6Ox5R057IMAmWZ26GqPxusAp1TZzj+IdY9tXNWWD3vkF/wEqydCONcwjTFpxybBqZsg==", + "version": "5.5.5", + "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.5.5.tgz", + "integrity": "sha512-hscXkbqUZ2sPithAuLm5MXL+Wph+U7wHngPBv9OMWwlP8iaflyxpjTYZkmdgB4/vPIhemRlBEoLrH7UC1n7aUw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { - "prettier-linter-helpers": "^1.0.0", - "synckit": "^0.11.7" + "prettier-linter-helpers": "^1.0.1", + "synckit": "^0.11.12" }, "engines": { "node": "^14.18.0 || >=16.0.0" @@ -9614,31 +9928,106 @@ } } }, + "node_modules/eslint-plugin-react": { + "version": "7.37.5", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.37.5.tgz", + "integrity": "sha512-Qteup0SqU15kdocexFNAJMvCJEfa2xUKNV4CC1xsVMrIIqEy3SQ/rqyxCWNzfrd3/ldy6HMlD2e0JDVpDg2qIA==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-includes": "^3.1.8", + "array.prototype.findlast": "^1.2.5", + "array.prototype.flatmap": "^1.3.3", + "array.prototype.tosorted": "^1.1.4", + "doctrine": "^2.1.0", + "es-iterator-helpers": "^1.2.1", + "estraverse": "^5.3.0", + "hasown": "^2.0.2", + "jsx-ast-utils": "^2.4.1 || ^3.0.0", + "minimatch": "^3.1.2", + "object.entries": "^1.1.9", + "object.fromentries": "^2.0.8", + "object.values": "^1.2.1", + "prop-types": "^15.8.1", + "resolve": "^2.0.0-next.5", + "semver": "^6.3.1", + "string.prototype.matchall": "^4.0.12", + "string.prototype.repeat": "^1.0.0" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7" + } + }, + "node_modules/eslint-plugin-react-hooks": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-7.1.1.tgz", + "integrity": "sha512-f2I7Gw6JbvCexzIInuSbZpfdQ44D7iqdWX01FKLvrPgqxoE7oMj8clOfto8U6vYiz4yd5oKu39rRSVOe1zRu0g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.24.4", + "@babel/parser": "^7.24.4", + "hermes-parser": "^0.25.1", + "zod": "^3.25.0 || ^4.0.0", + "zod-validation-error": "^3.5.0 || ^4.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0 || ^10.0.0" + } + }, + "node_modules/eslint-plugin-react/node_modules/resolve": { + "version": "2.0.0-next.7", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.7.tgz", + "integrity": "sha512-tqt+NBWwyaMgw3zDsnygx4CByWjQEJHOPMdslYhppaQSJUtL/D4JO9CcBBlhPoI8lz9oJIDXkwXfhF4aWqP8xQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "is-core-module": "^2.16.2", + "node-exports-info": "^1.6.0", + "object-keys": "^1.1.1", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/eslint-plugin-unicorn": { - "version": "61.0.2", - "resolved": "https://registry.npmjs.org/eslint-plugin-unicorn/-/eslint-plugin-unicorn-61.0.2.tgz", - "integrity": "sha512-zLihukvneYT7f74GNbVJXfWIiNQmkc/a9vYBTE4qPkQZswolWNdu+Wsp9sIXno1JOzdn6OUwLPd19ekXVkahRA==", + "version": "64.0.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-unicorn/-/eslint-plugin-unicorn-64.0.0.tgz", + "integrity": "sha512-rNZwalHh8i0UfPlhNwg5BTUO1CMdKNmjqe+TgzOTZnpKoi8VBgsW7u9qCHIdpxEzZ1uwrJrPF0uRb7l//K38gA==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-validator-identifier": "^7.27.1", - "@eslint-community/eslint-utils": "^4.7.0", - "@eslint/plugin-kit": "^0.3.3", + "@babel/helper-validator-identifier": "^7.28.5", + "@eslint-community/eslint-utils": "^4.9.1", "change-case": "^5.4.4", - "ci-info": "^4.3.0", + "ci-info": "^4.4.0", "clean-regexp": "^1.0.0", - "core-js-compat": "^3.44.0", - "esquery": "^1.6.0", + "core-js-compat": "^3.49.0", "find-up-simple": "^1.0.1", - "globals": "^16.3.0", + "globals": "^17.4.0", "indent-string": "^5.0.0", "is-builtin-module": "^5.0.0", "jsesc": "^3.1.0", "pluralize": "^8.0.0", "regexp-tree": "^0.1.27", - "regjsparser": "^0.12.0", - "semver": "^7.7.2", - "strip-indent": "^4.0.0" + "regjsparser": "^0.13.0", + "semver": "^7.7.4", + "strip-indent": "^4.1.1" }, "engines": { "node": "^20.10.0 || >=21.0.0" @@ -9647,13 +10036,26 @@ "url": "https://github.com/sindresorhus/eslint-plugin-unicorn?sponsor=1" }, "peerDependencies": { - "eslint": ">=9.29.0" + "eslint": ">=9.38.0" + } + }, + "node_modules/eslint-plugin-unicorn/node_modules/regjsparser": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.13.1.tgz", + "integrity": "sha512-dLsljMd9sqwRkby8zhO1gSg3PnJIBFid8f4CQj/sXx+7cKx+E7u0PKhZ+U4wmhx7EfmtvnA318oVaIkAB1lRJw==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "jsesc": "~3.1.0" + }, + "bin": { + "regjsparser": "bin/parser" } }, "node_modules/eslint-plugin-unicorn/node_modules/semver": { - "version": "7.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", - "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.0.tgz", + "integrity": "sha512-AcM7dV/5ul4EekoQ29Agm5vri8JNqRyj39o0qpX6vDF2GZrtutZl5RwgD1XnZjiTAfncsJhMI48QQH3sN87YNA==", "dev": true, "license": "ISC", "bin": { @@ -9963,9 +10365,9 @@ } }, "node_modules/esquery": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", - "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.7.0.tgz", + "integrity": "sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==", "dev": true, "license": "BSD-3-Clause", "dependencies": { @@ -11338,9 +11740,9 @@ } }, "node_modules/git-hooks-list": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/git-hooks-list/-/git-hooks-list-4.1.1.tgz", - "integrity": "sha512-cmP497iLq54AZnv4YRAEMnEyQ1eIn4tGKbmswqwmFV4GBnAqE8NLtWxxdXa++AalfgL5EBH4IxTPyquEuGY/jA==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/git-hooks-list/-/git-hooks-list-4.2.1.tgz", + "integrity": "sha512-WNvqJjOxxs/8ZP9+DWdwWJ7cDsd60NHf39XnD82pDVrKO5q7xfPqpkK6hwEAmBa/ZSEE4IOoR75EzbbIuwGlMw==", "dev": true, "license": "MIT", "funding": { @@ -11766,12 +12168,11 @@ } }, "node_modules/globals": { - "version": "16.4.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-16.4.0.tgz", - "integrity": "sha512-ob/2LcVVaVGCYN+r14cnwnoDPUufjiYgSqRhiFD0Q1iI4Odora5RE8Iv1D24hAz5oMophRGkGz+yuvQmmUMnMw==", + "version": "17.6.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-17.6.0.tgz", + "integrity": "sha512-sepffkT8stwnIYbsMBpoCHJuJM5l98FUF2AnE07hfvE0m/qp3R586hw4jF4uadbhvg1ooIdzuu7CsfD2jzCaNA==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=18" }, @@ -11821,13 +12222,6 @@ "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", "license": "ISC" }, - "node_modules/graphemer": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", - "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", - "dev": true, - "license": "MIT" - }, "node_modules/handlebars": { "version": "4.7.8", "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.8.tgz", @@ -11951,9 +12345,9 @@ } }, "node_modules/hasown": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", - "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.3.tgz", + "integrity": "sha512-ej4AhfhfL2Q2zpMmLo7U1Uv9+PyhIZpgQLGT1F9miIGmiCJIoCgSmczFdrc97mWT4kVY72KA+WnnhJ5pghSvSg==", "license": "MIT", "dependencies": { "function-bind": "^1.1.2" @@ -11972,6 +12366,23 @@ "he": "bin/he" } }, + "node_modules/hermes-estree": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/hermes-estree/-/hermes-estree-0.25.1.tgz", + "integrity": "sha512-0wUoCcLp+5Ev5pDW2OriHC2MJCbwLwuRx+gAqMTOkGKJJiBCLjtrvy4PWUGn6MIVefecRpzoOZ/UV6iGdOr+Cw==", + "dev": true, + "license": "MIT" + }, + "node_modules/hermes-parser": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/hermes-parser/-/hermes-parser-0.25.1.tgz", + "integrity": "sha512-6pEjquH3rqaI6cYAXYPcz9MS4rY6R4ngRgrgfDshRptUZIc3lw0MCIJIGDj9++mfySOuPTHB4nrSW99BCvOPIA==", + "dev": true, + "license": "MIT", + "dependencies": { + "hermes-estree": "0.25.1" + } + }, "node_modules/hono": { "version": "4.12.9", "resolved": "https://registry.npmjs.org/hono/-/hono-4.12.9.tgz", @@ -12003,6 +12414,23 @@ "node": "^20.19.0 || ^22.12.0 || >=24.0.0" } }, + "node_modules/html-entities": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.6.0.tgz", + "integrity": "sha512-kig+rMn/QOVRvr7c86gQ8lWXq+Hkv6CbAH1hLu+RG338StTpE8Z0b44SDVaqVu7HGKf27frdmUYEs9hTUX/cLQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/mdevils" + }, + { + "type": "patreon", + "url": "https://patreon.com/mdevils" + } + ], + "license": "MIT" + }, "node_modules/html-minifier-terser": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz", @@ -12565,13 +12993,13 @@ } }, "node_modules/is-core-module": { - "version": "2.16.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", - "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", + "version": "2.16.2", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.2.tgz", + "integrity": "sha512-evOr8xfXKxE6qSR0hSXL2r3sd7ALj8+7jQEUvPYcm5sgZFdJ+AYzT6yNmJenvIYQBgIGwfwz08sL8zoL7yq2BA==", "dev": true, "license": "MIT", "dependencies": { - "hasown": "^2.0.2" + "hasown": "^2.0.3" }, "engines": { "node": ">= 0.4" @@ -12800,7 +13228,20 @@ "dev": true, "license": "MIT", "engines": { - "node": ">=8" + "node": ">=8" + } + }, + "node_modules/is-plain-obj": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", + "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/is-plain-object": { @@ -13068,6 +13509,24 @@ "node": ">=0.10.0" } }, + "node_modules/iterator.prototype": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/iterator.prototype/-/iterator.prototype-1.1.5.tgz", + "integrity": "sha512-H0dkQoCa3b2VEeKQBOxFph+JAbcrQdE7KC0UkqwpLmv2EC4P41QXP+rqo9wYodACiG5/WM5s9oDApTU8utwj9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.6", + "get-proto": "^1.0.0", + "has-symbols": "^1.1.0", + "set-function-name": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/jackspeak": { "version": "3.4.3", "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", @@ -13398,59 +13857,40 @@ } }, "node_modules/jsonc-eslint-parser": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/jsonc-eslint-parser/-/jsonc-eslint-parser-2.4.0.tgz", - "integrity": "sha512-WYDyuc/uFcGp6YtM2H0uKmUwieOuzeE/5YocFJLnLfclZ4inf3mRn8ZVy1s7Hxji7Jxm6Ss8gqpexD/GlKoGgg==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jsonc-eslint-parser/-/jsonc-eslint-parser-3.1.0.tgz", + "integrity": "sha512-75EA7EWZExL/j+MDKQrRbdzcRI2HOkRlmUw8fZJc1ioqFEOvBsq7Rt+A6yCxOt9w/TYNpkt52gC6nm/g5tFIng==", "dev": true, "license": "MIT", "dependencies": { "acorn": "^8.5.0", - "eslint-visitor-keys": "^3.0.0", - "espree": "^9.0.0", + "eslint-visitor-keys": "^5.0.0", "semver": "^7.3.5" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^20.19.0 || ^22.13.0 || >=24" }, "funding": { "url": "https://github.com/sponsors/ota-meshi" } }, "node_modules/jsonc-eslint-parser/node_modules/eslint-visitor-keys": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-5.0.1.tgz", + "integrity": "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==", "dev": true, "license": "Apache-2.0", "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/jsonc-eslint-parser/node_modules/espree": { - "version": "9.6.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", - "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "acorn": "^8.9.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.4.1" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^20.19.0 || ^22.13.0 || >=24" }, "funding": { "url": "https://opencollective.com/eslint" } }, "node_modules/jsonc-eslint-parser/node_modules/semver": { - "version": "7.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", - "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.0.tgz", + "integrity": "sha512-AcM7dV/5ul4EekoQ29Agm5vri8JNqRyj39o0qpX6vDF2GZrtutZl5RwgD1XnZjiTAfncsJhMI48QQH3sN87YNA==", "dev": true, "license": "ISC", "bin": { @@ -13487,6 +13927,49 @@ "node": "*" } }, + "node_modules/jsx-ast-utils": { + "version": "3.3.5", + "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz", + "integrity": "sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-includes": "^3.1.6", + "array.prototype.flat": "^1.3.1", + "object.assign": "^4.1.4", + "object.values": "^1.1.6" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/katex": { + "version": "0.16.47", + "resolved": "https://registry.npmjs.org/katex/-/katex-0.16.47.tgz", + "integrity": "sha512-Eeo8Ys1doU1z+x8AZsPpQu+p/QcZBI5PeOo7QGQdy2x2m0MU/hYagBbGOmXwr5KVbEfVuWv9LpnQWeehogurjg==", + "dev": true, + "funding": [ + "https://opencollective.com/katex", + "https://github.com/sponsors/katex" + ], + "license": "MIT", + "dependencies": { + "commander": "^8.3.0" + }, + "bin": { + "katex": "cli.js" + } + }, + "node_modules/katex/node_modules/commander": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", + "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 12" + } + }, "node_modules/keyv": { "version": "4.5.4", "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", @@ -14080,6 +14563,19 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, "node_modules/lower-case": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", @@ -14364,6 +14860,26 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/mdast-util-math": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-math/-/mdast-util-math-3.0.0.tgz", + "integrity": "sha512-Tl9GBNeG/AhJnQM221bJR2HPvLOSnLE/T9cJI9tlc6zwQk2nPk/4f0cHkOdEixQPC/j8UtKDdITswvLAy1OZ1w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "longest-streak": "^3.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.1.0", + "unist-util-remove-position": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/mdast-util-phrasing": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/mdast-util-phrasing/-/mdast-util-phrasing-4.1.0.tgz", @@ -14727,6 +15243,26 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/micromark-extension-math": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-math/-/micromark-extension-math-3.1.0.tgz", + "integrity": "sha512-lvEqd+fHjATVs+2v/8kg9i5Q0AP2k85H0WUOwpIVvUML8BapsMvh1XAogmQjOCsLpoKRCVQqEkQBB3NhVBcsOg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/katex": "^0.16.0", + "devlop": "^1.0.0", + "katex": "^0.16.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/micromark-factory-destination": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-2.0.1.tgz", @@ -15417,6 +15953,25 @@ "tslib": "^2.0.3" } }, + "node_modules/node-exports-info": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/node-exports-info/-/node-exports-info-1.6.0.tgz", + "integrity": "sha512-pyFS63ptit/P5WqUkt+UUfe+4oevH+bFeIiPPdfb0pFeYEu/1ELnJu5l+5EcTKYL5M7zaAa7S8ddywgXypqKCw==", + "dev": true, + "license": "MIT", + "dependencies": { + "array.prototype.flatmap": "^1.3.3", + "es-errors": "^1.3.0", + "object.entries": "^1.1.9", + "semver": "^6.3.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/node-releases": { "version": "2.0.27", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.27.tgz", @@ -15644,6 +16199,23 @@ "url": "https://github.com/fb55/nth-check?sponsor=1" } }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-deep-merge": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/object-deep-merge/-/object-deep-merge-2.0.0.tgz", + "integrity": "sha512-3DC3UMpeffLTHiuXSy/UG4NOIYTLlY9u3V82+djSCLYClWobZiS4ivYzpIUWrRY/nfsJ8cWsKyG3QfyLePmhvg==", + "dev": true, + "license": "MIT" + }, "node_modules/object-inspect": { "version": "1.13.4", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", @@ -15687,6 +16259,22 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/object.entries": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.9.tgz", + "integrity": "sha512-8u/hfXFRBD1O0hPUjioLhoWFHRmt6tKA4/vZPyckBr18l1KE9uHrFaFaUi8MDRTpi4uak2goyPTSNJLXX2k2Hw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/object.fromentries": { "version": "2.0.8", "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.8.tgz", @@ -16521,9 +17109,9 @@ } }, "node_modules/prettier-linter-helpers": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", - "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.1.tgz", + "integrity": "sha512-SxToR7P8Y2lWmv/kTzVLC1t/GDI2WGjMwNhLLE9qtH8Q13C+aEmuRlzDst4Up4s0Wc8sF2M+J57iB3cMLqftfg==", "dev": true, "license": "MIT", "dependencies": { @@ -16613,6 +17201,18 @@ "node": ">=0.4.0" } }, + "node_modules/prop-types": { + "version": "15.8.1", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", + "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", + "dev": true, + "license": "MIT", + "dependencies": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.13.1" + } + }, "node_modules/proxy-addr": { "version": "2.0.7", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", @@ -16859,6 +17459,13 @@ "node": ">= 0.10" } }, + "node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "dev": true, + "license": "MIT" + }, "node_modules/react-is-18": { "name": "react-is", "version": "18.3.1", @@ -17270,6 +17877,19 @@ "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", "license": "MIT" }, + "node_modules/reserved-identifiers": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/reserved-identifiers/-/reserved-identifiers-1.2.0.tgz", + "integrity": "sha512-yE7KUfFvaBFzGPs5H3Ops1RevfUEsDc5Iz65rOwWg4lE8HJSYtle77uul3+573457oHvBKuHYDl/xqUkKpEEdw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/resolve": { "version": "1.22.12", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.12.tgz", @@ -18019,26 +18639,26 @@ } }, "node_modules/sort-object-keys": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/sort-object-keys/-/sort-object-keys-1.1.3.tgz", - "integrity": "sha512-855pvK+VkU7PaKYPc+Jjnmt4EzejQHyhhF33q31qG8x7maDzkeFhAAThdCYay11CISO+qAMwjOBP+fPZe0IPyg==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/sort-object-keys/-/sort-object-keys-2.1.0.tgz", + "integrity": "sha512-SOiEnthkJKPv2L6ec6HMwhUcN0/lppkeYuN1x63PbyPRrgSPIuBJCiYxYyvWRTtjMlOi14vQUCGUJqS6PLVm8g==", "dev": true, "license": "MIT" }, "node_modules/sort-package-json": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/sort-package-json/-/sort-package-json-3.4.0.tgz", - "integrity": "sha512-97oFRRMM2/Js4oEA9LJhjyMlde+2ewpZQf53pgue27UkbEXfHJnDzHlUxQ/DWUkzqmp7DFwJp8D+wi/TYeQhpA==", + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/sort-package-json/-/sort-package-json-3.6.1.tgz", + "integrity": "sha512-Chgejw1+10p2D0U2tB7au1lHtz6TkFnxmvZktyBCRyV0GgmF6nl1IxXxAsPtJVsUyg/fo+BfCMAVVFUVRkAHrQ==", "dev": true, "license": "MIT", "dependencies": { - "detect-indent": "^7.0.1", + "detect-indent": "^7.0.2", "detect-newline": "^4.0.1", - "git-hooks-list": "^4.0.0", + "git-hooks-list": "^4.1.1", "is-plain-obj": "^4.1.0", - "semver": "^7.7.1", - "sort-object-keys": "^1.1.3", - "tinyglobby": "^0.2.12" + "semver": "^7.7.3", + "sort-object-keys": "^2.0.1", + "tinyglobby": "^0.2.15" }, "bin": { "sort-package-json": "cli.js" @@ -18060,23 +18680,10 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/sort-package-json/node_modules/is-plain-obj": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", - "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/sort-package-json/node_modules/semver": { - "version": "7.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", - "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.0.tgz", + "integrity": "sha512-AcM7dV/5ul4EekoQ29Agm5vri8JNqRyj39o0qpX6vDF2GZrtutZl5RwgD1XnZjiTAfncsJhMI48QQH3sN87YNA==", "dev": true, "license": "ISC", "bin": { @@ -18652,6 +19259,34 @@ "node": ">=8" } }, + "node_modules/string.prototype.matchall": { + "version": "4.0.12", + "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.12.tgz", + "integrity": "sha512-6CC9uyBL+/48dYizRf7H7VAYCMCNTBeM78x/VTUe9bFEaxBepPJDa1Ow99LqI/1yF7kuy7Q3cQsYMrcjGUcskA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.6", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.6", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "internal-slot": "^1.1.0", + "regexp.prototype.flags": "^1.5.3", + "set-function-name": "^2.0.2", + "side-channel": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/string.prototype.padend": { "version": "3.1.6", "resolved": "https://registry.npmjs.org/string.prototype.padend/-/string.prototype.padend-3.1.6.tgz", @@ -18671,6 +19306,17 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/string.prototype.repeat": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/string.prototype.repeat/-/string.prototype.repeat-1.0.0.tgz", + "integrity": "sha512-0u/TldDbKD8bFCQ/4f5+mNRrXwZ8hg2w7ZR8wa16e8z9XpePWl3eGEcUD0OXpEH/VJH/2G3gjUtR3ZOiBe2S/w==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.5" + } + }, "node_modules/string.prototype.trim": { "version": "1.2.10", "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.10.tgz", @@ -18789,9 +19435,9 @@ } }, "node_modules/strip-indent": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-4.1.0.tgz", - "integrity": "sha512-OA95x+JPmL7kc7zCu+e+TeYxEiaIyndRx0OrBcK2QPPH09oAndr2ALvymxWA+Lx1PYYvFUm4O63pRkdJAaW96w==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-4.1.1.tgz", + "integrity": "sha512-SlyRoSkdh1dYP0PzclLE7r0M9sgbFKKMFXpFRUMNuKhQSbC6VQIGzq3E0qsfvGJaUFJPGv6Ws1NZ/haTAjfbMA==", "dev": true, "license": "MIT", "engines": { @@ -18914,9 +19560,9 @@ "license": "MIT" }, "node_modules/synckit": { - "version": "0.11.11", - "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.11.11.tgz", - "integrity": "sha512-MeQTA1r0litLUf0Rp/iisCaL8761lKAZHaimlbGK4j0HysC4PLfqygQj9srcs0m2RdtDYnF8UuYyKpbjHYp7Jw==", + "version": "0.11.12", + "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.11.12.tgz", + "integrity": "sha512-Bh7QjT8/SuKUIfObSXNHNSK6WHo6J1tHCqJsuaFDP7gP0fkzSfTxI8y85JrppZ0h8l0maIgc2tfuZQ6/t3GtnQ==", "dev": true, "license": "MIT", "dependencies": { @@ -19240,6 +19886,23 @@ "node": ">=8.0" } }, + "node_modules/to-valid-identifier": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/to-valid-identifier/-/to-valid-identifier-1.0.0.tgz", + "integrity": "sha512-41wJyvKep3yT2tyPqX/4blcfybknGB4D+oETKLs7Q76UiPqRpUJK3hr1nxelyYO0PHKVzJwlu0aCeEAsGI6rpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@sindresorhus/base62": "^1.0.0", + "reserved-identifiers": "^1.0.0" + }, + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/toidentifier": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", @@ -19302,9 +19965,9 @@ } }, "node_modules/ts-api-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.1.0.tgz", - "integrity": "sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.5.0.tgz", + "integrity": "sha512-OJ/ibxhPlqrMM0UiNHJ/0CKQkoKF243/AEmplt3qpRgkW8VG7IfOS41h7V8TjITqdByHzrjcS/2si+y4lIh8NA==", "dev": true, "license": "MIT", "engines": { @@ -19330,6 +19993,7 @@ } ], "license": "BSD-3-Clause", + "peer": true, "dependencies": { "picomatch": "^4.0.2" }, @@ -19549,17 +20213,16 @@ } }, "node_modules/typescript-eslint": { - "version": "8.48.0", - "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.48.0.tgz", - "integrity": "sha512-fcKOvQD9GUn3Xw63EgiDqhvWJ5jsyZUaekl3KVpGsDJnN46WJTe3jWxtQP9lMZm1LJNkFLlTaWAxK2vUQR+cqw==", + "version": "8.59.3", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.59.3.tgz", + "integrity": "sha512-KgusgyDgG4LI8Ih/sWaCtZ06tckLAS5CvT5A4D1Q7bYVoAAyzwiZvE4BmwDHkhRVkvhRBepKeASoFzQetha7Fg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { - "@typescript-eslint/eslint-plugin": "8.48.0", - "@typescript-eslint/parser": "8.48.0", - "@typescript-eslint/typescript-estree": "8.48.0", - "@typescript-eslint/utils": "8.48.0" + "@typescript-eslint/eslint-plugin": "8.59.3", + "@typescript-eslint/parser": "8.59.3", + "@typescript-eslint/typescript-estree": "8.59.3", + "@typescript-eslint/utils": "8.59.3" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -19569,8 +20232,8 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0", - "typescript": ">=4.8.4 <6.0.0" + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" } }, "node_modules/uglify-js": { @@ -19693,6 +20356,21 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/unist-util-remove-position": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-remove-position/-/unist-util-remove-position-5.0.0.tgz", + "integrity": "sha512-Hp5Kh3wLxv0PHj9m2yZhhLt58KzPtEYKQQ4yxfYFEO7EvHwzyDYnduhHnY1mDxoqr7VUwVuHXk9RXKIiYS1N8Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-visit": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/unist-util-stringify-position": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", @@ -20600,10 +21278,24 @@ "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==", "dev": true, "license": "MIT", + "peer": true, "funding": { "url": "https://github.com/sponsors/colinhacks" } }, + "node_modules/zod-validation-error": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/zod-validation-error/-/zod-validation-error-4.0.2.tgz", + "integrity": "sha512-Q6/nZLe6jxuU80qb/4uJ4t5v2VEZ44lzQjPDhYJNztRQ4wyWc6VF3D3Kb/fAuPetZQnhS3hnajCf9CsWesghLQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "zod": "^3.25.0 || ^4.0.0" + } + }, "node_modules/zwitch": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz", diff --git a/package.json b/package.json index eecb29c95c..161d035dbf 100644 --- a/package.json +++ b/package.json @@ -97,7 +97,7 @@ "css-loader": "^7.1.1", "eslint": "^9.30.1", "eslint-config-prettier": "^10.1.5", - "eslint-config-webpack": "^4.4.0", + "eslint-config-webpack": "^4.9.6", "eslint-plugin-import": "^2.32.0", "eslint-plugin-jsdoc": "^51.3.4", "eslint-plugin-n": "^17.21.0", diff --git a/scripts/run-tests.mjs b/scripts/run-tests.mjs index 973cb94106..53ed64ff83 100644 --- a/scripts/run-tests.mjs +++ b/scripts/run-tests.mjs @@ -37,7 +37,7 @@ for (const pattern of PATTERNS) { } } -const testFiles = [...files].sort(); +const testFiles = [...files].toSorted(); const nodeArgs = [ "--import", diff --git a/test/e2e/options-middleware.test.js b/test/e2e/options-middleware.test.js index 9419c720a4..ebfa2a0866 100644 --- a/test/e2e/options-middleware.test.js +++ b/test/e2e/options-middleware.test.js @@ -94,7 +94,7 @@ describe("handle options-request correctly", () => { htmlUrl, ); - expect(responseStatus.sort()).toEqual([200, 204]); + expect(responseStatus.toSorted()).toEqual([200, 204]); } finally { await browser.close(); await server.stop(); diff --git a/test/e2e/target.test.js b/test/e2e/target.test.js index e0578b5beb..f182fed7fb 100644 --- a/test/e2e/target.test.js +++ b/test/e2e/target.test.js @@ -18,7 +18,7 @@ const __dirname = path.dirname(fileURLToPath(import.meta.url)); const port = portsMap.target; const sortByTerm = (data, term) => - data.sort((a, b) => (a.indexOf(term) < b.indexOf(term) ? -1 : 1)); + data.toSorted((a, b) => (a.indexOf(term) < b.indexOf(term) ? -1 : 1)); describe("target", () => { const targets = [ diff --git a/test/helpers/run-browser.js b/test/helpers/run-browser.js index 547de9b256..a4010d8496 100644 --- a/test/helpers/run-browser.js +++ b/test/helpers/run-browser.js @@ -1,9 +1,9 @@ import { launch } from "puppeteer"; import { puppeteerArgs } from "./puppeteer-constants.js"; -/** @typedef {import('puppeteer').Browser} Browser */ -/** @typedef {import('puppeteer').Page} Page */ -/** @typedef {import('puppeteer').Device} Device */ +/** @typedef {import("puppeteer").Browser} Browser */ +/** @typedef {import("puppeteer").Page} Page */ +/** @typedef {import("puppeteer").Device} Device */ /** * @typedef {object} RunBrowserResult @@ -67,11 +67,11 @@ export function runPage(browser, device) { function runBrowser(device) { return new Promise((resolve, reject) => { /** - * @type {import('puppeteer').Page} + * @type {import("puppeteer").Page} */ let page; /** - * @type {import('puppeteer').Browser} + * @type {import("puppeteer").Browser} */ let browser; From a157165e3c128255693a34daefee6c37689cf544 Mon Sep 17 00:00:00 2001 From: Sebastian Beltran Date: Sat, 16 May 2026 11:02:22 -0500 Subject: [PATCH 22/29] fixup! --- lib/Server.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Server.js b/lib/Server.js index 459dbeb99a..5b526041e9 100644 --- a/lib/Server.js +++ b/lib/Server.js @@ -1074,7 +1074,7 @@ class Server { } const httpsProperties = - /** @type {keyof ServerOptions[]} */ + /** @type {(keyof ServerOptions)[]} */ (["ca", "cert", "crl", "key", "pfx"]); for (const property_ of httpsProperties) { From 0178ed9fa24e22906387622e2b56dd3d38c7ab1d Mon Sep 17 00:00:00 2001 From: Sebastian Beltran Date: Sat, 16 May 2026 11:11:26 -0500 Subject: [PATCH 23/29] refactor: dynamically import 'node:net' in Server class for improved module loading --- lib/Server.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/Server.js b/lib/Server.js index 5b526041e9..d1dec7adfc 100644 --- a/lib/Server.js +++ b/lib/Server.js @@ -1,5 +1,4 @@ import { createRequire } from "node:module"; -import net from "node:net"; import os from "node:os"; import path from "node:path"; import url, { fileURLToPath } from "node:url"; @@ -3275,6 +3274,8 @@ class Server { await this.normalizeOptions(); if (this.options.ipc) { + const { default: net } = await import("node:net"); + await /** @type {Promise} */ ( new Promise((resolve, reject) => { const socket = new net.Socket(); From 381a5e51d315d48cdebc322739020ee880cfb3f0 Mon Sep 17 00:00:00 2001 From: Sebastian Beltran Date: Sat, 16 May 2026 11:16:17 -0500 Subject: [PATCH 24/29] refactor: update type definition for onLoadQueue to ensure correct function signature --- client-src/overlay.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client-src/overlay.js b/client-src/overlay.js index db3bdf7227..6003b6194b 100644 --- a/client-src/overlay.js +++ b/client-src/overlay.js @@ -450,7 +450,7 @@ const createOverlay = (options) => { let containerElement; /** @type {HTMLDivElement | null | undefined} */ let headerElement; - /** @type {(element: HTMLDivElement) => void[]} */ + /** @type {((element: HTMLDivElement) => void)[]} */ let onLoadQueue = []; /** @type {Omit | undefined} */ let overlayTrustedTypesPolicy; From 6c504335cb8f7671d16445cff5d568493d4f13c5 Mon Sep 17 00:00:00 2001 From: Sebastian Beltran Date: Sat, 16 May 2026 11:21:57 -0500 Subject: [PATCH 25/29] fixup! --- types/lib/Server.d.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/types/lib/Server.d.ts b/types/lib/Server.d.ts index f963e8be60..3cbce6cdc2 100644 --- a/types/lib/Server.d.ts +++ b/types/lib/Server.d.ts @@ -269,10 +269,10 @@ export type ClientConfiguration = { webSocketURL?: (string | WebSocketURL) | undefined; }; export type Headers = - | Array<{ + | { key: string; value: string; - }> + }[] | Record; export type MiddlewareHandler< T extends BasicApplication = import("express").Application, @@ -304,16 +304,16 @@ export type Configuration< historyApiFallback?: (boolean | ConnectHistoryApiFallbackOptions) | undefined; bonjour?: (boolean | Record | BonjourOptions) | undefined; watchFiles?: - | (string | string[] | WatchFiles | Array) + | (string | string[] | WatchFiles | (string | WatchFiles)[]) | undefined; - static?: (boolean | string | Static | Array) | undefined; + static?: (boolean | string | Static | (string | Static)[]) | undefined; server?: (ServerType | ServerConfiguration) | undefined; app?: (() => Promise) | undefined; webSocketServer?: | (boolean | "ws" | string | WebSocketServerConfiguration) | undefined; proxy?: ProxyConfigArray | undefined; - open?: (boolean | string | Open | Array) | undefined; + open?: (boolean | string | Open | (string | Open)[]) | undefined; setupExitSignals?: boolean | undefined; client?: (boolean | ClientConfiguration) | undefined; headers?: @@ -1515,7 +1515,7 @@ declare class Server< staticWatchers: FSWatcher[]; /** * @private - * @type {{ name: string | symbol, listener: (...args: EXPECTED_ANY[]) => void}[] }} + * @type {{ name: string | symbol, listener: (...args: EXPECTED_ANY[]) => void }[]} } */ private listeners; /** From b7df6e57421cc017a8e83fd812abc76ed20e8ab7 Mon Sep 17 00:00:00 2001 From: Sebastian Beltran Date: Sat, 16 May 2026 11:49:13 -0500 Subject: [PATCH 26/29] refactor: migrate examples to ES module syntax and remove "use strict" directives - Updated all example files to use ES module imports instead of CommonJS require. - Removed unnecessary "use strict" directives from JavaScript files. - Adjusted webpack configuration files to utilize import.meta for context and URL handling. - Ensured consistent use of import statements across all examples. --- examples/README.md | 21 ++ examples/api/find-ip/app.js | 4 +- examples/api/middleware/app.js | 2 - examples/api/middleware/server.js | 8 +- examples/api/middleware/webpack.config.js | 25 +-- examples/api/simple/app.js | 2 - examples/api/simple/server.js | 8 +- examples/api/simple/webpack.config.js | 25 +-- examples/api/start-callback/app.js | 2 - examples/api/start-callback/server.js | 8 +- examples/api/start-callback/webpack.config.js | 25 +-- examples/api/start/app.js | 2 - examples/api/start/server.js | 8 +- examples/api/start/webpack.config.js | 25 +-- examples/api/stop-callback/app.js | 2 - examples/api/stop-callback/server.js | 8 +- examples/api/stop-callback/webpack.config.js | 25 +-- examples/api/stop/app.js | 2 - examples/api/stop/server.js | 8 +- examples/api/stop/webpack.config.js | 25 +-- examples/app/connect/app.js | 2 - examples/app/connect/webpack.config.js | 21 +- examples/app/hono/app.js | 2 - examples/app/hono/webpack.config.js | 99 ++++----- examples/bonjour/boolean/app.js | 2 - examples/bonjour/boolean/webpack.config.js | 19 +- examples/bonjour/object/app.js | 2 - examples/bonjour/object/webpack.config.js | 25 +-- examples/client/logging/app.js | 2 - examples/client/logging/webpack.config.js | 47 ++--- examples/client/overlay/app.js | 9 +- examples/client/overlay/create-button.js | 6 +- examples/client/overlay/webpack.config.js | 59 +++--- examples/client/progress/app.js | 2 - examples/client/progress/webpack.config.js | 21 +- examples/client/reconnect/false/app.js | 2 - .../client/reconnect/false/webpack.config.js | 21 +- examples/client/reconnect/number/app.js | 2 - .../client/reconnect/number/webpack.config.js | 21 +- examples/client/reconnect/true/app.js | 2 - .../client/reconnect/true/webpack.config.js | 21 +- examples/client/trusted-types-overlay/app.js | 2 - .../trusted-types-overlay/webpack.config.js | 43 ++-- examples/client/web-socket-url/app.js | 2 - .../client/web-socket-url/webpack.config.js | 25 +-- examples/compression/false/app.js | 2 - examples/compression/false/webpack.config.js | 19 +- examples/compression/true/app.js | 2 - examples/compression/true/webpack.config.js | 19 +- examples/default-cjs/README.md | 19 ++ examples/default-cjs/app.js | 4 + examples/default-cjs/webpack.config.cjs | 31 +++ examples/default/app.js | 4 +- examples/default/webpack.config.js | 35 ++-- examples/dev-middleware/app.js | 2 - examples/dev-middleware/webpack.config.js | 25 +-- examples/general/config-array/app.js | 4 +- .../general/config-array/webpack.config.js | 39 ++-- examples/general/config-promise/app.js | 2 - .../general/config-promise/webpack.config.js | 19 +- examples/general/proxy-advanced/app.js | 2 - .../general/proxy-advanced/webpack.config.js | 51 ++--- examples/general/proxy-hot-reload/app.js | 2 - .../general/proxy-hot-reload/proxy-config.js | 6 +- .../proxy-hot-reload/webpack.config.js | 41 ++-- examples/general/proxy-simple/app.js | 2 - .../general/proxy-simple/webpack.config.js | 21 +- examples/general/universal-config/client.js | 2 - examples/general/universal-config/server.js | 2 - .../universal-config/webpack.config.js | 25 +-- examples/general/webworker/web.js | 2 - examples/general/webworker/webpack.config.js | 21 +- examples/general/webworker/worker.js | 2 - examples/headers/array/app.js | 2 - examples/headers/array/webpack.config.js | 37 ++-- examples/headers/function/app.js | 2 - examples/headers/function/webpack.config.js | 19 +- examples/headers/object/app.js | 2 - examples/headers/object/webpack.config.js | 21 +- examples/history-api-fallback/app.js | 2 - .../history-api-fallback/webpack.config.js | 19 +- examples/hmr/boolean/app.js | 8 +- examples/hmr/boolean/example.js | 2 - examples/hmr/boolean/webpack.config.js | 19 +- examples/hmr/only/app.js | 8 +- examples/hmr/only/example.js | 2 - examples/hmr/only/webpack.config.js | 19 +- examples/host-and-port/app.js | 2 - examples/host-and-port/webpack.config.js | 15 +- examples/ipc/app.js | 2 - examples/ipc/webpack.config.js | 53 ++--- examples/multi-compiler/app.js | 2 - examples/multi-compiler/webpack.config.js | 17 +- examples/node-false/app.js | 2 - examples/node-false/webpack.config.js | 17 +- examples/on-listening/app.js | 2 - examples/on-listening/webpack.config.js | 23 ++- examples/open-target-multiple/app1.js | 2 - examples/open-target-multiple/app2.js | 2 - .../open-target-multiple/webpack.config.js | 66 +++--- examples/open-target/app.js | 2 - examples/open-target/webpack.config.js | 31 +-- examples/proxy/app.js | 2 - examples/proxy/webpack.config.js | 35 ++-- examples/server/http2/app.js | 2 - examples/server/http2/webpack.config.js | 25 +-- examples/server/https/app.js | 2 - examples/server/https/webpack.config.js | 33 +-- examples/setup-middlewares/app.js | 2 - examples/setup-middlewares/webpack.config.js | 55 ++--- examples/util.js | 188 +++++++++--------- examples/watch-static/app.js | 2 - examples/watch-static/webpack.config.js | 19 +- examples/web-socket-server/ws/app.js | 2 - .../web-socket-server/ws/webpack.config.js | 19 +- 115 files changed, 947 insertions(+), 938 deletions(-) create mode 100644 examples/default-cjs/README.md create mode 100644 examples/default-cjs/app.js create mode 100644 examples/default-cjs/webpack.config.cjs diff --git a/examples/README.md b/examples/README.md index 2fd15a53ed..ff19cd3746 100644 --- a/examples/README.md +++ b/examples/README.md @@ -16,6 +16,27 @@ An example should be as minimal as possible and consists of at least: API examples can be found in the `api` directory. These examples demonstrate how to access and run `webpack-dev-server` directly in your application / script. +## Module format + +Examples are written as ES modules (`import` / `export`) because the project's +`package.json` sets `"type": "module"`. The shared helper `util.js` exports a +`setup` function that each `webpack.config.js` calls like this: + +```js +import { setup } from "../util.js"; + +export default setup( + { + context: import.meta.dirname, + entry: "./app.js", + }, + import.meta.url, +); +``` + +If you still need a CommonJS configuration, see [`default-cjs/`](./default-cjs) +for a minimal CJS example using a `.cjs` extension. + ## Notes - Each example's `webpack` config is wrapped with `util.setup`; a helper function diff --git a/examples/api/find-ip/app.js b/examples/api/find-ip/app.js index b4dc418ddc..32aabd0995 100644 --- a/examples/api/find-ip/app.js +++ b/examples/api/find-ip/app.js @@ -1,6 +1,4 @@ -"use strict"; - -const WebpackDevServer = require("../../../lib/Server"); +import WebpackDevServer from "../../../lib/Server.js"; const logInternalIPs = async () => { const localIPv4 = WebpackDevServer.findIp("v4", false); diff --git a/examples/api/middleware/app.js b/examples/api/middleware/app.js index 51cf4a396b..bb080674bb 100644 --- a/examples/api/middleware/app.js +++ b/examples/api/middleware/app.js @@ -1,5 +1,3 @@ -"use strict"; - const target = document.querySelector("#target"); target.classList.add("pass"); diff --git a/examples/api/middleware/server.js b/examples/api/middleware/server.js index 9102416371..9540272bb7 100644 --- a/examples/api/middleware/server.js +++ b/examples/api/middleware/server.js @@ -1,8 +1,6 @@ -"use strict"; - -const Webpack = require("webpack"); -const WebpackDevServer = require("../../../lib/Server"); -const webpackConfig = require("./webpack.config"); +import Webpack from "webpack"; +import WebpackDevServer from "../../../lib/Server.js"; +import webpackConfig from "./webpack.config.js"; const compiler = Webpack(webpackConfig); const devServerOptions = webpackConfig.devServer; diff --git a/examples/api/middleware/webpack.config.js b/examples/api/middleware/webpack.config.js index 74e736ae9a..2a3bc16cc8 100644 --- a/examples/api/middleware/webpack.config.js +++ b/examples/api/middleware/webpack.config.js @@ -1,16 +1,17 @@ -"use strict"; - // our setup function adds behind-the-scenes bits to the config that all of our // examples need -const { setup } = require("../../util"); +import { setup } from "../../util.js"; -module.exports = setup({ - context: __dirname, - entry: "./app.js", - output: { - filename: "bundle.js", - }, - stats: { - colors: true, +export default setup( + { + context: import.meta.dirname, + entry: "./app.js", + output: { + filename: "bundle.js", + }, + stats: { + colors: true, + }, }, -}); + import.meta.url, +); diff --git a/examples/api/simple/app.js b/examples/api/simple/app.js index 550a73c229..cf3af3c2ea 100644 --- a/examples/api/simple/app.js +++ b/examples/api/simple/app.js @@ -1,5 +1,3 @@ -"use strict"; - const target = document.querySelector("#target"); target.classList.add("pass"); diff --git a/examples/api/simple/server.js b/examples/api/simple/server.js index 6aa74ce368..cc66e7166c 100644 --- a/examples/api/simple/server.js +++ b/examples/api/simple/server.js @@ -1,8 +1,6 @@ -"use strict"; - -const Webpack = require("webpack"); -const WebpackDevServer = require("../../../lib/Server"); -const webpackConfig = require("./webpack.config"); +import Webpack from "webpack"; +import WebpackDevServer from "../../../lib/Server.js"; +import webpackConfig from "./webpack.config.js"; const compiler = Webpack(webpackConfig); const devServerOptions = { ...webpackConfig.devServer, open: true }; diff --git a/examples/api/simple/webpack.config.js b/examples/api/simple/webpack.config.js index 74e736ae9a..2a3bc16cc8 100644 --- a/examples/api/simple/webpack.config.js +++ b/examples/api/simple/webpack.config.js @@ -1,16 +1,17 @@ -"use strict"; - // our setup function adds behind-the-scenes bits to the config that all of our // examples need -const { setup } = require("../../util"); +import { setup } from "../../util.js"; -module.exports = setup({ - context: __dirname, - entry: "./app.js", - output: { - filename: "bundle.js", - }, - stats: { - colors: true, +export default setup( + { + context: import.meta.dirname, + entry: "./app.js", + output: { + filename: "bundle.js", + }, + stats: { + colors: true, + }, }, -}); + import.meta.url, +); diff --git a/examples/api/start-callback/app.js b/examples/api/start-callback/app.js index 51cf4a396b..bb080674bb 100644 --- a/examples/api/start-callback/app.js +++ b/examples/api/start-callback/app.js @@ -1,5 +1,3 @@ -"use strict"; - const target = document.querySelector("#target"); target.classList.add("pass"); diff --git a/examples/api/start-callback/server.js b/examples/api/start-callback/server.js index 116ef47ad5..832b4c680f 100644 --- a/examples/api/start-callback/server.js +++ b/examples/api/start-callback/server.js @@ -1,8 +1,6 @@ -"use strict"; - -const Webpack = require("webpack"); -const WebpackDevServer = require("../../../lib/Server"); -const webpackConfig = require("./webpack.config"); +import Webpack from "webpack"; +import WebpackDevServer from "../../../lib/Server.js"; +import webpackConfig from "./webpack.config.js"; const compiler = Webpack(webpackConfig); const devServerOptions = { ...webpackConfig.devServer, open: true }; diff --git a/examples/api/start-callback/webpack.config.js b/examples/api/start-callback/webpack.config.js index 74e736ae9a..2a3bc16cc8 100644 --- a/examples/api/start-callback/webpack.config.js +++ b/examples/api/start-callback/webpack.config.js @@ -1,16 +1,17 @@ -"use strict"; - // our setup function adds behind-the-scenes bits to the config that all of our // examples need -const { setup } = require("../../util"); +import { setup } from "../../util.js"; -module.exports = setup({ - context: __dirname, - entry: "./app.js", - output: { - filename: "bundle.js", - }, - stats: { - colors: true, +export default setup( + { + context: import.meta.dirname, + entry: "./app.js", + output: { + filename: "bundle.js", + }, + stats: { + colors: true, + }, }, -}); + import.meta.url, +); diff --git a/examples/api/start/app.js b/examples/api/start/app.js index 51cf4a396b..bb080674bb 100644 --- a/examples/api/start/app.js +++ b/examples/api/start/app.js @@ -1,5 +1,3 @@ -"use strict"; - const target = document.querySelector("#target"); target.classList.add("pass"); diff --git a/examples/api/start/server.js b/examples/api/start/server.js index 11659156e2..313e6e60bd 100644 --- a/examples/api/start/server.js +++ b/examples/api/start/server.js @@ -1,8 +1,6 @@ -"use strict"; - -const Webpack = require("webpack"); -const WebpackDevServer = require("../../../lib/Server"); -const webpackConfig = require("./webpack.config"); +import Webpack from "webpack"; +import WebpackDevServer from "../../../lib/Server.js"; +import webpackConfig from "./webpack.config.js"; const compiler = Webpack(webpackConfig); const devServerOptions = { ...webpackConfig.devServer, open: true }; diff --git a/examples/api/start/webpack.config.js b/examples/api/start/webpack.config.js index 74e736ae9a..2a3bc16cc8 100644 --- a/examples/api/start/webpack.config.js +++ b/examples/api/start/webpack.config.js @@ -1,16 +1,17 @@ -"use strict"; - // our setup function adds behind-the-scenes bits to the config that all of our // examples need -const { setup } = require("../../util"); +import { setup } from "../../util.js"; -module.exports = setup({ - context: __dirname, - entry: "./app.js", - output: { - filename: "bundle.js", - }, - stats: { - colors: true, +export default setup( + { + context: import.meta.dirname, + entry: "./app.js", + output: { + filename: "bundle.js", + }, + stats: { + colors: true, + }, }, -}); + import.meta.url, +); diff --git a/examples/api/stop-callback/app.js b/examples/api/stop-callback/app.js index 8ac9db4eaf..7fb3dafe4e 100644 --- a/examples/api/stop-callback/app.js +++ b/examples/api/stop-callback/app.js @@ -1,5 +1,3 @@ -"use strict"; - const target = document.querySelector("#target"); target.classList.add("pass"); diff --git a/examples/api/stop-callback/server.js b/examples/api/stop-callback/server.js index 09656cd418..ab83622c54 100644 --- a/examples/api/stop-callback/server.js +++ b/examples/api/stop-callback/server.js @@ -1,8 +1,6 @@ -"use strict"; - -const Webpack = require("webpack"); -const WebpackDevServer = require("../../../lib/Server"); -const webpackConfig = require("./webpack.config"); +import Webpack from "webpack"; +import WebpackDevServer from "../../../lib/Server.js"; +import webpackConfig from "./webpack.config.js"; const compiler = Webpack(webpackConfig); const devServerOptions = { ...webpackConfig.devServer, open: true }; diff --git a/examples/api/stop-callback/webpack.config.js b/examples/api/stop-callback/webpack.config.js index 74e736ae9a..2a3bc16cc8 100644 --- a/examples/api/stop-callback/webpack.config.js +++ b/examples/api/stop-callback/webpack.config.js @@ -1,16 +1,17 @@ -"use strict"; - // our setup function adds behind-the-scenes bits to the config that all of our // examples need -const { setup } = require("../../util"); +import { setup } from "../../util.js"; -module.exports = setup({ - context: __dirname, - entry: "./app.js", - output: { - filename: "bundle.js", - }, - stats: { - colors: true, +export default setup( + { + context: import.meta.dirname, + entry: "./app.js", + output: { + filename: "bundle.js", + }, + stats: { + colors: true, + }, }, -}); + import.meta.url, +); diff --git a/examples/api/stop/app.js b/examples/api/stop/app.js index 8ac9db4eaf..7fb3dafe4e 100644 --- a/examples/api/stop/app.js +++ b/examples/api/stop/app.js @@ -1,5 +1,3 @@ -"use strict"; - const target = document.querySelector("#target"); target.classList.add("pass"); diff --git a/examples/api/stop/server.js b/examples/api/stop/server.js index 6439456ff2..d7bf6bf5ae 100644 --- a/examples/api/stop/server.js +++ b/examples/api/stop/server.js @@ -1,8 +1,6 @@ -"use strict"; - -const Webpack = require("webpack"); -const WebpackDevServer = require("../../../lib/Server"); -const webpackConfig = require("./webpack.config"); +import Webpack from "webpack"; +import WebpackDevServer from "../../../lib/Server.js"; +import webpackConfig from "./webpack.config.js"; const compiler = Webpack(webpackConfig); const devServerOptions = { ...webpackConfig.devServer, open: true }; diff --git a/examples/api/stop/webpack.config.js b/examples/api/stop/webpack.config.js index 74e736ae9a..2a3bc16cc8 100644 --- a/examples/api/stop/webpack.config.js +++ b/examples/api/stop/webpack.config.js @@ -1,16 +1,17 @@ -"use strict"; - // our setup function adds behind-the-scenes bits to the config that all of our // examples need -const { setup } = require("../../util"); +import { setup } from "../../util.js"; -module.exports = setup({ - context: __dirname, - entry: "./app.js", - output: { - filename: "bundle.js", - }, - stats: { - colors: true, +export default setup( + { + context: import.meta.dirname, + entry: "./app.js", + output: { + filename: "bundle.js", + }, + stats: { + colors: true, + }, }, -}); + import.meta.url, +); diff --git a/examples/app/connect/app.js b/examples/app/connect/app.js index 51cf4a396b..bb080674bb 100644 --- a/examples/app/connect/app.js +++ b/examples/app/connect/app.js @@ -1,5 +1,3 @@ -"use strict"; - const target = document.querySelector("#target"); target.classList.add("pass"); diff --git a/examples/app/connect/webpack.config.js b/examples/app/connect/webpack.config.js index 0b7dd7bc23..f54d6f5bc4 100644 --- a/examples/app/connect/webpack.config.js +++ b/examples/app/connect/webpack.config.js @@ -1,14 +1,15 @@ -"use strict"; - // our setup function adds behind-the-scenes bits to the config that all of our // examples need -const connect = require("connect"); -const { setup } = require("../../util"); +import connect from "connect"; +import { setup } from "../../util.js"; -module.exports = setup({ - context: __dirname, - entry: "./app.js", - devServer: { - app: () => connect(), +export default setup( + { + context: import.meta.dirname, + entry: "./app.js", + devServer: { + app: () => connect(), + }, }, -}); + import.meta.url, +); diff --git a/examples/app/hono/app.js b/examples/app/hono/app.js index 51cf4a396b..bb080674bb 100644 --- a/examples/app/hono/app.js +++ b/examples/app/hono/app.js @@ -1,5 +1,3 @@ -"use strict"; - const target = document.querySelector("#target"); target.classList.add("pass"); diff --git a/examples/app/hono/webpack.config.js b/examples/app/hono/webpack.config.js index dff0e98988..7a9682ea46 100644 --- a/examples/app/hono/webpack.config.js +++ b/examples/app/hono/webpack.config.js @@ -1,55 +1,56 @@ -"use strict"; - -const { createAdaptorServer } = require("@hono/node-server"); +import { createAdaptorServer } from "@hono/node-server"; // eslint-disable-next-line import/no-unresolved -const { serveStatic } = require("@hono/node-server/serve-static"); -const { Hono } = require("hono"); -const wdm = require("webpack-dev-middleware"); -const { setup } = require("../../util"); +import { serveStatic } from "@hono/node-server/serve-static"; +import { Hono } from "hono"; +import wdm from "webpack-dev-middleware"; +import { setup } from "../../util.js"; // our setup function adds behind-the-scenes bits to the config that all of our // examples need -module.exports = setup({ - context: __dirname, - entry: "./app.js", - devServer: { - // WARNING: - // - // You always need to set up middlewares which you required for your app, - // built-in middlewares (like `history-api-fallback`/etc) doesn't work by default with `hono` - setupMiddlewares: (_, devServer) => [ - { - name: "webpack-dev-middleware", - middleware: wdm.honoWrapper(devServer.compiler), - }, - { - name: "static", - path: "/.assets/*", - middleware: serveStatic({ - root: "../../.assets", - rewriteRequestPath: (item) => item.replace(/^\/\.assets\//, "/"), +export default setup( + { + context: import.meta.dirname, + entry: "./app.js", + devServer: { + // WARNING: + // + // You always need to set up middlewares which you required for your app, + // built-in middlewares (like `history-api-fallback`/etc) doesn't work by default with `hono` + setupMiddlewares: (_, devServer) => [ + { + name: "webpack-dev-middleware", + middleware: wdm.honoWrapper(devServer.compiler), + }, + { + name: "static", + path: "/.assets/*", + middleware: serveStatic({ + root: "../../.assets", + rewriteRequestPath: (item) => item.replace(/^\/\.assets\//, "/"), + }), + }, + ], + app: () => new Hono(), + server: (_, app) => + createAdaptorServer({ + fetch: app.fetch, + // + // Uncomment for `https` + // createServer: require('node:https').createServer, + // serverOptions: { + // key: fs.readFileSync("./ssl/localhost-privkey.pem"), + // cert: fs.readFileSync("./ssl/localhost-cert.pem"), + // }, + // + // Uncomment for `http2` + // createServer: require("node:http2").createSecureServer, + // serverOptions: { + // allowHTTP1: true, + // key: require("fs").readFileSync("./ssl/localhost-privkey.pem"), + // cert: require("fs").readFileSync("./ssl/localhost-cert.pem"), + // }, }), - }, - ], - app: () => new Hono(), - server: (_, app) => - createAdaptorServer({ - fetch: app.fetch, - // - // Uncomment for `https` - // createServer: require('node:https').createServer, - // serverOptions: { - // key: fs.readFileSync("./ssl/localhost-privkey.pem"), - // cert: fs.readFileSync("./ssl/localhost-cert.pem"), - // }, - // - // Uncomment for `http2` - // createServer: require("node:http2").createSecureServer, - // serverOptions: { - // allowHTTP1: true, - // key: require("fs").readFileSync("./ssl/localhost-privkey.pem"), - // cert: require("fs").readFileSync("./ssl/localhost-cert.pem"), - // }, - }), + }, }, -}); + import.meta.url, +); diff --git a/examples/bonjour/boolean/app.js b/examples/bonjour/boolean/app.js index f8e58b3b28..38f92d6076 100644 --- a/examples/bonjour/boolean/app.js +++ b/examples/bonjour/boolean/app.js @@ -1,5 +1,3 @@ -"use strict"; - const target = document.querySelector("#target"); target.innerHTML = "Please check your Zeroconf service."; diff --git a/examples/bonjour/boolean/webpack.config.js b/examples/bonjour/boolean/webpack.config.js index 34550ba9a1..fa0c4e0c13 100644 --- a/examples/bonjour/boolean/webpack.config.js +++ b/examples/bonjour/boolean/webpack.config.js @@ -1,13 +1,14 @@ -"use strict"; - // our setup function adds behind-the-scenes bits to the config that all of our // examples need -const { setup } = require("../../util"); +import { setup } from "../../util.js"; -module.exports = setup({ - context: __dirname, - entry: "./app.js", - devServer: { - bonjour: true, +export default setup( + { + context: import.meta.dirname, + entry: "./app.js", + devServer: { + bonjour: true, + }, }, -}); + import.meta.url, +); diff --git a/examples/bonjour/object/app.js b/examples/bonjour/object/app.js index f8e58b3b28..38f92d6076 100644 --- a/examples/bonjour/object/app.js +++ b/examples/bonjour/object/app.js @@ -1,5 +1,3 @@ -"use strict"; - const target = document.querySelector("#target"); target.innerHTML = "Please check your Zeroconf service."; diff --git a/examples/bonjour/object/webpack.config.js b/examples/bonjour/object/webpack.config.js index 80e0150a65..da7b85af49 100644 --- a/examples/bonjour/object/webpack.config.js +++ b/examples/bonjour/object/webpack.config.js @@ -1,17 +1,18 @@ -"use strict"; - // our setup function adds behind-the-scenes bits to the config that all of our // examples need -const { setup } = require("../../util"); +import { setup } from "../../util.js"; -module.exports = setup({ - context: __dirname, - entry: "./app.js", - devServer: { - bonjour: { - name: "webpack-dev-server", - type: "https", - subtype: "webpack", +export default setup( + { + context: import.meta.dirname, + entry: "./app.js", + devServer: { + bonjour: { + name: "webpack-dev-server", + type: "https", + subtype: "webpack", + }, }, }, -}); + import.meta.url, +); diff --git a/examples/client/logging/app.js b/examples/client/logging/app.js index 51cf4a396b..bb080674bb 100644 --- a/examples/client/logging/app.js +++ b/examples/client/logging/app.js @@ -1,5 +1,3 @@ -"use strict"; - const target = document.querySelector("#target"); target.classList.add("pass"); diff --git a/examples/client/logging/webpack.config.js b/examples/client/logging/webpack.config.js index c5f88ce70e..cb3ccb99d7 100644 --- a/examples/client/logging/webpack.config.js +++ b/examples/client/logging/webpack.config.js @@ -1,29 +1,30 @@ -"use strict"; - // our setup function adds behind-the-scenes bits to the config that all of our // examples need -const { setup } = require("../../util"); +import { setup } from "../../util.js"; -module.exports = setup({ - context: __dirname, - entry: "./app.js", - plugins: [ - { - apply(compiler) { - compiler.hooks.thisCompilation.tap( - "warnings-webpack-plugin", - (compilation) => { - compilation.warnings.push( - new Error("Manual warnings produced during compilation."), - ); - }, - ); +export default setup( + { + context: import.meta.dirname, + entry: "./app.js", + plugins: [ + { + apply(compiler) { + compiler.hooks.thisCompilation.tap( + "warnings-webpack-plugin", + (compilation) => { + compilation.warnings.push( + new Error("Manual warnings produced during compilation."), + ); + }, + ); + }, + }, + ], + devServer: { + client: { + logging: "info", }, - }, - ], - devServer: { - client: { - logging: "info", }, }, -}); + import.meta.url, +); diff --git a/examples/client/overlay/app.js b/examples/client/overlay/app.js index 0303b0653f..6ff0610231 100644 --- a/examples/client/overlay/app.js +++ b/examples/client/overlay/app.js @@ -1,6 +1,6 @@ -"use strict"; - -const createButton = require("./create-button"); +import createButton from "./create-button.js"; +// eslint-disable-next-line import/no-unresolved, import/extensions +import invalid from "./invalid.js"; /** * @param {string} errorMessage @@ -46,9 +46,6 @@ target.insertAdjacentElement( }), ); -// eslint-disable-next-line import/no-unresolved, import/extensions -const invalid = require("./invalid.js"); - console.log(invalid); target.classList.add("pass"); target.innerHTML = "Success!"; diff --git a/examples/client/overlay/create-button.js b/examples/client/overlay/create-button.js index 4631083de9..06019deacd 100644 --- a/examples/client/overlay/create-button.js +++ b/examples/client/overlay/create-button.js @@ -1,15 +1,13 @@ -"use strict"; - /** * @param {string} label * @param {() => void} onClick * @returns HTMLButtonElement */ -module.exports = function createButton(label, onClick) { +export default function createButton(label, onClick) { const button = document.createElement("button"); button.addEventListener("click", onClick); button.innerHTML = label; return button; -}; +} diff --git a/examples/client/overlay/webpack.config.js b/examples/client/overlay/webpack.config.js index 46d34de85f..9b87039cd6 100644 --- a/examples/client/overlay/webpack.config.js +++ b/examples/client/overlay/webpack.config.js @@ -1,41 +1,42 @@ -"use strict"; - // our setup function adds behind-the-scenes bits to the config that all of our // examples need -const { setup } = require("../../util"); +import { setup } from "../../util.js"; -module.exports = setup({ - context: __dirname, - // create error for overlay - entry: "./app.js", - devServer: { - client: { - overlay: { - warnings: false, - runtimeErrors: (msg) => { - if (msg) { - if (msg instanceof DOMException && msg.name === "AbortError") { - return false; - } +export default setup( + { + context: import.meta.dirname, + // create error for overlay + entry: "./app.js", + devServer: { + client: { + overlay: { + warnings: false, + runtimeErrors: (msg) => { + if (msg) { + if (msg instanceof DOMException && msg.name === "AbortError") { + return false; + } - let msgString; + let msgString; - if (msg instanceof Error) { - msgString = msg.message; - } else if (typeof msg === "string") { - msgString = msg; - } + if (msg instanceof Error) { + msgString = msg.message; + } else if (typeof msg === "string") { + msgString = msg; + } - if (msgString) { - return !/something/i.test(msgString); + if (msgString) { + return !/something/i.test(msgString); + } } - } - return true; + return true; + }, }, }, }, + // uncomment to test for IE + // target: ["web", "es5"], }, - // uncomment to test for IE - // target: ["web", "es5"], -}); + import.meta.url, +); diff --git a/examples/client/progress/app.js b/examples/client/progress/app.js index 51cf4a396b..bb080674bb 100644 --- a/examples/client/progress/app.js +++ b/examples/client/progress/app.js @@ -1,5 +1,3 @@ -"use strict"; - const target = document.querySelector("#target"); target.classList.add("pass"); diff --git a/examples/client/progress/webpack.config.js b/examples/client/progress/webpack.config.js index d3f044a064..018f022ed7 100644 --- a/examples/client/progress/webpack.config.js +++ b/examples/client/progress/webpack.config.js @@ -1,15 +1,16 @@ -"use strict"; - // our setup function adds behind-the-scenes bits to the config that all of our // examples need -const { setup } = require("../../util"); +import { setup } from "../../util.js"; -module.exports = setup({ - context: __dirname, - entry: "./app.js", - devServer: { - client: { - progress: true, +export default setup( + { + context: import.meta.dirname, + entry: "./app.js", + devServer: { + client: { + progress: true, + }, }, }, -}); + import.meta.url, +); diff --git a/examples/client/reconnect/false/app.js b/examples/client/reconnect/false/app.js index f489bd6f33..f6b8a060fb 100644 --- a/examples/client/reconnect/false/app.js +++ b/examples/client/reconnect/false/app.js @@ -1,5 +1,3 @@ -"use strict"; - const target = document.querySelector("#target"); target.classList.add("pass"); diff --git a/examples/client/reconnect/false/webpack.config.js b/examples/client/reconnect/false/webpack.config.js index 4d9ffc4eaa..11d38a5b52 100644 --- a/examples/client/reconnect/false/webpack.config.js +++ b/examples/client/reconnect/false/webpack.config.js @@ -1,15 +1,16 @@ -"use strict"; - // our setup function adds behind-the-scenes bits to the config that all of our // examples need -const { setup } = require("../../../util"); +import { setup } from "../../../util.js"; -module.exports = setup({ - context: __dirname, - entry: "./app.js", - devServer: { - client: { - reconnect: false, +export default setup( + { + context: import.meta.dirname, + entry: "./app.js", + devServer: { + client: { + reconnect: false, + }, }, }, -}); + import.meta.url, +); diff --git a/examples/client/reconnect/number/app.js b/examples/client/reconnect/number/app.js index f489bd6f33..f6b8a060fb 100644 --- a/examples/client/reconnect/number/app.js +++ b/examples/client/reconnect/number/app.js @@ -1,5 +1,3 @@ -"use strict"; - const target = document.querySelector("#target"); target.classList.add("pass"); diff --git a/examples/client/reconnect/number/webpack.config.js b/examples/client/reconnect/number/webpack.config.js index 831deb76ff..aa4c65072a 100644 --- a/examples/client/reconnect/number/webpack.config.js +++ b/examples/client/reconnect/number/webpack.config.js @@ -1,15 +1,16 @@ -"use strict"; - // our setup function adds behind-the-scenes bits to the config that all of our // examples need -const { setup } = require("../../../util"); +import { setup } from "../../../util.js"; -module.exports = setup({ - context: __dirname, - entry: "./app.js", - devServer: { - client: { - reconnect: 2, +export default setup( + { + context: import.meta.dirname, + entry: "./app.js", + devServer: { + client: { + reconnect: 2, + }, }, }, -}); + import.meta.url, +); diff --git a/examples/client/reconnect/true/app.js b/examples/client/reconnect/true/app.js index f489bd6f33..f6b8a060fb 100644 --- a/examples/client/reconnect/true/app.js +++ b/examples/client/reconnect/true/app.js @@ -1,5 +1,3 @@ -"use strict"; - const target = document.querySelector("#target"); target.classList.add("pass"); diff --git a/examples/client/reconnect/true/webpack.config.js b/examples/client/reconnect/true/webpack.config.js index abb446d1a9..e57b74f940 100644 --- a/examples/client/reconnect/true/webpack.config.js +++ b/examples/client/reconnect/true/webpack.config.js @@ -1,15 +1,16 @@ -"use strict"; - // our setup function adds behind-the-scenes bits to the config that all of our // examples need -const { setup } = require("../../../util"); +import { setup } from "../../../util.js"; -module.exports = setup({ - context: __dirname, - entry: "./app.js", - devServer: { - client: { - reconnect: true, +export default setup( + { + context: import.meta.dirname, + entry: "./app.js", + devServer: { + client: { + reconnect: true, + }, }, }, -}); + import.meta.url, +); diff --git a/examples/client/trusted-types-overlay/app.js b/examples/client/trusted-types-overlay/app.js index 130fdcd715..567986ed77 100644 --- a/examples/client/trusted-types-overlay/app.js +++ b/examples/client/trusted-types-overlay/app.js @@ -1,5 +1,3 @@ -"use strict"; - const target = document.querySelector("#target"); target.classList.add("pass"); diff --git a/examples/client/trusted-types-overlay/webpack.config.js b/examples/client/trusted-types-overlay/webpack.config.js index af962f1ff8..75b1fdfc68 100644 --- a/examples/client/trusted-types-overlay/webpack.config.js +++ b/examples/client/trusted-types-overlay/webpack.config.js @@ -1,35 +1,36 @@ -"use strict"; - -const path = require("node:path"); -const HtmlWebpackPlugin = require("html-webpack-plugin"); +import path from "node:path"; +import HtmlWebpackPlugin from "html-webpack-plugin"; // our setup function adds behind-the-scenes bits to the config that all of our // examples need -const { setup } = require("../../util"); +import { setup } from "../../util.js"; -const config = setup({ - context: __dirname, - // create error for overlay - entry: "./app.js", - output: { - trustedTypes: { policyName: "webpack" }, - }, - devServer: { - headers: { - "Content-Security-Policy": "require-trusted-types-for 'script'", +const config = setup( + { + context: import.meta.dirname, + // create error for overlay + entry: "./app.js", + output: { + trustedTypes: { policyName: "webpack" }, }, - client: { - overlay: { - trustedTypesPolicyName: "webpack#dev-overlay", + devServer: { + headers: { + "Content-Security-Policy": "require-trusted-types-for 'script'", + }, + client: { + overlay: { + trustedTypesPolicyName: "webpack#dev-overlay", + }, }, }, }, -}); + import.meta.url, +); // overwrite the index.html with our own to enable Trusted Types config.plugins[0] = new HtmlWebpackPlugin({ filename: "index.html", - template: path.join(__dirname, "./layout.html"), + template: path.join(import.meta.dirname, "./layout.html"), title: "trusted types overlay", }); -module.exports = config; +export default config; diff --git a/examples/client/web-socket-url/app.js b/examples/client/web-socket-url/app.js index b5ea7b6280..1d4fc6f47f 100644 --- a/examples/client/web-socket-url/app.js +++ b/examples/client/web-socket-url/app.js @@ -1,5 +1,3 @@ -"use strict"; - const target = document.querySelector("#target"); target.innerHTML = diff --git a/examples/client/web-socket-url/webpack.config.js b/examples/client/web-socket-url/webpack.config.js index 8fe4b5d921..9b626dbbb7 100644 --- a/examples/client/web-socket-url/webpack.config.js +++ b/examples/client/web-socket-url/webpack.config.js @@ -1,17 +1,18 @@ -"use strict"; - // our setup function adds behind-the-scenes bits to the config that all of our // examples need -const { setup } = require("../../util"); +import { setup } from "../../util.js"; -module.exports = setup({ - context: __dirname, - entry: "./app.js", - devServer: { - host: "0.0.0.0", - client: { - webSocketURL: "ws://localhost:8080", +export default setup( + { + context: import.meta.dirname, + entry: "./app.js", + devServer: { + host: "0.0.0.0", + client: { + webSocketURL: "ws://localhost:8080", + }, + allowedHosts: "all", }, - allowedHosts: "all", }, -}); + import.meta.url, +); diff --git a/examples/compression/false/app.js b/examples/compression/false/app.js index 51cf4a396b..bb080674bb 100644 --- a/examples/compression/false/app.js +++ b/examples/compression/false/app.js @@ -1,5 +1,3 @@ -"use strict"; - const target = document.querySelector("#target"); target.classList.add("pass"); diff --git a/examples/compression/false/webpack.config.js b/examples/compression/false/webpack.config.js index 1f76cb6172..25bc281a4c 100644 --- a/examples/compression/false/webpack.config.js +++ b/examples/compression/false/webpack.config.js @@ -1,13 +1,14 @@ -"use strict"; - // our setup function adds behind-the-scenes bits to the config that all of our // examples need -const { setup } = require("../../util"); +import { setup } from "../../util.js"; -module.exports = setup({ - context: __dirname, - entry: "./app.js", - devServer: { - compress: false, +export default setup( + { + context: import.meta.dirname, + entry: "./app.js", + devServer: { + compress: false, + }, }, -}); + import.meta.url, +); diff --git a/examples/compression/true/app.js b/examples/compression/true/app.js index 51cf4a396b..bb080674bb 100644 --- a/examples/compression/true/app.js +++ b/examples/compression/true/app.js @@ -1,5 +1,3 @@ -"use strict"; - const target = document.querySelector("#target"); target.classList.add("pass"); diff --git a/examples/compression/true/webpack.config.js b/examples/compression/true/webpack.config.js index fb66c73b76..a2c8117666 100644 --- a/examples/compression/true/webpack.config.js +++ b/examples/compression/true/webpack.config.js @@ -1,13 +1,14 @@ -"use strict"; - // our setup function adds behind-the-scenes bits to the config that all of our // examples need -const { setup } = require("../../util"); +import { setup } from "../../util.js"; -module.exports = setup({ - context: __dirname, - entry: "./app.js", - devServer: { - compress: true, +export default setup( + { + context: import.meta.dirname, + entry: "./app.js", + devServer: { + compress: true, + }, }, -}); + import.meta.url, +); diff --git a/examples/default-cjs/README.md b/examples/default-cjs/README.md new file mode 100644 index 0000000000..b5f50c35f5 --- /dev/null +++ b/examples/default-cjs/README.md @@ -0,0 +1,19 @@ +## CommonJS Example + +This example demonstrates that `webpack-dev-server` still works with a +CommonJS configuration. The rest of the examples have been migrated to +ESM; this one is intentionally kept in CJS for users who haven't migrated +yet. + +The webpack config is named `webpack.config.cjs` (with the explicit `.cjs` +extension) because the project's `package.json` has `"type": "module"`, +which makes plain `.js` files ESM by default. + +```console +npx webpack serve --open --config webpack.config.cjs +``` + +## What Should Happen + +1. The script should open `http://localhost:8080/` in your default browser. +2. You should see the text on the page change to `Success from CommonJS example!`. diff --git a/examples/default-cjs/app.js b/examples/default-cjs/app.js new file mode 100644 index 0000000000..79dbc3e7cb --- /dev/null +++ b/examples/default-cjs/app.js @@ -0,0 +1,4 @@ +const target = document.querySelector("#target"); + +target.classList.add("pass"); +target.innerHTML = "Success from CommonJS example!"; diff --git a/examples/default-cjs/webpack.config.cjs b/examples/default-cjs/webpack.config.cjs new file mode 100644 index 0000000000..5fdb946abd --- /dev/null +++ b/examples/default-cjs/webpack.config.cjs @@ -0,0 +1,31 @@ +"use strict"; + +// CommonJS variant of the default example. +// Demonstrates that webpack-dev-server still supports CJS configs even +// though the rest of the examples use ESM. +// +// The file uses the `.cjs` extension because the project's package.json +// has `"type": "module"`, which makes plain `.js` files ESM by default. + +const path = require("node:path"); +const HtmlWebpackPlugin = require("html-webpack-plugin"); + +module.exports = { + mode: "development", + context: __dirname, + entry: "./app.js", + output: { + path: __dirname, + filename: "bundle.js", + }, + plugins: [ + new HtmlWebpackPlugin({ + filename: "index.html", + template: path.join(__dirname, "../.assets/layout.html"), + title: "CommonJS example", + }), + ], + stats: { + colors: true, + }, +}; diff --git a/examples/default/app.js b/examples/default/app.js index 6b9de75e76..f85a7d4af8 100644 --- a/examples/default/app.js +++ b/examples/default/app.js @@ -1,6 +1,4 @@ -"use strict"; - -require("./style.less"); +import "./style.less"; const target = document.querySelector("#target"); diff --git a/examples/default/webpack.config.js b/examples/default/webpack.config.js index c9fc70748f..dc966414a8 100644 --- a/examples/default/webpack.config.js +++ b/examples/default/webpack.config.js @@ -1,8 +1,6 @@ -"use strict"; - // our setup function adds behind-the-scenes bits to the config that all of our // examples need -const { setup } = require("../util"); +import { setup } from "../util.js"; const moduleRuleForPNG = { test: /\.png$/, @@ -12,18 +10,21 @@ const moduleRuleForPNG = { }, }; -module.exports = setup({ - context: __dirname, - entry: "./app.js", - module: { - rules: [ - { - test: /\.less$/, - use: ["style-loader", "css-loader", "less-loader"], - }, - { - ...moduleRuleForPNG, - }, - ], +export default setup( + { + context: import.meta.dirname, + entry: "./app.js", + module: { + rules: [ + { + test: /\.less$/, + use: ["style-loader", "css-loader", "less-loader"], + }, + { + ...moduleRuleForPNG, + }, + ], + }, }, -}); + import.meta.url, +); diff --git a/examples/dev-middleware/app.js b/examples/dev-middleware/app.js index 51cf4a396b..bb080674bb 100644 --- a/examples/dev-middleware/app.js +++ b/examples/dev-middleware/app.js @@ -1,5 +1,3 @@ -"use strict"; - const target = document.querySelector("#target"); target.classList.add("pass"); diff --git a/examples/dev-middleware/webpack.config.js b/examples/dev-middleware/webpack.config.js index 6df62b5fe1..bcd8cd0ed0 100644 --- a/examples/dev-middleware/webpack.config.js +++ b/examples/dev-middleware/webpack.config.js @@ -1,18 +1,19 @@ -"use strict"; - // our setup function adds behind-the-scenes bits to the config that all of our // examples need -const { setup } = require("../util"); +import { setup } from "../util.js"; -module.exports = setup({ - context: __dirname, - entry: "./app.js", - devServer: { - devMiddleware: { - index: false, - headers: { - "X-Custom-Header": "yes", +export default setup( + { + context: import.meta.dirname, + entry: "./app.js", + devServer: { + devMiddleware: { + index: false, + headers: { + "X-Custom-Header": "yes", + }, }, }, }, -}); + import.meta.url, +); diff --git a/examples/general/config-array/app.js b/examples/general/config-array/app.js index 95630d3839..1b4ddf4b1f 100644 --- a/examples/general/config-array/app.js +++ b/examples/general/config-array/app.js @@ -1,6 +1,4 @@ -"use strict"; - -require("./style.less"); +import "./style.less"; const target = document.querySelector("#target"); diff --git a/examples/general/config-array/webpack.config.js b/examples/general/config-array/webpack.config.js index 3c15ca173b..ea5a08b496 100644 --- a/examples/general/config-array/webpack.config.js +++ b/examples/general/config-array/webpack.config.js @@ -1,8 +1,6 @@ -"use strict"; - // our setup function adds behind-the-scenes bits to the config that all of our // examples need -const { setup } = require("../../util"); +import { setup } from "../../util.js"; const moduleRuleForPNG = { test: /\.png$/, @@ -12,24 +10,27 @@ const moduleRuleForPNG = { }, }; -module.exports = [ - setup({ - context: __dirname, - entry: "./app.js", - module: { - rules: [ - { - test: /\.less$/, - use: ["style-loader", "css-loader", "less-loader"], - }, - { - ...moduleRuleForPNG, - }, - ], +export default [ + setup( + { + context: import.meta.dirname, + entry: "./app.js", + module: { + rules: [ + { + test: /\.less$/, + use: ["style-loader", "css-loader", "less-loader"], + }, + { + ...moduleRuleForPNG, + }, + ], + }, }, - }), + import.meta.url, + ), { - context: __dirname, + context: import.meta.dirname, entry: "./app.js", output: { filename: "bundle2.js", diff --git a/examples/general/config-promise/app.js b/examples/general/config-promise/app.js index 048032a34a..38f6b57f1e 100644 --- a/examples/general/config-promise/app.js +++ b/examples/general/config-promise/app.js @@ -1,5 +1,3 @@ -"use strict"; - // Change the following line and save to see the compilation status const target = document.querySelector("#target"); diff --git a/examples/general/config-promise/webpack.config.js b/examples/general/config-promise/webpack.config.js index d6aef14331..045776d650 100644 --- a/examples/general/config-promise/webpack.config.js +++ b/examples/general/config-promise/webpack.config.js @@ -1,15 +1,16 @@ -"use strict"; - // our setup function adds behind-the-scenes bits to the config that all of our // examples need -const { setup } = require("../../util"); +import { setup } from "../../util.js"; -module.exports = new Promise((resolve) => { +export default new Promise((resolve) => { resolve( - setup({ - context: __dirname, - entry: "./app.js", - devServer: {}, - }), + setup( + { + context: import.meta.dirname, + entry: "./app.js", + devServer: {}, + }, + import.meta.url, + ), ); }); diff --git a/examples/general/proxy-advanced/app.js b/examples/general/proxy-advanced/app.js index 51cf4a396b..bb080674bb 100644 --- a/examples/general/proxy-advanced/app.js +++ b/examples/general/proxy-advanced/app.js @@ -1,5 +1,3 @@ -"use strict"; - const target = document.querySelector("#target"); target.classList.add("pass"); diff --git a/examples/general/proxy-advanced/webpack.config.js b/examples/general/proxy-advanced/webpack.config.js index e573112ea5..80a54c08d7 100644 --- a/examples/general/proxy-advanced/webpack.config.js +++ b/examples/general/proxy-advanced/webpack.config.js @@ -1,31 +1,32 @@ -"use strict"; - // our setup function adds behind-the-scenes bits to the config that all of our // examples need -const { setup } = require("../../util"); +import { setup } from "../../util.js"; -module.exports = setup({ - context: __dirname, - entry: "./app.js", - devServer: { - port: 8080, - static: { - directory: ".", - }, - proxy: [ - { - context: "/api/nope", - router: () => "http://localhost:8080", - pathRewrite: () => "/bypass.html", +export default setup( + { + context: import.meta.dirname, + entry: "./app.js", + devServer: { + port: 8080, + static: { + directory: ".", }, - { - context: "/api", - target: "http://jsonplaceholder.typicode.com/", - changeOrigin: true, - pathRewrite: { - "^/api": "", + proxy: [ + { + context: "/api/nope", + router: () => "http://localhost:8080", + pathRewrite: () => "/bypass.html", }, - }, - ], + { + context: "/api", + target: "http://jsonplaceholder.typicode.com/", + changeOrigin: true, + pathRewrite: { + "^/api": "", + }, + }, + ], + }, }, -}); + import.meta.url, +); diff --git a/examples/general/proxy-hot-reload/app.js b/examples/general/proxy-hot-reload/app.js index 51cf4a396b..bb080674bb 100644 --- a/examples/general/proxy-hot-reload/app.js +++ b/examples/general/proxy-hot-reload/app.js @@ -1,5 +1,3 @@ -"use strict"; - const target = document.querySelector("#target"); target.classList.add("pass"); diff --git a/examples/general/proxy-hot-reload/proxy-config.js b/examples/general/proxy-hot-reload/proxy-config.js index f023c51ffb..65d5e3ba3e 100644 --- a/examples/general/proxy-hot-reload/proxy-config.js +++ b/examples/general/proxy-hot-reload/proxy-config.js @@ -1,7 +1,5 @@ -"use strict"; - /**/ -module.exports = { +export default { target: "http://jsonplaceholder.typicode.com/", pathRewrite: { "^/api": "", @@ -15,7 +13,7 @@ module.exports = { /** * / - * module.exports = { + * export default { * target: 'http://reqres.in/' * }; * /* diff --git a/examples/general/proxy-hot-reload/webpack.config.js b/examples/general/proxy-hot-reload/webpack.config.js index 50e4530a23..afcdeafc88 100644 --- a/examples/general/proxy-hot-reload/webpack.config.js +++ b/examples/general/proxy-hot-reload/webpack.config.js @@ -1,10 +1,10 @@ -"use strict"; - -const fs = require("node:fs"); +import fs from "node:fs"; +import path from "node:path"; +import { pathToFileURL } from "node:url"; // our setup function adds behind-the-scenes bits to the config that all of our // examples need -const { setup } = require("../../util"); -const proxyConfig = require("./proxy-config"); +import { setup } from "../../util.js"; +import proxyConfig from "./proxy-config.js"; let proxyOptions = { context: "/api", @@ -13,10 +13,12 @@ let proxyOptions = { changeOrigin: true, }; -fs.watch("./proxy-config.js", () => { - delete require.cache[require.resolve("./proxy-config")]; +fs.watch("./proxy-config.js", async () => { try { - const newProxyConfig = require("./proxy-config"); + const cacheBustingUrl = `${ + pathToFileURL(path.resolve(import.meta.dirname, "./proxy-config.js")).href + }?t=${Date.now()}`; + const { default: newProxyConfig } = await import(cacheBustingUrl); if (proxyOptions.target !== newProxyConfig.target) { console.log("Proxy target changed:", newProxyConfig.target); @@ -32,14 +34,17 @@ fs.watch("./proxy-config.js", () => { } }); -module.exports = setup({ - context: __dirname, - entry: "./app.js", - devServer: { - proxy: [ - function proxy() { - return proxyOptions; - }, - ], +export default setup( + { + context: import.meta.dirname, + entry: "./app.js", + devServer: { + proxy: [ + function proxy() { + return proxyOptions; + }, + ], + }, }, -}); + import.meta.url, +); diff --git a/examples/general/proxy-simple/app.js b/examples/general/proxy-simple/app.js index 51cf4a396b..bb080674bb 100644 --- a/examples/general/proxy-simple/app.js +++ b/examples/general/proxy-simple/app.js @@ -1,5 +1,3 @@ -"use strict"; - const target = document.querySelector("#target"); target.classList.add("pass"); diff --git a/examples/general/proxy-simple/webpack.config.js b/examples/general/proxy-simple/webpack.config.js index 6c600f15f3..44c1237201 100644 --- a/examples/general/proxy-simple/webpack.config.js +++ b/examples/general/proxy-simple/webpack.config.js @@ -1,15 +1,16 @@ -"use strict"; - // our setup function adds behind-the-scenes bits to the config that all of our // examples need -const { setup } = require("../../util"); +import { setup } from "../../util.js"; -module.exports = setup({ - context: __dirname, - entry: "./app.js", - devServer: { - proxy: { - "/api": "http://127.0.0.1:50545", +export default setup( + { + context: import.meta.dirname, + entry: "./app.js", + devServer: { + proxy: { + "/api": "http://127.0.0.1:50545", + }, }, }, -}); + import.meta.url, +); diff --git a/examples/general/universal-config/client.js b/examples/general/universal-config/client.js index bfae6682f6..a3c4af2f8d 100644 --- a/examples/general/universal-config/client.js +++ b/examples/general/universal-config/client.js @@ -1,5 +1,3 @@ -"use strict"; - const target = document.querySelector("#target"); if (!globalThis.fetch) { diff --git a/examples/general/universal-config/server.js b/examples/general/universal-config/server.js index e865358b35..3c11a3524c 100644 --- a/examples/general/universal-config/server.js +++ b/examples/general/universal-config/server.js @@ -1,3 +1 @@ -"use strict"; - console.log("webpack-dev-server/server"); diff --git a/examples/general/universal-config/webpack.config.js b/examples/general/universal-config/webpack.config.js index cbf9a8ec7c..e37a6833f4 100644 --- a/examples/general/universal-config/webpack.config.js +++ b/examples/general/universal-config/webpack.config.js @@ -1,16 +1,17 @@ -"use strict"; +import { setup } from "../../util.js"; -const { setup } = require("../../util"); - -module.exports = [ - setup({ - mode: "development", - entry: "./client.js", - output: { - filename: "client.js", +export default [ + setup( + { + mode: "development", + entry: "./client.js", + output: { + filename: "client.js", + }, + context: import.meta.dirname, }, - context: __dirname, - }), + import.meta.url, + ), { mode: "development", target: "node", @@ -18,7 +19,7 @@ module.exports = [ output: { filename: "server.js", }, - context: __dirname, + context: import.meta.dirname, node: false, }, ]; diff --git a/examples/general/webworker/web.js b/examples/general/webworker/web.js index 058353d668..84155b0a98 100644 --- a/examples/general/webworker/web.js +++ b/examples/general/webworker/web.js @@ -1,5 +1,3 @@ -"use strict"; - /* eslint-env browser */ const worker = new Worker("worker.bundle.js"); diff --git a/examples/general/webworker/webpack.config.js b/examples/general/webworker/webpack.config.js index 9bee0a16d3..b332f30654 100644 --- a/examples/general/webworker/webpack.config.js +++ b/examples/general/webworker/webpack.config.js @@ -1,22 +1,23 @@ -"use strict"; - // our setup function adds behind-the-scenes bits to the config that all of our // examples need -const { setup } = require("../../util"); +import { setup } from "../../util.js"; -module.exports = [ - setup({ - devtool: "source-map", - target: "web", - entry: "./web.js", - }), +export default [ + setup( + { + devtool: "source-map", + target: "web", + entry: "./web.js", + }, + import.meta.url, + ), { devtool: "source-map", target: "webworker", entry: "./worker.js", output: { filename: "worker.bundle.js", - path: __dirname, + path: import.meta.dirname, }, }, ]; diff --git a/examples/general/webworker/worker.js b/examples/general/webworker/worker.js index d799292230..49b08817ca 100644 --- a/examples/general/webworker/worker.js +++ b/examples/general/webworker/worker.js @@ -1,5 +1,3 @@ -"use strict"; - /* eslint-env worker */ globalThis.onmessage = function onMessage(e) { diff --git a/examples/headers/array/app.js b/examples/headers/array/app.js index 51cf4a396b..bb080674bb 100644 --- a/examples/headers/array/app.js +++ b/examples/headers/array/app.js @@ -1,5 +1,3 @@ -"use strict"; - const target = document.querySelector("#target"); target.classList.add("pass"); diff --git a/examples/headers/array/webpack.config.js b/examples/headers/array/webpack.config.js index e2ad9d34a0..72fc5767c5 100644 --- a/examples/headers/array/webpack.config.js +++ b/examples/headers/array/webpack.config.js @@ -1,22 +1,23 @@ -"use strict"; - // our setup function adds behind-the-scenes bits to the config that all of our // examples need -const { setup } = require("../../util"); +import { setup } from "../../util.js"; -module.exports = setup({ - context: __dirname, - entry: "./app.js", - devServer: { - headers: [ - { - key: "X-Foo", - value: "value1", - }, - { - key: "X-Bar", - value: "value2", - }, - ], +export default setup( + { + context: import.meta.dirname, + entry: "./app.js", + devServer: { + headers: [ + { + key: "X-Foo", + value: "value1", + }, + { + key: "X-Bar", + value: "value2", + }, + ], + }, }, -}); + import.meta.url, +); diff --git a/examples/headers/function/app.js b/examples/headers/function/app.js index 51cf4a396b..bb080674bb 100644 --- a/examples/headers/function/app.js +++ b/examples/headers/function/app.js @@ -1,5 +1,3 @@ -"use strict"; - const target = document.querySelector("#target"); target.classList.add("pass"); diff --git a/examples/headers/function/webpack.config.js b/examples/headers/function/webpack.config.js index 9ae00dcd3d..fa917298d3 100644 --- a/examples/headers/function/webpack.config.js +++ b/examples/headers/function/webpack.config.js @@ -1,13 +1,14 @@ -"use strict"; - // our setup function adds behind-the-scenes bits to the config that all of our // examples need -const { setup } = require("../../util"); +import { setup } from "../../util.js"; -module.exports = setup({ - context: __dirname, - entry: "./app.js", - devServer: { - headers: () => ({ "X-Custom-Header": ["key1=value1", "key2=value2"] }), +export default setup( + { + context: import.meta.dirname, + entry: "./app.js", + devServer: { + headers: () => ({ "X-Custom-Header": ["key1=value1", "key2=value2"] }), + }, }, -}); + import.meta.url, +); diff --git a/examples/headers/object/app.js b/examples/headers/object/app.js index 51cf4a396b..bb080674bb 100644 --- a/examples/headers/object/app.js +++ b/examples/headers/object/app.js @@ -1,5 +1,3 @@ -"use strict"; - const target = document.querySelector("#target"); target.classList.add("pass"); diff --git a/examples/headers/object/webpack.config.js b/examples/headers/object/webpack.config.js index 20cb07cf7a..20502a6ba6 100644 --- a/examples/headers/object/webpack.config.js +++ b/examples/headers/object/webpack.config.js @@ -1,15 +1,16 @@ -"use strict"; - // our setup function adds behind-the-scenes bits to the config that all of our // examples need -const { setup } = require("../../util"); +import { setup } from "../../util.js"; -module.exports = setup({ - context: __dirname, - entry: "./app.js", - devServer: { - headers: { - "X-Custom-Header": "yes", +export default setup( + { + context: import.meta.dirname, + entry: "./app.js", + devServer: { + headers: { + "X-Custom-Header": "yes", + }, }, }, -}); + import.meta.url, +); diff --git a/examples/history-api-fallback/app.js b/examples/history-api-fallback/app.js index d940d46306..0538ceaa0b 100644 --- a/examples/history-api-fallback/app.js +++ b/examples/history-api-fallback/app.js @@ -1,5 +1,3 @@ -"use strict"; - const path = document.location.pathname; const target = document.querySelector("#target"); const style = document.createElement("style"); diff --git a/examples/history-api-fallback/webpack.config.js b/examples/history-api-fallback/webpack.config.js index 78d6bc2345..5c35aff9da 100644 --- a/examples/history-api-fallback/webpack.config.js +++ b/examples/history-api-fallback/webpack.config.js @@ -1,13 +1,14 @@ -"use strict"; - // our setup function adds behind-the-scenes bits to the config that all of our // examples need -const { setup } = require("../util"); +import { setup } from "../util.js"; -module.exports = setup({ - context: __dirname, - entry: "./app.js", - devServer: { - historyApiFallback: true, +export default setup( + { + context: import.meta.dirname, + entry: "./app.js", + devServer: { + historyApiFallback: true, + }, }, -}); + import.meta.url, +); diff --git a/examples/hmr/boolean/app.js b/examples/hmr/boolean/app.js index 3dff1ef2ee..5f6b32aee4 100644 --- a/examples/hmr/boolean/app.js +++ b/examples/hmr/boolean/app.js @@ -1,9 +1,7 @@ -"use strict"; +import "./example.js"; -require("./example"); - -if (module.hot) { - module.hot.accept((err) => { +if (import.meta.webpackHot) { + import.meta.webpackHot.accept((err) => { if (err) { console.error("Cannot apply HMR update.", err); } diff --git a/examples/hmr/boolean/example.js b/examples/hmr/boolean/example.js index 77f80b74a7..d47c8ea843 100644 --- a/examples/hmr/boolean/example.js +++ b/examples/hmr/boolean/example.js @@ -1,5 +1,3 @@ -"use strict"; - const target = document.querySelector("#target"); target.innerHTML = diff --git a/examples/hmr/boolean/webpack.config.js b/examples/hmr/boolean/webpack.config.js index be0e606ce5..271f80da96 100644 --- a/examples/hmr/boolean/webpack.config.js +++ b/examples/hmr/boolean/webpack.config.js @@ -1,13 +1,14 @@ -"use strict"; - // our setup function adds behind-the-scenes bits to the config that all of our // examples need -const { setup } = require("../../util"); +import { setup } from "../../util.js"; -module.exports = setup({ - context: __dirname, - entry: "./app.js", - devServer: { - hot: true, +export default setup( + { + context: import.meta.dirname, + entry: "./app.js", + devServer: { + hot: true, + }, }, -}); + import.meta.url, +); diff --git a/examples/hmr/only/app.js b/examples/hmr/only/app.js index 3dff1ef2ee..5f6b32aee4 100644 --- a/examples/hmr/only/app.js +++ b/examples/hmr/only/app.js @@ -1,9 +1,7 @@ -"use strict"; +import "./example.js"; -require("./example"); - -if (module.hot) { - module.hot.accept((err) => { +if (import.meta.webpackHot) { + import.meta.webpackHot.accept((err) => { if (err) { console.error("Cannot apply HMR update.", err); } diff --git a/examples/hmr/only/example.js b/examples/hmr/only/example.js index 77f80b74a7..d47c8ea843 100644 --- a/examples/hmr/only/example.js +++ b/examples/hmr/only/example.js @@ -1,5 +1,3 @@ -"use strict"; - const target = document.querySelector("#target"); target.innerHTML = diff --git a/examples/hmr/only/webpack.config.js b/examples/hmr/only/webpack.config.js index e84cfe130a..c117f01e21 100644 --- a/examples/hmr/only/webpack.config.js +++ b/examples/hmr/only/webpack.config.js @@ -1,13 +1,14 @@ -"use strict"; - // our setup function adds behind-the-scenes bits to the config that all of our // examples need -const { setup } = require("../../util"); +import { setup } from "../../util.js"; -module.exports = setup({ - context: __dirname, - entry: "./app.js", - devServer: { - hot: "only", +export default setup( + { + context: import.meta.dirname, + entry: "./app.js", + devServer: { + hot: "only", + }, }, -}); + import.meta.url, +); diff --git a/examples/host-and-port/app.js b/examples/host-and-port/app.js index 51cf4a396b..bb080674bb 100644 --- a/examples/host-and-port/app.js +++ b/examples/host-and-port/app.js @@ -1,5 +1,3 @@ -"use strict"; - const target = document.querySelector("#target"); target.classList.add("pass"); diff --git a/examples/host-and-port/webpack.config.js b/examples/host-and-port/webpack.config.js index 564acff99e..e70cf5183f 100644 --- a/examples/host-and-port/webpack.config.js +++ b/examples/host-and-port/webpack.config.js @@ -1,10 +1,11 @@ -"use strict"; - // our setup function adds behind-the-scenes bits to the config that all of our // examples need -const { setup } = require("../util"); +import { setup } from "../util.js"; -module.exports = setup({ - context: __dirname, - entry: "./app.js", -}); +export default setup( + { + context: import.meta.dirname, + entry: "./app.js", + }, + import.meta.url, +); diff --git a/examples/ipc/app.js b/examples/ipc/app.js index 51cf4a396b..bb080674bb 100644 --- a/examples/ipc/app.js +++ b/examples/ipc/app.js @@ -1,5 +1,3 @@ -"use strict"; - const target = document.querySelector("#target"); target.classList.add("pass"); diff --git a/examples/ipc/webpack.config.js b/examples/ipc/webpack.config.js index ea85092a65..32df532c3b 100644 --- a/examples/ipc/webpack.config.js +++ b/examples/ipc/webpack.config.js @@ -1,34 +1,35 @@ -"use strict"; - -const http = require("node:http"); -const httpProxy = require("http-proxy"); +import http from "node:http"; +import httpProxy from "http-proxy"; // our setup function adds behind-the-scenes bits to the config that all of our // examples need -const { setup } = require("../util"); +import { setup } from "../util.js"; -module.exports = setup({ - context: __dirname, - entry: "./app.js", - devServer: { - webSocketServer: "ws", - onAfterSetupMiddleware: (server) => { - const proxyPort = 8080; - const proxyHost = "127.0.0.1"; - const proxy = httpProxy.createProxyServer({ - target: { socketPath: server.options.ipc }, - }); +export default setup( + { + context: import.meta.dirname, + entry: "./app.js", + devServer: { + webSocketServer: "ws", + onAfterSetupMiddleware: (server) => { + const proxyPort = 8080; + const proxyHost = "127.0.0.1"; + const proxy = httpProxy.createProxyServer({ + target: { socketPath: server.options.ipc }, + }); - const proxyServer = http.createServer((request, response) => { - // You can define here your custom logic to handle the request - // and then proxy the request. - proxy.web(request, response); - }); + const proxyServer = http.createServer((request, response) => { + // You can define here your custom logic to handle the request + // and then proxy the request. + proxy.web(request, response); + }); - proxyServer.on("upgrade", (request, socket, head) => { - proxy.ws(request, socket, head); - }); + proxyServer.on("upgrade", (request, socket, head) => { + proxy.ws(request, socket, head); + }); - proxyServer.listen(proxyPort, proxyHost); + proxyServer.listen(proxyPort, proxyHost); + }, }, }, -}); + import.meta.url, +); diff --git a/examples/multi-compiler/app.js b/examples/multi-compiler/app.js index 97c93a7f44..322023e617 100644 --- a/examples/multi-compiler/app.js +++ b/examples/multi-compiler/app.js @@ -1,5 +1,3 @@ -"use strict"; - const target = document.querySelector("#target"); target.classList.add("pass"); diff --git a/examples/multi-compiler/webpack.config.js b/examples/multi-compiler/webpack.config.js index 6366f481c2..4025c3284b 100644 --- a/examples/multi-compiler/webpack.config.js +++ b/examples/multi-compiler/webpack.config.js @@ -1,12 +1,13 @@ -"use strict"; - // our setup function adds behind-the-scenes bits to the config that all of our // examples need -const { setup } = require("../util"); +import { setup } from "../util.js"; -module.exports = [ - setup({ - context: __dirname, - entry: "./app.js", - }), +export default [ + setup( + { + context: import.meta.dirname, + entry: "./app.js", + }, + import.meta.url, + ), ]; diff --git a/examples/node-false/app.js b/examples/node-false/app.js index 51cf4a396b..bb080674bb 100644 --- a/examples/node-false/app.js +++ b/examples/node-false/app.js @@ -1,5 +1,3 @@ -"use strict"; - const target = document.querySelector("#target"); target.classList.add("pass"); diff --git a/examples/node-false/webpack.config.js b/examples/node-false/webpack.config.js index 0dd23f9c7c..a3966cc65d 100644 --- a/examples/node-false/webpack.config.js +++ b/examples/node-false/webpack.config.js @@ -1,11 +1,12 @@ -"use strict"; - // our setup function adds behind-the-scenes bits to the config that all of our // examples need -const { setup } = require("../util"); +import { setup } from "../util.js"; -module.exports = setup({ - context: __dirname, - entry: "./app.js", - node: false, -}); +export default setup( + { + context: import.meta.dirname, + entry: "./app.js", + node: false, + }, + import.meta.url, +); diff --git a/examples/on-listening/app.js b/examples/on-listening/app.js index 51cf4a396b..bb080674bb 100644 --- a/examples/on-listening/app.js +++ b/examples/on-listening/app.js @@ -1,5 +1,3 @@ -"use strict"; - const target = document.querySelector("#target"); target.classList.add("pass"); diff --git a/examples/on-listening/webpack.config.js b/examples/on-listening/webpack.config.js index 8c9481746d..a863c5b38f 100644 --- a/examples/on-listening/webpack.config.js +++ b/examples/on-listening/webpack.config.js @@ -1,16 +1,17 @@ -"use strict"; - // our setup function adds behind-the-scenes bits to the config that all of our // examples need -const { setup } = require("../util"); +import { setup } from "../util.js"; -module.exports = setup({ - context: __dirname, - entry: "./app.js", - devServer: { - onListening: (devServer) => { - const { port } = devServer.server.address(); - console.log("Listening on port:", port); +export default setup( + { + context: import.meta.dirname, + entry: "./app.js", + devServer: { + onListening: (devServer) => { + const { port } = devServer.server.address(); + console.log("Listening on port:", port); + }, }, }, -}); + import.meta.url, +); diff --git a/examples/open-target-multiple/app1.js b/examples/open-target-multiple/app1.js index 09a8c2b001..b14d6ac504 100644 --- a/examples/open-target-multiple/app1.js +++ b/examples/open-target-multiple/app1.js @@ -1,5 +1,3 @@ -"use strict"; - const target = document.querySelector("#target"); if (globalThis.location.href.endsWith("example1.html")) { diff --git a/examples/open-target-multiple/app2.js b/examples/open-target-multiple/app2.js index 69297e2b2b..f6f61a8163 100644 --- a/examples/open-target-multiple/app2.js +++ b/examples/open-target-multiple/app2.js @@ -1,5 +1,3 @@ -"use strict"; - const target = document.querySelector("#target"); if (globalThis.location.href.endsWith("example2.html")) { diff --git a/examples/open-target-multiple/webpack.config.js b/examples/open-target-multiple/webpack.config.js index 6f3de30cb6..b9c6e0c6c5 100644 --- a/examples/open-target-multiple/webpack.config.js +++ b/examples/open-target-multiple/webpack.config.js @@ -1,37 +1,41 @@ -"use strict"; - -const HtmlWebpackPlugin = require("html-webpack-plugin"); +import HtmlWebpackPlugin from "html-webpack-plugin"; // our setup function adds behind-the-scenes bits to the config that all of our // examples need -const { setup } = require("../util"); +import { setup } from "../util.js"; -module.exports = [ - setup({ - context: __dirname, - entry: "./app1.js", - output: { - filename: "app1.js", +export default [ + setup( + { + context: import.meta.dirname, + entry: "./app1.js", + output: { + filename: "app1.js", + }, + plugins: [ + new HtmlWebpackPlugin({ + filename: "example1.html", + template: "../.assets/layout.html", + title: "Open Target (Multiple) / Example / Page 1", + }), + ], }, - plugins: [ - new HtmlWebpackPlugin({ - filename: "example1.html", - template: "../.assets/layout.html", - title: "Open Target (Multiple) / Example / Page 1", - }), - ], - }), - setup({ - context: __dirname, - entry: "./app2.js", - output: { - filename: "app2.js", + import.meta.url, + ), + setup( + { + context: import.meta.dirname, + entry: "./app2.js", + output: { + filename: "app2.js", + }, + plugins: [ + new HtmlWebpackPlugin({ + filename: "example2.html", + template: "../.assets/layout.html", + title: "Open Target (Multiple) / Example / Page 2", + }), + ], }, - plugins: [ - new HtmlWebpackPlugin({ - filename: "example2.html", - template: "../.assets/layout.html", - title: "Open Target (Multiple) / Example / Page 2", - }), - ], - }), + import.meta.url, + ), ]; diff --git a/examples/open-target/app.js b/examples/open-target/app.js index 7d91e11582..5ee0912ea7 100644 --- a/examples/open-target/app.js +++ b/examples/open-target/app.js @@ -1,5 +1,3 @@ -"use strict"; - const target = document.querySelector("#target"); if (globalThis.location.href.endsWith("example.html#page1")) { diff --git a/examples/open-target/webpack.config.js b/examples/open-target/webpack.config.js index 18c9b29139..28b306cd92 100644 --- a/examples/open-target/webpack.config.js +++ b/examples/open-target/webpack.config.js @@ -1,18 +1,19 @@ -"use strict"; - -const HtmlWebpackPlugin = require("html-webpack-plugin"); +import HtmlWebpackPlugin from "html-webpack-plugin"; // our setup function adds behind-the-scenes bits to the config that all of our // examples need -const { setup } = require("../util"); +import { setup } from "../util.js"; -module.exports = setup({ - context: __dirname, - entry: "./app.js", - plugins: [ - new HtmlWebpackPlugin({ - filename: "example.html", - template: "../.assets/layout.html", - title: "Open Target / Example", - }), - ], -}); +export default setup( + { + context: import.meta.dirname, + entry: "./app.js", + plugins: [ + new HtmlWebpackPlugin({ + filename: "example.html", + template: "../.assets/layout.html", + title: "Open Target / Example", + }), + ], + }, + import.meta.url, +); diff --git a/examples/proxy/app.js b/examples/proxy/app.js index 85698e7be9..6000403620 100644 --- a/examples/proxy/app.js +++ b/examples/proxy/app.js @@ -1,5 +1,3 @@ -"use strict"; - const target = document.querySelector("#target"); target.classList.add("pass"); diff --git a/examples/proxy/webpack.config.js b/examples/proxy/webpack.config.js index ad87568081..e73519b971 100644 --- a/examples/proxy/webpack.config.js +++ b/examples/proxy/webpack.config.js @@ -1,9 +1,7 @@ -"use strict"; - -const express = require("express"); +import express from "express"; // our setup function adds behind-the-scenes bits to the config that all of our // examples need -const { setup } = require("../util"); +import { setup } from "../util.js"; /** * @@ -22,18 +20,21 @@ async function listenProxyServer() { }); } -module.exports = setup({ - context: __dirname, - entry: "./app.js", - devServer: { - onBeforeSetupMiddleware: async () => { - await listenProxyServer(); - }, - proxy: [ - { - context: "/proxy", - target: "http://localhost:5000", +export default setup( + { + context: import.meta.dirname, + entry: "./app.js", + devServer: { + onBeforeSetupMiddleware: async () => { + await listenProxyServer(); }, - ], + proxy: [ + { + context: "/proxy", + target: "http://localhost:5000", + }, + ], + }, }, -}); + import.meta.url, +); diff --git a/examples/server/http2/app.js b/examples/server/http2/app.js index 51cf4a396b..bb080674bb 100644 --- a/examples/server/http2/app.js +++ b/examples/server/http2/app.js @@ -1,5 +1,3 @@ -"use strict"; - const target = document.querySelector("#target"); target.classList.add("pass"); diff --git a/examples/server/http2/webpack.config.js b/examples/server/http2/webpack.config.js index 4c29be511c..4d042b93be 100644 --- a/examples/server/http2/webpack.config.js +++ b/examples/server/http2/webpack.config.js @@ -1,16 +1,17 @@ -"use strict"; - // our setup function adds behind-the-scenes bits to the config that all of our // examples need -const connect = require("connect"); -const { setup } = require("../../util"); +import connect from "connect"; +import { setup } from "../../util.js"; -module.exports = setup({ - context: __dirname, - entry: "./app.js", - devServer: { - server: "http2", - // Only `connect` supports `http2` - app: () => connect(), +export default setup( + { + context: import.meta.dirname, + entry: "./app.js", + devServer: { + server: "http2", + // Only `connect` supports `http2` + app: () => connect(), + }, }, -}); + import.meta.url, +); diff --git a/examples/server/https/app.js b/examples/server/https/app.js index 51cf4a396b..bb080674bb 100644 --- a/examples/server/https/app.js +++ b/examples/server/https/app.js @@ -1,5 +1,3 @@ -"use strict"; - const target = document.querySelector("#target"); target.classList.add("pass"); diff --git a/examples/server/https/webpack.config.js b/examples/server/https/webpack.config.js index 6e3a7f753a..a8f10872eb 100644 --- a/examples/server/https/webpack.config.js +++ b/examples/server/https/webpack.config.js @@ -1,22 +1,23 @@ -"use strict"; - // our setup function adds behind-the-scenes bits to the config that all of our // examples need -const { setup } = require("../../util"); +import { setup } from "../../util.js"; -module.exports = setup({ - context: __dirname, - entry: "./app.js", - devServer: { - server: { - type: "https", - options: { - key: "./ssl/server.key", - pfx: "./ssl/server.pfx", - cert: "./ssl/server.crt", - ca: "./ssl/ca.pem", - passphrase: "webpack-dev-server", +export default setup( + { + context: import.meta.dirname, + entry: "./app.js", + devServer: { + server: { + type: "https", + options: { + key: "./ssl/server.key", + pfx: "./ssl/server.pfx", + cert: "./ssl/server.crt", + ca: "./ssl/ca.pem", + passphrase: "webpack-dev-server", + }, }, }, }, -}); + import.meta.url, +); diff --git a/examples/setup-middlewares/app.js b/examples/setup-middlewares/app.js index 51cf4a396b..bb080674bb 100644 --- a/examples/setup-middlewares/app.js +++ b/examples/setup-middlewares/app.js @@ -1,5 +1,3 @@ -"use strict"; - const target = document.querySelector("#target"); target.classList.add("pass"); diff --git a/examples/setup-middlewares/webpack.config.js b/examples/setup-middlewares/webpack.config.js index df9d9fb74a..d5bc264efc 100644 --- a/examples/setup-middlewares/webpack.config.js +++ b/examples/setup-middlewares/webpack.config.js @@ -1,36 +1,37 @@ -"use strict"; - // our setup function adds behind-the-scenes bits to the config that all of our // examples need -const { setup } = require("../util"); +import { setup } from "../util.js"; -module.exports = setup({ - context: __dirname, - entry: "./app.js", - devServer: { - setupMiddlewares: (middlewares, devServer) => { - if (!devServer) { - throw new Error("webpack-dev-server is not defined"); - } +export default setup( + { + context: import.meta.dirname, + entry: "./app.js", + devServer: { + setupMiddlewares: (middlewares, devServer) => { + if (!devServer) { + throw new Error("webpack-dev-server is not defined"); + } - devServer.app.get("/setup-middleware/some/path", (_, response) => { - response.send("setup-middlewares option GET"); - }); + devServer.app.get("/setup-middleware/some/path", (_, response) => { + response.send("setup-middlewares option GET"); + }); - middlewares.push({ - name: "hello-world-test-one", - // `path` is optional - path: "/foo/bar", - middleware: (req, res) => { - res.send("Foo Bar!"); - }, - }); + middlewares.push({ + name: "hello-world-test-one", + // `path` is optional + path: "/foo/bar", + middleware: (req, res) => { + res.send("Foo Bar!"); + }, + }); - middlewares.push((req, res) => { - res.send("Hello World!"); - }); + middlewares.push((req, res) => { + res.send("Hello World!"); + }); - return middlewares; + return middlewares; + }, }, }, -}); + import.meta.url, +); diff --git a/examples/util.js b/examples/util.js index dc1d97f771..a79f6c06c1 100644 --- a/examples/util.js +++ b/examples/util.js @@ -1,104 +1,108 @@ -"use strict"; - -const path = require("node:path"); -const fs = require("graceful-fs"); -const HtmlWebpackPlugin = require("html-webpack-plugin"); -const { marked } = require("marked"); -const mime = require("mime"); - -module.exports = { - setup(config) { - const defaults = { mode: "development", plugins: [], devServer: {} }; - - if (config.entry) { - if (typeof config.entry === "string") { - config.entry = path.resolve(config.entry); - } else if (Array.isArray(config.entry)) { - config.entry = config.entry.map((entry) => path.resolve(entry)); - } else if (typeof config.entry === "object") { - for (const [key, value] of Object.entries(config.entry)) { - config.entry[key] = path.resolve(value); - } +import path from "node:path"; +import { fileURLToPath } from "node:url"; +import fs from "graceful-fs"; +import HtmlWebpackPlugin from "html-webpack-plugin"; +import { marked } from "marked"; +import mime from "mime"; + +const __dirname = import.meta.dirname; + +/** + * @param {object} config webpack config + * @param {string} callerUrl `import.meta.url` of the calling webpack config — used to derive `output.path` + * @returns {object} normalized webpack config + */ +export function setup(config, callerUrl) { + const defaults = { mode: "development", plugins: [], devServer: {} }; + + if (config.entry) { + if (typeof config.entry === "string") { + config.entry = path.resolve(config.entry); + } else if (Array.isArray(config.entry)) { + config.entry = config.entry.map((entry) => path.resolve(entry)); + } else if (typeof config.entry === "object") { + for (const [key, value] of Object.entries(config.entry)) { + config.entry[key] = path.resolve(value); } } + } + + const result = { ...defaults, ...config }; + const onBeforeSetupMiddleware = ({ app }) => { + app.use("/.assets/", (req, res, next) => { + if (req.method !== "GET" && req.method !== "HEAD") { + next(); + return; + } - const result = { ...defaults, ...config }; - const onBeforeSetupMiddleware = ({ app }) => { - app.use("/.assets/", (req, res, next) => { - if (req.method !== "GET" && req.method !== "HEAD") { - next(); - return; - } - - res.setHeader("Content-Type", mime.lookup(req.url)); + res.setHeader("Content-Type", mime.lookup(req.url)); + + const filename = path.join(__dirname, "/.assets/", req.url); + const stream = fs.createReadStream(filename); + + stream.pipe(res); + }); + }; + const renderer = new marked.Renderer(); + const { heading } = renderer; + const markedOptions = { + gfm: true, + tables: true, + breaks: false, + pedantic: false, + sanitize: false, + sanitizer: null, + mangle: true, + smartLists: false, + silent: false, + langPrefix: "lang-", + smartypants: false, + headerPrefix: "", + renderer, + xhtml: false, + }; + const readme = fs.readFileSync("README.md", "utf8"); + + let exampleTitle = ""; + + renderer.heading = function headingProxy(text, level, raw, slugger) { + if (level === 1 && !exampleTitle) { + exampleTitle = text; + } - const filename = path.join(__dirname, "/.assets/", req.url); - const stream = fs.createReadStream(filename); + return heading.call(this, text, level, raw, slugger); + }; - stream.pipe(res); - }); - }; - const renderer = new marked.Renderer(); - const { heading } = renderer; - const markedOptions = { - gfm: true, - tables: true, - breaks: false, - pedantic: false, - sanitize: false, - sanitizer: null, - mangle: true, - smartLists: false, - silent: false, - langPrefix: "lang-", - smartypants: false, - headerPrefix: "", - renderer, - xhtml: false, - }; - const readme = fs.readFileSync("README.md", "utf8"); + marked.setOptions(markedOptions); - let exampleTitle = ""; + marked(readme, { renderer }); - renderer.heading = function headingProxy(text, level, raw, slugger) { - if (level === 1 && !exampleTitle) { - exampleTitle = text; - } + result.plugins.push( + new HtmlWebpackPlugin({ + filename: "index.html", + template: path.join(__dirname, ".assets/layout.html"), + title: exampleTitle, + }), + ); - return heading.call(this, text, level, raw, slugger); + if (result.devServer.setupMiddlewares) { + const proxy = result.devServer.setupMiddlewares; + result.devServer.setupMiddlewares = (middlewares, devServer) => { + onBeforeSetupMiddleware(devServer); + return proxy(middlewares, devServer); }; - - marked.setOptions(markedOptions); - - marked(readme, { renderer }); - - result.plugins.push( - new HtmlWebpackPlugin({ - filename: "index.html", - template: path.join(__dirname, ".assets/layout.html"), - title: exampleTitle, - }), - ); - - if (result.devServer.setupMiddlewares) { - const proxy = result.devServer.setupMiddlewares; - result.devServer.setupMiddlewares = (middlewares, devServer) => { - onBeforeSetupMiddleware(devServer); - return proxy(middlewares, devServer); - }; - } else { - result.devServer.setupMiddlewares = (middlewares, devServer) => { - onBeforeSetupMiddleware(devServer); - return middlewares; - }; - } - - const output = { - path: path.dirname(module.parent.filename), + } else { + result.devServer.setupMiddlewares = (middlewares, devServer) => { + onBeforeSetupMiddleware(devServer); + return middlewares; }; + } + + const output = { + path: path.dirname(fileURLToPath(callerUrl)), + }; - result.output = result.output ? { ...result.output, ...output } : output; + result.output = result.output ? { ...result.output, ...output } : output; - return result; - }, -}; + return result; +} diff --git a/examples/watch-static/app.js b/examples/watch-static/app.js index 51cf4a396b..bb080674bb 100644 --- a/examples/watch-static/app.js +++ b/examples/watch-static/app.js @@ -1,5 +1,3 @@ -"use strict"; - const target = document.querySelector("#target"); target.classList.add("pass"); diff --git a/examples/watch-static/webpack.config.js b/examples/watch-static/webpack.config.js index 438cff8ada..a40485612e 100644 --- a/examples/watch-static/webpack.config.js +++ b/examples/watch-static/webpack.config.js @@ -1,13 +1,14 @@ -"use strict"; - // our setup function adds behind-the-scenes bits to the config that all of our // examples need -const { setup } = require("../util"); +import { setup } from "../util.js"; -module.exports = setup({ - context: __dirname, - entry: "./app.js", - devServer: { - static: ["assets", "css"], +export default setup( + { + context: import.meta.dirname, + entry: "./app.js", + devServer: { + static: ["assets", "css"], + }, }, -}); + import.meta.url, +); diff --git a/examples/web-socket-server/ws/app.js b/examples/web-socket-server/ws/app.js index 51cf4a396b..bb080674bb 100644 --- a/examples/web-socket-server/ws/app.js +++ b/examples/web-socket-server/ws/app.js @@ -1,5 +1,3 @@ -"use strict"; - const target = document.querySelector("#target"); target.classList.add("pass"); diff --git a/examples/web-socket-server/ws/webpack.config.js b/examples/web-socket-server/ws/webpack.config.js index 98d34d1f9b..448e8ce6ad 100644 --- a/examples/web-socket-server/ws/webpack.config.js +++ b/examples/web-socket-server/ws/webpack.config.js @@ -1,13 +1,14 @@ -"use strict"; - // our setup function adds behind-the-scenes bits to the config that all of our // examples need -const { setup } = require("../../util"); +import { setup } from "../../util.js"; -module.exports = setup({ - context: __dirname, - entry: "./app.js", - devServer: { - webSocketServer: "ws", +export default setup( + { + context: import.meta.dirname, + entry: "./app.js", + devServer: { + webSocketServer: "ws", + }, }, -}); + import.meta.url, +); From 0f424785e2abd37d826cc90045ca967446233015 Mon Sep 17 00:00:00 2001 From: Sebastian Beltran Date: Sat, 16 May 2026 11:57:02 -0500 Subject: [PATCH 27/29] refactor: update webpack configuration and asset handling for improved module support --- .gitignore | 3 +++ examples/default-cjs/webpack.config.cjs | 3 ++- examples/default/app.js | 3 ++- examples/default/webpack.config.js | 14 +++++--------- examples/util.js | 3 ++- 5 files changed, 14 insertions(+), 12 deletions(-) diff --git a/.gitignore b/.gitignore index de3b694aec..8a1aee341d 100644 --- a/.gitignore +++ b/.gitignore @@ -7,6 +7,9 @@ npm-debug.log client !/examples/client !/test/client + +examples/**/dist + coverage node_modules .vscode diff --git a/examples/default-cjs/webpack.config.cjs b/examples/default-cjs/webpack.config.cjs index 5fdb946abd..7533a297b6 100644 --- a/examples/default-cjs/webpack.config.cjs +++ b/examples/default-cjs/webpack.config.cjs @@ -15,7 +15,8 @@ module.exports = { context: __dirname, entry: "./app.js", output: { - path: __dirname, + path: path.join(__dirname, "dist"), + publicPath: "/", filename: "bundle.js", }, plugins: [ diff --git a/examples/default/app.js b/examples/default/app.js index f85a7d4af8..e8b1817d31 100644 --- a/examples/default/app.js +++ b/examples/default/app.js @@ -1,4 +1,5 @@ import "./style.less"; +import svgUrl from "./svg.svg"; const target = document.querySelector("#target"); @@ -6,7 +7,7 @@ target.classList.add("pass"); target.innerHTML = "Success!"; const img = document.createElement("img"); -img.src = "/svg.svg"; +img.src = svgUrl; img.style = "width: 200px;"; document.body.appendChild(img); diff --git a/examples/default/webpack.config.js b/examples/default/webpack.config.js index dc966414a8..a0226b350c 100644 --- a/examples/default/webpack.config.js +++ b/examples/default/webpack.config.js @@ -2,14 +2,6 @@ // examples need import { setup } from "../util.js"; -const moduleRuleForPNG = { - test: /\.png$/, - type: "asset/resource", - generator: { - filename: "images/[hash][ext][query]", - }, -}; - export default setup( { context: import.meta.dirname, @@ -21,7 +13,11 @@ export default setup( use: ["style-loader", "css-loader", "less-loader"], }, { - ...moduleRuleForPNG, + test: /\.(png|svg)$/, + type: "asset/resource", + generator: { + filename: "images/[hash][ext][query]", + }, }, ], }, diff --git a/examples/util.js b/examples/util.js index a79f6c06c1..83a741dc6d 100644 --- a/examples/util.js +++ b/examples/util.js @@ -99,7 +99,8 @@ export function setup(config, callerUrl) { } const output = { - path: path.dirname(fileURLToPath(callerUrl)), + path: path.join(path.dirname(fileURLToPath(callerUrl)), "dist"), + publicPath: "/", }; result.output = result.output ? { ...result.output, ...output } : output; From 82c91502e48e540d00cb273ae228581cdf45f01f Mon Sep 17 00:00:00 2001 From: Sebastian Beltran Date: Sat, 16 May 2026 12:00:30 -0500 Subject: [PATCH 28/29] refactor: update webSocketServer configuration to use object syntax for improved clarity --- examples/web-socket-server/ws/README.md | 6 ++++-- examples/web-socket-server/ws/webpack.config.js | 4 +++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/examples/web-socket-server/ws/README.md b/examples/web-socket-server/ws/README.md index b87604dfae..9056033858 100644 --- a/examples/web-socket-server/ws/README.md +++ b/examples/web-socket-server/ws/README.md @@ -9,10 +9,12 @@ This mode uses [ws](https://github.com/websockets/ws) as a server. **webpack.config.js** ```js -module.exports = { +export default { // ... devServer: { - webSocketServer: "ws", + webSocketServer: { + type: "ws", + }, }, }; ``` diff --git a/examples/web-socket-server/ws/webpack.config.js b/examples/web-socket-server/ws/webpack.config.js index 448e8ce6ad..a9a3d88d4c 100644 --- a/examples/web-socket-server/ws/webpack.config.js +++ b/examples/web-socket-server/ws/webpack.config.js @@ -7,7 +7,9 @@ export default setup( context: import.meta.dirname, entry: "./app.js", devServer: { - webSocketServer: "ws", + webSocketServer: { + type: "ws", + }, }, }, import.meta.url, From 46d014861ee13d031d75bc39f644c536060b0d68 Mon Sep 17 00:00:00 2001 From: Sebastian Beltran Date: Sat, 16 May 2026 12:07:55 -0500 Subject: [PATCH 29/29] refactor: update test coverage script to include additional directories for improved coverage reporting --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 161d035dbf..aaff3cd758 100644 --- a/package.json +++ b/package.json @@ -37,7 +37,7 @@ "build:types": "rimraf -g ./types/* && tsc --declaration --emitDeclarationOnly --outDir types && node ./scripts/extend-webpack-types.js && prettier \"types/**/*.ts\" --write && prettier \"types/**/*.ts\" --write", "build": "npm-run-all -p \"build:**\"", "test:only": "node ./scripts/check-test-ports.mjs && node ./scripts/run-tests.mjs", - "test:coverage": "npm run test:only -- --experimental-test-coverage --test-reporter=spec --test-reporter-destination=stdout --test-reporter=lcov --test-reporter-destination=coverage/lcov.info", + "test:coverage": "npm run test:only -- --experimental-test-coverage --test-coverage-include=lib/** --test-coverage-include=bin/** --test-coverage-include=client/** --test-coverage-include=client-src/** --test-reporter=spec --test-reporter-destination=stdout --test-reporter=lcov --test-reporter-destination=coverage/lcov.info", "test:watch": "npm run test:only -- --watch", "test": "npm run test:coverage", "pretest": "npm run lint",