Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/nodejs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ jobs:
run: npm run build:ci

- name: Run tests and generate coverage
run: npm run test:coverage --ci --shard=${{ matrix.shard }}
run: npm run test:coverage -- --ci --shard=${{ matrix.shard }}

- name: Upload coverage to Codecov
uses: codecov/codecov-action@671740ac38dd9b0130fbe1cec585b89eea48d3de # v5.5.2
Expand Down
4 changes: 2 additions & 2 deletions jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ module.exports = {
transform: {
"^.+\\.(ts)?$": "ts-jest",
},
testRegex: ["/test/.*\\.(test.js|test.ts)$"],
moduleFileExtensions: ["ts", "js", "json"],
testRegex: ["/test/.*\\.(test.js|test.cjs|test.mjs|test.ts|test.cts|test.mts)$"],
moduleFileExtensions: ["ts", "cts", "mts", "js", "cjs", "mjs", "json"],
snapshotResolver: "<rootDir>/scripts/snapshot-resolver.js",
setupFilesAfterEnv: ["<rootDir>/scripts/setup-test.js"],
globalTeardown: "<rootDir>/scripts/cleanup-test.js",
Expand Down
1,092 changes: 552 additions & 540 deletions package-lock.json

Large diffs are not rendered by default.

16 changes: 7 additions & 9 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,10 @@
"fix": "npm run fix:code",
"fix:code": "npm run lint:code -- --fix",
"pretest": "npm run build && npm run lint",
"test": "jest --reporters=default",
"test": "npm run test:base",
"test:base": "node --experimental-vm-modules ./node_modules/jest-cli/bin/jest",
"test:smoketests": "nyc node smoketests",
"test:coverage": "nyc --no-clean jest",
"test:cli": "jest test --reporters=default",
"test:packages": "jest packages/ --reporters=default",
"test:ci": "npm run test:cli && npm run test:packages",
"test:coverage": "nyc --no-clean npm run test:base -- --coverage",
"publish:monorepo": "npm run build && lerna version && lerna publish from-git",
"update:docs": "node ./scripts/update-docs",
"prepare": "husky"
Expand All @@ -63,7 +61,7 @@
"coffeescript": "^2.7.0",
"colorette": "^2.0.16",
"concat-stream": "^2.0.0",
"cspell": "^8.3.2",
"cspell": "^9.4.0",
"css-loader": "^7.1.2",
"del-cli": "^6.0.0",
"eslint": "^9.29.0",
Expand All @@ -75,13 +73,13 @@
"eslint-plugin-n": "^17.19.0",
"eslint-plugin-prettier": "^5.4.1",
"eslint-plugin-unicorn": "^62.0.0",
"execa": "^5.0.0",
"get-port": "^5.1.1",
"execa": "^9.6.1",
"get-port": "^7.1.0",
"globals": "^16.2.0",
"husky": "^9.1.4",
"jest": "^30.2.0",
"lerna": "^9.0.3",
"lint-staged": "^15.2.9",
"lint-staged": "^16.2.7",
"mini-css-extract-plugin": "^2.6.1",
"nyc": "^17.1.0",
"prettier": "^3.6.0",
Expand Down
20 changes: 14 additions & 6 deletions scripts/update-docs.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
const { writeFileSync } = require("node:fs");
const { resolve } = require("node:path");
const { sync } = require("execa");
const { version } = require("webpack-dev-server/package.json");

const [majorDevServerVersion] = version.split(".");

try {
const { stdout: cliOptions } = sync(
/**
* @returns {Promise<void>}
*/
async function updateDocs() {
const { execa } = await import("execa");
const { stdout: cliOptions } = await execa(
resolve(__dirname, "../packages/webpack-cli/bin/cli.js"),
["--help=verbose", "--no-color"],
{
Expand All @@ -16,13 +19,13 @@ try {
);

// format output for markdown
const mdContent = ["```\n", cliOptions, "\n```"].join("");
const mdContent = ["```\n", cliOptions, "\n```\n"].join("");

// create OPTIONS.md
writeFileSync("OPTIONS.md", mdContent);

// serve options
const { stdout: serveOptions } = sync(
const { stdout: serveOptions } = await execa(
resolve(__dirname, "../packages/webpack-cli/bin/cli.js"),
["serve", "--help", "--no-color"],
{
Expand All @@ -32,12 +35,17 @@ try {
);

// format output for markdown
const serveContent = ["```\n", serveOptions, "\n```"].join("");
const serveContent = ["```\n", serveOptions, "\n```\n"].join("");

// create SERVE.md
writeFileSync(`SERVE-OPTIONS-v${majorDevServerVersion}.md`, serveContent);

console.log(`Successfully updated "OPTIONS.md" and "SERVE-OPTIONS-v${majorDevServerVersion}.md"`);
}

try {
// eslint-disable-next-line unicorn/prefer-top-level-await
updateDocs();
} catch (err) {
console.error(err);
}
34 changes: 24 additions & 10 deletions smoketests/helpers.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
const fs = require("node:fs");
const path = require("node:path");
const { stripVTControlCharacters } = require("node:util");
const execa = require("execa");

const ROOT_PATH = process.env.GITHUB_WORKSPACE || path.resolve(__dirname, "..");

Expand All @@ -22,12 +21,16 @@ const swapPkgName = (current, isSubPackage = false) => {

const CLI_ENTRY_PATH = path.resolve(ROOT_PATH, "./packages/webpack-cli/bin/cli.js");

const runTest = (pkg, cliArgs = [], logMessage = undefined, isSubPackage = false) => {
const runTest = async (pkg, cliArgs = [], logMessage = undefined, isSubPackage = false) => {
// Simulate package missing
swapPkgName(pkg, isSubPackage);

const { execa } = await import("execa");
const abortController = new AbortController();
const proc = execa(CLI_ENTRY_PATH, cliArgs, {
cwd: __dirname,
reject: false,
cancelSignal: abortController.signal,
});

proc.stdin.setDefaultEncoding("utf8");
Expand Down Expand Up @@ -61,8 +64,8 @@ const runTest = (pkg, cliArgs = [], logMessage = undefined, isSubPackage = false
}

if (hasLogMessage && hasPrompt) {
abortController.abort();
hasPassed = true;
proc.kill();
}
});

Expand All @@ -80,12 +83,16 @@ const runTest = (pkg, cliArgs = [], logMessage = undefined, isSubPackage = false
});
};

const runTestStdout = ({ packageName, cliArgs, logMessage, isSubPackage } = {}) => {
const runTestStdout = async ({ packageName, cliArgs, logMessage, isSubPackage } = {}) => {
// Simulate package missing
swapPkgName(packageName, isSubPackage);

const { execa } = await import("execa");
const abortController = new AbortController();
const proc = execa(CLI_ENTRY_PATH, cliArgs, {
cwd: __dirname,
reject: false,
cancelSignal: abortController.signal,
});

proc.stdin.setDefaultEncoding("utf8");
Expand All @@ -105,7 +112,7 @@ const runTestStdout = ({ packageName, cliArgs, logMessage, isSubPackage } = {})

if (data.includes(logMessage)) {
hasPassed = true;
proc.kill();
abortController.abort();
}
});

Expand All @@ -128,7 +135,7 @@ const runTestStdout = ({ packageName, cliArgs, logMessage, isSubPackage } = {})
});
};

const runTestStdoutWithInput = ({
const runTestStdoutWithInput = async ({
packageName,
cliArgs,
inputs,
Expand All @@ -138,8 +145,12 @@ const runTestStdoutWithInput = ({
// Simulate package missing
swapPkgName(packageName, isSubPackage);

const { execa } = await import("execa");
const abortController = new AbortController();
const proc = execa(CLI_ENTRY_PATH, cliArgs, {
cwd: __dirname,
reject: false,
cancelSignal: abortController.signal,
});

proc.stdin.setDefaultEncoding("utf8");
Expand All @@ -158,7 +169,7 @@ const runTestStdoutWithInput = ({

if (data.includes(logMessage)) {
hasPassed = true;
proc.kill();
abortController.abort();
}

for (const input of Object.keys(inputs)) {
Expand Down Expand Up @@ -187,16 +198,19 @@ const runTestStdoutWithInput = ({
});
};

const runTestWithHelp = (pkg, cliArgs = [], logMessage = undefined, isSubPackage = false) => {
const runTestWithHelp = async (pkg, cliArgs = [], logMessage = undefined, isSubPackage = false) => {
// Simulate package missing
swapPkgName(pkg, isSubPackage);

const { execa } = await import("execa");
const abortController = new AbortController();
const proc = execa(CLI_ENTRY_PATH, cliArgs, {
cwd: __dirname,
reject: false,
cancelSignal: abortController.signal,
});

proc.stdin.setDefaultEncoding("utf8");

proc.stdout.on("data", (chunk) => {
console.log(` stdout: ${chunk.toString()}`);
});
Expand Down Expand Up @@ -228,7 +242,7 @@ const runTestWithHelp = (pkg, cliArgs = [], logMessage = undefined, isSubPackage

if (hasLogMessage || hasUndefinedLogMessage) {
hasPassed = true;
proc.kill();
abortController.abort();
}
});

Expand Down
9 changes: 5 additions & 4 deletions smoketests/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,13 @@ const tests = [
const passResults = [];
const failResults = [];

for await (const test of tests) {
console.log(`\nRUN ${test.name}`);
for (const test of tests) {
console.log(`RUN ${test.name}`);

let isPass = true;

for await (const testCase of test.run) {
for (const testCase of test.run) {
console.log(`RUN case ${testCase.name}`);
isPass &&= await testCase();
}

Expand All @@ -34,7 +35,7 @@ const tests = [
}
}

console.log("\n\nSummary of smoketest run:");
console.log("\nSummary of smoke tests run:");
console.log(`${failResults.length} tests failed, ${passResults.length} tests passed`);

for (const result of failResults) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
const { existsSync, unlinkSync } = require("node:fs");
const { resolve } = require("node:path");

const execa = require("execa");
const { run } = require("../../../utils/test-utils");

const { sync: spawnSync } = execa;

describe("webpack cli", () => {
it('should work with the "disable-interpret" option from flags', async () => {
const configFileName = "webpack.config";
const configFilePath = resolve(__dirname, `${configFileName}.ts`);
const buildScripts = spawnSync("yarn", ["tsc", configFilePath]);
const { execa } = await import("execa");
const buildScripts = await execa("yarn", ["tsc", configFilePath]);
expect(buildScripts.stdout).toBeTruthy();

const { exitCode, stderr, stdout } = await run(__dirname, ["--disable-interpret"]);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"type": "module",
"type": "commonjs",
"engines": {
"node": ">=18.12.0"
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@
"target": "esnext",
"allowImportingTsExtensions": true,
"rewriteRelativeImportExtensions": true,
"module": "esnext"
"module": "commonjs"
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
const { existsSync } = require("node:fs");
const { resolve } = require("node:path");
const { run } = require("../../../utils/test-utils");
import { existsSync } from "node:fs";
import { dirname, resolve } from "node:path";
import { fileURLToPath } from "node:url";
import { run } from "../../../utils/test-utils.js";

const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);

describe("webpack cli", () => {
it("should support typescript esnext file", async () => {
Expand All @@ -15,7 +19,7 @@ describe("webpack cli", () => {
WEBPACK_CLI_FORCE_LOAD_ESM_CONFIG: true,
},
// Fallback to `ts-node/esm` for old Node.js versions
nodeOptions: major >= 24 ? [] : ["--experimental-loader=ts-node/esm"],
nodeOptions: major >= 24 ? [] : ["--require=ts-node/register"],
},
);

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import * as path from "node:path";
const path = require("node:path");

/* eslint-disable no-useless-concat */

Expand All @@ -13,4 +13,4 @@ const config = {
},
};

export default config;
module.exports = config;
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
const { existsSync } = require("node:fs");
const { resolve } = require("node:path");
const { run } = require("../../../utils/test-utils");
import { existsSync } from "node:fs";
import { dirname, resolve } from "node:path";
import { fileURLToPath } from "node:url";
import { run } from "../../../utils/test-utils.js";

const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);

describe("webpack cli", () => {
it("should support typescript esnext file", async () => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
const { existsSync } = require("node:fs");
const { resolve } = require("node:path");
const { run } = require("../../../utils/test-utils");
import { existsSync } from "node:fs";
import { dirname, resolve } from "node:path";
import { fileURLToPath } from "node:url";
import { run } from "../../../utils/test-utils.js";

const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);

describe("webpack cli", () => {
it("should support typescript esnext file", async () => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
const { existsSync } = require("node:fs");
const { resolve } = require("node:path");
const { run } = require("../../../utils/test-utils");
import { existsSync } from "node:fs";
import { dirname, resolve } from "node:path";
import { fileURLToPath } from "node:url";
import { run } from "../../../utils/test-utils.js";

const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);

describe("webpack cli", () => {
it("should support typescript esnext file", async () => {
Expand Down
Loading
Loading