diff --git a/.nycrc b/.nycrc index 36cd87040de..540462ce0a4 100644 --- a/.nycrc +++ b/.nycrc @@ -2,5 +2,6 @@ "include": ["packages/**"], "reporter": ["html", "json", "cobertura"], "source-map": true, + "hook-require": false, "exclude-after-remap": false } diff --git a/eslint.config.mjs b/eslint.config.mjs index 9c51bae9331..960d43d6927 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -15,7 +15,7 @@ export default defineConfig([ "test/build/config/error-array/webpack.config.js", "test/build/config-format/esm-require-await/webpack.config.js", "test/configtest/with-config-path/syntax-error.config.js", - "test/build/config-format/esm-require/webpack.config.js", + "test/build/config-format/auto/webpack.config.js", ]), { extends: [config], diff --git a/test/build/config-format/auto/auto.test.mjs b/test/build/config-format/auto/auto.test.mjs new file mode 100644 index 00000000000..da5ace9657b --- /dev/null +++ b/test/build/config-format/auto/auto.test.mjs @@ -0,0 +1,44 @@ +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("auto loading different formats of configuration", () => { + it("should support configuration (Node.js build-in support)", async () => { + const { exitCode, stderr, stdout } = await run(__dirname, ["-c", "./webpack.config.js"], { + nodeOptions: [], + }); + + expect(stderr).toContain( + "Reparsing as ES module because module syntax was detected. This incurs a performance overhead.", + ); + expect(stdout).toBeTruthy(); + expect(exitCode).toBe(0); + expect(existsSync(resolve(__dirname, "dist/foo.bundle.js"))).toBeTruthy(); + }); + + it("should support configuration (Node.js build-in support) with `mjs` extension", async () => { + const { exitCode, stderr, stdout } = await run(__dirname, ["-c", "./webpack.config.mjs"], { + nodeOptions: [], + }); + + expect(stderr).toBeFalsy(); + expect(stdout).toBeTruthy(); + expect(exitCode).toBe(0); + expect(existsSync(resolve(__dirname, "dist/foo.bundle.js"))).toBeTruthy(); + }); + + it("should support configuration (Node.js build-in support) with `cjs` extension", async () => { + const { exitCode, stderr, stdout } = await run(__dirname, ["-c", "./webpack.config.cjs"], { + nodeOptions: [], + }); + + expect(stderr).toBeFalsy(); + expect(stdout).toBeTruthy(); + expect(exitCode).toBe(0); + expect(existsSync(resolve(__dirname, "dist/foo.bundle.js"))).toBeTruthy(); + }); +}); diff --git a/test/build/config-format/typescript-cjs-using-nodejs/main.ts b/test/build/config-format/auto/main.js similarity index 100% rename from test/build/config-format/typescript-cjs-using-nodejs/main.ts rename to test/build/config-format/auto/main.js diff --git a/test/build/config-format/typescript-mjs-using-nodejs/package.json b/test/build/config-format/auto/package.json similarity index 70% rename from test/build/config-format/typescript-mjs-using-nodejs/package.json rename to test/build/config-format/auto/package.json index 2921f73c914..c49ae366fdc 100644 --- a/test/build/config-format/typescript-mjs-using-nodejs/package.json +++ b/test/build/config-format/auto/package.json @@ -1,5 +1,4 @@ { - "type": "module", "engines": { "node": ">=18.12.0" } diff --git a/test/build/config-format/auto/webpack.config.cjs b/test/build/config-format/auto/webpack.config.cjs new file mode 100644 index 00000000000..abfcb5385b0 --- /dev/null +++ b/test/build/config-format/auto/webpack.config.cjs @@ -0,0 +1,13 @@ +const path = require("node:path"); + +const mode = "development"; +const config = { + mode, + entry: "./main.js", + output: { + path: path.resolve("dist"), + filename: "foo.bundle.js", + }, +}; + +module.exports = config; diff --git a/test/build/config-format/auto/webpack.config.js b/test/build/config-format/auto/webpack.config.js new file mode 100644 index 00000000000..b00f4bdc850 --- /dev/null +++ b/test/build/config-format/auto/webpack.config.js @@ -0,0 +1,13 @@ +import * as path from "node:path"; + +const mode = "development"; +const config = { + mode, + entry: "./main.js", + output: { + path: path.resolve("dist"), + filename: "foo.bundle.js", + }, +}; + +export default config; diff --git a/test/build/config-format/auto/webpack.config.mjs b/test/build/config-format/auto/webpack.config.mjs new file mode 100644 index 00000000000..b00f4bdc850 --- /dev/null +++ b/test/build/config-format/auto/webpack.config.mjs @@ -0,0 +1,13 @@ +import * as path from "node:path"; + +const mode = "development"; +const config = { + mode, + entry: "./main.js", + output: { + path: path.resolve("dist"), + filename: "foo.bundle.js", + }, +}; + +export default config; diff --git a/test/build/config-format/disable-interpret/disable-interpret.test.js b/test/build/config-format/disable-interpret/disable-interpret.test.js index 5bbca3a227d..8033092e58c 100644 --- a/test/build/config-format/disable-interpret/disable-interpret.test.js +++ b/test/build/config-format/disable-interpret/disable-interpret.test.js @@ -21,7 +21,13 @@ describe("webpack cli", () => { }); it("should log error without transpilation", async () => { - const { exitCode, stderr, stdout } = await run(__dirname, ["--disable-interpret"]); + const [major] = process.versions.node.split(".").map(Number); + const { exitCode, stderr, stdout } = await run(__dirname, ["--disable-interpret"], { + nodeOptions: [ + // Disable typescript strip types for tests + ...(major >= 24 ? ["--no-experimental-strip-types"] : []), + ], + }); expect(exitCode).toBe(2); expect(stderr).toContain(`Failed to load '${resolve(__dirname, "webpack.config.ts")}' config`); diff --git a/test/build/config-format/esm-require-await/index.test.js b/test/build/config-format/esm-require-await/index.test.js deleted file mode 100644 index 002daf8c301..00000000000 --- a/test/build/config-format/esm-require-await/index.test.js +++ /dev/null @@ -1,18 +0,0 @@ -const { run } = require("../../../utils/test-utils"); - -describe("webpack cli", () => { - it("should support mjs config format using `require`", async () => { - const { exitCode, stdout } = await run(__dirname, ["-c", "webpack.config.js"]); - - const [major, minor] = process.versions.node.split(".").map(Number); - - if ((major >= 20 && minor >= 19) || major >= 22 || major >= 23) { - expect(exitCode).toBe(0); - // stderr contains - Support for loading ES Module in require() is an experimental feature and might change at any time - // expect(stderr).toBeFalsy(); - expect(stdout).toBeTruthy(); - } else { - expect(exitCode).toBe(2); - } - }); -}); diff --git a/test/build/config-format/esm-require/index.test.js b/test/build/config-format/esm-require/index.test.js deleted file mode 100644 index 770ed8238bd..00000000000 --- a/test/build/config-format/esm-require/index.test.js +++ /dev/null @@ -1,18 +0,0 @@ -const { run } = require("../../../utils/test-utils"); - -describe("webpack cli", () => { - it("should support mjs config format using `require`", async () => { - const { exitCode, stdout } = await run(__dirname, ["-c", "webpack.config.js"]); - - const [major, minor] = process.versions.node.split(".").map(Number); - - if ((major >= 20 && minor >= 17) || major >= 22 || major >= 23) { - expect(exitCode).toBe(0); - // stderr contains - Support for loading ES Module in require() is an experimental feature and might change at any time - // expect(stderr).toBeFalsy(); - expect(stdout).toBeTruthy(); - } else { - expect(exitCode).toBe(2); - } - }); -}); diff --git a/test/build/config-format/esm-require/main.js b/test/build/config-format/esm-require/main.js deleted file mode 100644 index ecbe8cd001a..00000000000 --- a/test/build/config-format/esm-require/main.js +++ /dev/null @@ -1 +0,0 @@ -console.log("You know who"); diff --git a/test/build/config-format/esm-require/webpack.config.js b/test/build/config-format/esm-require/webpack.config.js deleted file mode 100644 index 224ee8485a4..00000000000 --- a/test/build/config-format/esm-require/webpack.config.js +++ /dev/null @@ -1,11 +0,0 @@ -import { fileURLToPath } from "url"; -import path from "path"; - -export default { - mode: "development", - entry: "./main.js", - output: { - path: path.resolve(path.dirname(fileURLToPath(import.meta.url)), "dist"), - filename: "foo.bundle.js", - }, -}; diff --git a/test/build/config-format/esm-top-level-await/index.test.js b/test/build/config-format/esm-top-level-await/index.test.js new file mode 100644 index 00000000000..59f39b19680 --- /dev/null +++ b/test/build/config-format/esm-top-level-await/index.test.js @@ -0,0 +1,11 @@ +const { run } = require("../../../utils/test-utils"); + +describe("webpack cli", () => { + it("should support mjs config format using `require`", async () => { + const { exitCode, stderr, stdout } = await run(__dirname, ["-c", "webpack.config.mjs"]); + + expect(stderr).toBeFalsy(); + expect(stdout).toBeTruthy(); + expect(exitCode).toBe(0); + }); +}); diff --git a/test/build/config-format/esm-require-await/main.js b/test/build/config-format/esm-top-level-await/main.js similarity index 100% rename from test/build/config-format/esm-require-await/main.js rename to test/build/config-format/esm-top-level-await/main.js diff --git a/test/build/config-format/esm-require-await/webpack.config.js b/test/build/config-format/esm-top-level-await/webpack.config.mjs similarity index 62% rename from test/build/config-format/esm-require-await/webpack.config.js rename to test/build/config-format/esm-top-level-await/webpack.config.mjs index 44d22682863..5bc8a2105fd 100644 --- a/test/build/config-format/esm-require-await/webpack.config.js +++ b/test/build/config-format/esm-top-level-await/webpack.config.mjs @@ -1,6 +1,7 @@ -import { fileURLToPath } from "url"; -import path from "path"; +import path from "node:path"; +import { fileURLToPath } from "node:url"; +// eslint-disable-next-line unicorn/no-unnecessary-await const mode = await "development"; export default { diff --git a/test/build/config-format/typescript-mjs-using-nodejs/main.ts b/test/build/config-format/typescript-auto/main.ts similarity index 100% rename from test/build/config-format/typescript-mjs-using-nodejs/main.ts rename to test/build/config-format/typescript-auto/main.ts diff --git a/test/build/config-format/typescript-ts-node-loader/package.json b/test/build/config-format/typescript-auto/package.json similarity index 70% rename from test/build/config-format/typescript-ts-node-loader/package.json rename to test/build/config-format/typescript-auto/package.json index 2921f73c914..c49ae366fdc 100644 --- a/test/build/config-format/typescript-ts-node-loader/package.json +++ b/test/build/config-format/typescript-auto/package.json @@ -1,5 +1,4 @@ { - "type": "module", "engines": { "node": ">=18.12.0" } diff --git a/test/build/config-format/typescript-auto/typescript.test.mjs b/test/build/config-format/typescript-auto/typescript.test.mjs new file mode 100644 index 00000000000..c6e1792d7d2 --- /dev/null +++ b/test/build/config-format/typescript-auto/typescript.test.mjs @@ -0,0 +1,74 @@ +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("typescript configuration", () => { + it("should support typescript configuration (Node.js build-in support)", async () => { + const [major] = process.versions.node.split(".").map(Number); + const { exitCode, stderr, stdout } = await run(__dirname, ["-c", "./webpack.config.ts"], { + // Fallback to `ts-node/esm` for old Node.js versions + nodeOptions: + major >= 22 + ? [] + : [ + "--no-deprecation", + "--import=data:text/javascript,import { register } from 'node:module'; import { pathToFileURL } from 'node:url'; register('ts-node/esm', pathToFileURL('./'));", + ], + }); + + if (major >= 22) { + // No `type` in `the package.json` but Node.js support `require` ECMA modules + expect(stderr).toContain( + "Reparsing as ES module because module syntax was detected. This incurs a performance overhead.", + ); + } else { + expect(stderr).toBeFalsy(); + } + + expect(stdout).toBeTruthy(); + expect(exitCode).toBe(0); + expect(existsSync(resolve(__dirname, "dist/foo.bundle.js"))).toBeTruthy(); + }); + + it("should support typescript configuration (Node.js build-in support) with `mts` extension", async () => { + const [major] = process.versions.node.split(".").map(Number); + const { exitCode, stderr, stdout } = await run(__dirname, ["-c", "./webpack.config.mts"], { + // Fallback to `ts-node/esm` for old Node.js versions + nodeOptions: + major >= 22 + ? [] + : [ + "--no-deprecation", + "--import=data:text/javascript,import { register } from 'node:module'; import { pathToFileURL } from 'node:url'; register('ts-node/esm', pathToFileURL('./'));", + ], + }); + + expect(stderr).toBeFalsy(); + expect(stdout).toBeTruthy(); + expect(exitCode).toBe(0); + expect(existsSync(resolve(__dirname, "dist/foo.bundle.js"))).toBeTruthy(); + }); + + it("should support typescript configuration (Node.js build-in support) with `cts` extension", async () => { + const [major] = process.versions.node.split(".").map(Number); + const { exitCode, stderr, stdout } = await run(__dirname, ["-c", "./webpack.config.cts"], { + // Fallback to `ts-node/esm` for old Node.js versions + nodeOptions: + major >= 22 + ? [] + : [ + "--no-deprecation", + "--import=data:text/javascript,import { register } from 'node:module'; import { pathToFileURL } from 'node:url'; register('ts-node/esm', pathToFileURL('./'));", + ], + }); + + expect(stderr).toBeFalsy(); + expect(stdout).toBeTruthy(); + expect(exitCode).toBe(0); + expect(existsSync(resolve(__dirname, "dist/foo.bundle.js"))).toBeTruthy(); + }); +}); diff --git a/test/build/config-format/typescript-cjs-using-nodejs/webpack.config.ts b/test/build/config-format/typescript-auto/webpack.config.cts similarity index 100% rename from test/build/config-format/typescript-cjs-using-nodejs/webpack.config.ts rename to test/build/config-format/typescript-auto/webpack.config.cts diff --git a/test/build/config-format/typescript-mjs-using-nodejs/webpack.config.ts b/test/build/config-format/typescript-auto/webpack.config.mts similarity index 100% rename from test/build/config-format/typescript-mjs-using-nodejs/webpack.config.ts rename to test/build/config-format/typescript-auto/webpack.config.mts diff --git a/test/build/config-format/typescript-ts-node-loader/webpack.config.ts b/test/build/config-format/typescript-auto/webpack.config.ts similarity index 100% rename from test/build/config-format/typescript-ts-node-loader/webpack.config.ts rename to test/build/config-format/typescript-auto/webpack.config.ts diff --git a/test/build/config-format/typescript-cjs-using-nodejs/typescript.test.mjs b/test/build/config-format/typescript-cjs-using-nodejs/typescript.test.mjs deleted file mode 100644 index 6cf4dd1c201..00000000000 --- a/test/build/config-format/typescript-cjs-using-nodejs/typescript.test.mjs +++ /dev/null @@ -1,26 +0,0 @@ -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 () => { - const [major] = process.versions.node.split(".").map(Number); - const { exitCode, stderr, stdout } = await run( - __dirname, - ["-c", "./webpack.config.ts", "--disable-interpret"], - { - // Fallback to `ts-node/esm` for old Node.js versions - nodeOptions: major >= 24 ? [] : ["--require=ts-node/register"], - }, - ); - - expect(stderr).toBeFalsy(); // Deprecation warning logs on stderr - expect(stdout).toBeTruthy(); - expect(exitCode).toBe(0); - expect(existsSync(resolve(__dirname, "dist/foo.bundle.js"))).toBeTruthy(); - }); -}); diff --git a/test/build/config-format/typescript-ts-node-loader/main.ts b/test/build/config-format/typescript-cjs/main.ts similarity index 100% rename from test/build/config-format/typescript-ts-node-loader/main.ts rename to test/build/config-format/typescript-cjs/main.ts diff --git a/test/build/config-format/typescript-cjs-using-nodejs/package.json b/test/build/config-format/typescript-cjs/package.json similarity index 100% rename from test/build/config-format/typescript-cjs-using-nodejs/package.json rename to test/build/config-format/typescript-cjs/package.json diff --git a/test/build/config-format/typescript-cjs-using-nodejs/tsconfig.json b/test/build/config-format/typescript-cjs/tsconfig.json similarity index 100% rename from test/build/config-format/typescript-cjs-using-nodejs/tsconfig.json rename to test/build/config-format/typescript-cjs/tsconfig.json diff --git a/test/build/config-format/typescript-cjs/typescript.test.mjs b/test/build/config-format/typescript-cjs/typescript.test.mjs new file mode 100644 index 00000000000..b578226de94 --- /dev/null +++ b/test/build/config-format/typescript-cjs/typescript.test.mjs @@ -0,0 +1,93 @@ +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("typescript commonjs configuration", () => { + it("should support typescript commonjs configuration (Node.js build-in support)", async () => { + const [major] = process.versions.node.split(".").map(Number); + const { exitCode, stderr, stdout } = await run(__dirname, ["-c", "./webpack.config.ts"], { + // Fallback to `ts-node/register` for old Node.js versions + nodeOptions: major >= 22 ? [] : ["--require=ts-node/register"], + }); + + expect(stderr).toBeFalsy(); + expect(stdout).toBeTruthy(); + expect(exitCode).toBe(0); + expect(existsSync(resolve(__dirname, "dist/foo.bundle.js"))).toBeTruthy(); + }); + + it("should support typescript commonjs configuration (using `--require=ts-node/register`)", async () => { + const [major] = process.versions.node.split(".").map(Number); + const { exitCode, stderr, stdout } = await run(__dirname, ["-c", "./webpack.config.ts"], { + nodeOptions: [ + "--require=ts-node/register", + // Disable typescript strip types for tests + ...(major >= 22 ? ["--no-experimental-strip-types"] : []), + ], + }); + + expect(stderr).toBeFalsy(); + expect(stdout).toBeTruthy(); + expect(exitCode).toBe(0); + expect(existsSync(resolve(__dirname, "dist/foo.bundle.js"))).toBeTruthy(); + }); + + it("should support typescript commonjs configuration (using `--require=ts-node/register` and disable `interpret`)", async () => { + const [major] = process.versions.node.split(".").map(Number); + const { exitCode, stderr, stdout } = await run( + __dirname, + ["-c", "./webpack.config.ts", "--disable-interpret"], + { + nodeOptions: [ + "--require=ts-node/register", + // Disable typescript strip types for tests + ...(major >= 22 ? ["--no-experimental-strip-types"] : []), + ], + }, + ); + + expect(stderr).toBeFalsy(); + expect(stdout).toBeTruthy(); + expect(exitCode).toBe(0); + expect(existsSync(resolve(__dirname, "dist/foo.bundle.js"))).toBeTruthy(); + }); + + it("should support typescript commonjs configuration (using `--import=ts-node/register` and disable `interpret`)", async () => { + const [major] = process.versions.node.split(".").map(Number); + const { exitCode, stderr, stdout } = await run( + __dirname, + ["-c", "./webpack.config.ts", "--disable-interpret"], + { + nodeOptions: [ + "--import=ts-node/register", + // Disable typescript strip types for tests + ...(major >= 22 ? ["--no-experimental-strip-types"] : []), + ], + }, + ); + + expect(stderr).toBeFalsy(); + expect(stdout).toBeTruthy(); + expect(exitCode).toBe(0); + expect(existsSync(resolve(__dirname, "dist/foo.bundle.js"))).toBeTruthy(); + }); + + it("should support typescript commonjs configuration (using `interpret`)", async () => { + const [major] = process.versions.node.split(".").map(Number); + const { exitCode, stderr, stdout } = await run(__dirname, ["-c", "./webpack.config.ts"], { + nodeOptions: [ + // Disable typescript strip types for tests + ...(major >= 22 ? ["--no-experimental-strip-types"] : []), + ], + }); + + expect(stderr).toBeFalsy(); + expect(stdout).toBeTruthy(); + expect(exitCode).toBe(0); + expect(existsSync(resolve(__dirname, "dist/foo.bundle.js"))).toBeTruthy(); + }); +}); diff --git a/test/build/config-format/typescript-ts-node-require/webpack.config.ts b/test/build/config-format/typescript-cjs/webpack.config.ts similarity index 68% rename from test/build/config-format/typescript-ts-node-require/webpack.config.ts rename to test/build/config-format/typescript-cjs/webpack.config.ts index f53400f9b25..586bd1b1cf3 100644 --- a/test/build/config-format/typescript-ts-node-require/webpack.config.ts +++ b/test/build/config-format/typescript-cjs/webpack.config.ts @@ -1,4 +1,4 @@ -import * as path from "node:path"; +const path = require("node:path"); /* eslint-disable no-useless-concat */ @@ -8,9 +8,9 @@ const config = { mode, entry: "./main.ts", output: { - path: path.resolve(__dirname, "dist"), + path: path.resolve("dist"), filename: "foo.bundle.js", }, }; -export = config; +module.exports = config; diff --git a/test/build/config-format/typescript-mjs-using-nodejs/typescript.test.mjs b/test/build/config-format/typescript-mjs-using-nodejs/typescript.test.mjs deleted file mode 100644 index 33638220420..00000000000 --- a/test/build/config-format/typescript-mjs-using-nodejs/typescript.test.mjs +++ /dev/null @@ -1,29 +0,0 @@ -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 () => { - const [major] = process.versions.node.split(".").map(Number); - const { exitCode, stderr, stdout } = await run( - __dirname, - ["-c", "./webpack.config.ts", "--disable-interpret"], - { - env: { - NODE_NO_WARNINGS: 1, - }, - // Fallback to `ts-node/esm` for old Node.js versions - nodeOptions: major >= 24 ? [] : ["--experimental-loader=ts-node/esm"], - }, - ); - - expect(stderr).toBeFalsy(); // Deprecation warning logs on stderr - expect(stdout).toBeTruthy(); - expect(exitCode).toBe(0); - expect(existsSync(resolve(__dirname, "dist/foo.bundle.js"))).toBeTruthy(); - }); -}); diff --git a/test/build/config-format/typescript-using-nodejs/main.ts b/test/build/config-format/typescript-mjs/main.ts similarity index 100% rename from test/build/config-format/typescript-using-nodejs/main.ts rename to test/build/config-format/typescript-mjs/main.ts diff --git a/test/build/config-format/babel-esm/package.json b/test/build/config-format/typescript-mjs/package.json similarity index 100% rename from test/build/config-format/babel-esm/package.json rename to test/build/config-format/typescript-mjs/package.json diff --git a/test/build/config-format/typescript-mjs-using-nodejs/tsconfig.json b/test/build/config-format/typescript-mjs/tsconfig.json similarity index 100% rename from test/build/config-format/typescript-mjs-using-nodejs/tsconfig.json rename to test/build/config-format/typescript-mjs/tsconfig.json diff --git a/test/build/config-format/typescript-mjs/typescript.test.mjs b/test/build/config-format/typescript-mjs/typescript.test.mjs new file mode 100644 index 00000000000..03acf17b9a9 --- /dev/null +++ b/test/build/config-format/typescript-mjs/typescript.test.mjs @@ -0,0 +1,101 @@ +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("typescript ecma modules configuration", () => { + it("should support typescript ecma modules configuration (Node.js build-in support)", async () => { + const [major] = process.versions.node.split(".").map(Number); + const { exitCode, stderr, stdout } = await run(__dirname, ["-c", "./webpack.config.ts"], { + // Fallback to `ts-node/esm` for old Node.js versions + nodeOptions: + major >= 22 + ? [] + : [ + "--no-deprecation", + "--import=data:text/javascript,import { register } from 'node:module'; import { pathToFileURL } from 'node:url'; register('ts-node/esm', pathToFileURL('./'));", + ], + }); + + expect(stderr).toBeFalsy(); + expect(stdout).toBeTruthy(); + expect(exitCode).toBe(0); + expect(existsSync(resolve(__dirname, "dist/foo.bundle.js"))).toBeTruthy(); + }); + + it("should support typescript ecma modules configuration (Node.js build-in support using `--experimental-transform-types`)", async () => { + const [major] = process.versions.node.split(".").map(Number); + const { exitCode, stderr, stdout } = await run(__dirname, ["-c", "./webpack.config.ts"], { + // Fallback to `ts-node/esm` for old Node.js versions + nodeOptions: + major >= 22 + ? ["--experimental-transform-types", "--no-warnings"] + : [ + "--no-deprecation", + "--import=data:text/javascript,import { register } from 'node:module'; import { pathToFileURL } from 'node:url'; register('ts-node/esm', pathToFileURL('./'));", + ], + }); + + expect(stderr).toBeFalsy(); + expect(stdout).toBeTruthy(); + expect(exitCode).toBe(0); + expect(existsSync(resolve(__dirname, "dist/foo.bundle.js"))).toBeTruthy(); + }); + + it("should support typescript ecma modules configuration (using `--import` and prefer `--import` over built-in feature)", async () => { + const [major] = process.versions.node.split(".").map(Number); + const { exitCode, stderr, stdout } = await run(__dirname, ["-c", "./webpack.config.ts"], { + // Fallback to `ts-node/esm` for old Node.js versions + nodeOptions: + major >= 22 + ? [] + : [ + "--no-deprecation", + "--import=data:text/javascript,import { register } from 'node:module'; import { pathToFileURL } from 'node:url'; register('ts-node/esm', pathToFileURL('./'));", + ], + }); + + expect(stderr).toBeFalsy(); + expect(stdout).toBeTruthy(); + expect(exitCode).toBe(0); + expect(existsSync(resolve(__dirname, "dist/foo.bundle.js"))).toBeTruthy(); + }); + + it("should support typescript ecma modules configuration (using `--import=ts-node/esm`)", async () => { + const [major] = process.versions.node.split(".").map(Number); + const { exitCode, stderr, stdout } = await run(__dirname, ["-c", "./webpack.config.ts"], { + nodeOptions: [ + "--no-deprecation", + "--import=data:text/javascript,import { register } from 'node:module'; import { pathToFileURL } from 'node:url'; register('ts-node/esm', pathToFileURL('./'));", + ...(major >= 22 ? ["--no-experimental-strip-types"] : []), + ], + }); + + expect(stderr).toBeFalsy(); + expect(stdout).toBeTruthy(); + expect(exitCode).toBe(0); + expect(existsSync(resolve(__dirname, "dist/foo.bundle.js"))).toBeTruthy(); + }); + + it("should support typescript ecma modules configuration (using `--experimental-loader=ts-node/esm`)", async () => { + const [major] = process.versions.node.split(".").map(Number); + const { exitCode, stderr, stdout } = await run(__dirname, ["-c", "./webpack.config.ts"], { + env: { + NODE_NO_WARNINGS: 1, + }, + nodeOptions: [ + "--no-deprecation", + "--experimental-loader=ts-node/esm", + ...(major >= 22 ? ["--no-experimental-strip-types"] : []), + ], + }); + + expect(stderr).toBeFalsy(); + expect(stdout).toBeTruthy(); + expect(exitCode).toBe(0); + expect(existsSync(resolve(__dirname, "dist/foo.bundle.js"))).toBeTruthy(); + }); +}); diff --git a/test/build/config-format/typescript-using-nodejs/webpack.config.ts b/test/build/config-format/typescript-mjs/webpack.config.ts similarity index 100% rename from test/build/config-format/typescript-using-nodejs/webpack.config.ts rename to test/build/config-format/typescript-mjs/webpack.config.ts diff --git a/test/build/config-format/typescript-ts-node-loader/tsconfig.json b/test/build/config-format/typescript-ts-node-loader/tsconfig.json deleted file mode 100644 index e0ba2dc7a46..00000000000 --- a/test/build/config-format/typescript-ts-node-loader/tsconfig.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "compilerOptions": { - "module": "esnext", - "allowSyntheticDefaultImports": true - } -} diff --git a/test/build/config-format/typescript-ts-node-loader/typescript.test.mjs b/test/build/config-format/typescript-ts-node-loader/typescript.test.mjs deleted file mode 100644 index 8653ad72ae8..00000000000 --- a/test/build/config-format/typescript-ts-node-loader/typescript.test.mjs +++ /dev/null @@ -1,27 +0,0 @@ -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 () => { - const [major, minor] = process.versions.node.split(".").map(Number); - const { exitCode, stderr, stdout } = await run(__dirname, ["-c", "./webpack.config.ts"], { - env: { - NODE_NO_WARNINGS: 1, - }, - nodeOptions: - major >= 22 && minor >= 6 - ? ["--no-experimental-strip-types", "--experimental-loader=ts-node/esm"] - : ["--experimental-loader=ts-node/esm"], - }); - - expect(stderr).toBeFalsy(); // Deprecation warning logs on stderr - expect(stdout).toBeTruthy(); - expect(exitCode).toBe(0); - expect(existsSync(resolve(__dirname, "dist/foo.bundle.js"))).toBeTruthy(); - }); -}); diff --git a/test/build/config-format/typescript-ts-node-require/main.ts b/test/build/config-format/typescript-ts-node-require/main.ts deleted file mode 100644 index 41d13d1a9a1..00000000000 --- a/test/build/config-format/typescript-ts-node-require/main.ts +++ /dev/null @@ -1 +0,0 @@ -console.log("Main typescript file"); diff --git a/test/build/config-format/typescript-ts-node-require/tsconfig.json b/test/build/config-format/typescript-ts-node-require/tsconfig.json deleted file mode 100644 index 391488ab17f..00000000000 --- a/test/build/config-format/typescript-ts-node-require/tsconfig.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "compilerOptions": { - "module": "commonjs" - } -} diff --git a/test/build/config-format/typescript-ts-node-require/typescript.test.js b/test/build/config-format/typescript-ts-node-require/typescript.test.js deleted file mode 100644 index 4041596d9fd..00000000000 --- a/test/build/config-format/typescript-ts-node-require/typescript.test.js +++ /dev/null @@ -1,21 +0,0 @@ -const { existsSync } = require("node:fs"); -const { resolve } = require("node:path"); -const { run } = require("../../../utils/test-utils"); - -describe("webpack cli", () => { - it("should support typescript file", async () => { - const [major, minor] = process.versions.node.split(".").map(Number); - const { exitCode, stderr, stdout } = await run(__dirname, ["-c", "./webpack.config.ts"], { - env: { NODE_NO_WARNINGS: 1 }, - nodeOptions: - major >= 22 && minor >= 6 - ? ["--no-experimental-strip-types", "--require=ts-node/register"] - : ["--require=ts-node/register"], - }); - - expect(stderr).toBeFalsy(); - expect(stdout).toBeTruthy(); - expect(exitCode).toBe(0); - expect(existsSync(resolve(__dirname, "dist/foo.bundle.js"))).toBeTruthy(); - }); -}); diff --git a/test/build/config-format/typescript-using-nodejs/package.json b/test/build/config-format/typescript-using-nodejs/package.json deleted file mode 100644 index 2921f73c914..00000000000 --- a/test/build/config-format/typescript-using-nodejs/package.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "type": "module", - "engines": { - "node": ">=18.12.0" - } -} diff --git a/test/build/config-format/typescript-using-nodejs/tsconfig.json b/test/build/config-format/typescript-using-nodejs/tsconfig.json deleted file mode 100644 index 3cf557d8735..00000000000 --- a/test/build/config-format/typescript-using-nodejs/tsconfig.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "compilerOptions": { - "target": "esnext", - "allowImportingTsExtensions": true, - "rewriteRelativeImportExtensions": true, - "module": "esnext" - } -} diff --git a/test/build/config-format/typescript-using-nodejs/typescript.test.mjs b/test/build/config-format/typescript-using-nodejs/typescript.test.mjs deleted file mode 100644 index 33638220420..00000000000 --- a/test/build/config-format/typescript-using-nodejs/typescript.test.mjs +++ /dev/null @@ -1,29 +0,0 @@ -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 () => { - const [major] = process.versions.node.split(".").map(Number); - const { exitCode, stderr, stdout } = await run( - __dirname, - ["-c", "./webpack.config.ts", "--disable-interpret"], - { - env: { - NODE_NO_WARNINGS: 1, - }, - // Fallback to `ts-node/esm` for old Node.js versions - nodeOptions: major >= 24 ? [] : ["--experimental-loader=ts-node/esm"], - }, - ); - - expect(stderr).toBeFalsy(); // Deprecation warning logs on stderr - expect(stdout).toBeTruthy(); - expect(exitCode).toBe(0); - expect(existsSync(resolve(__dirname, "dist/foo.bundle.js"))).toBeTruthy(); - }); -}); diff --git a/test/build/custom-webpack/custom-webpack.test.js b/test/build/custom-webpack/custom-webpack.test.js index a8764c4c1f8..94b2c54486e 100644 --- a/test/build/custom-webpack/custom-webpack.test.js +++ b/test/build/custom-webpack/custom-webpack.test.js @@ -19,9 +19,6 @@ describe("custom-webpack", () => { env: { WEBPACK_PACKAGE: resolve(__dirname, "./custom-webpack.js") }, }); - console.log(stderr); - console.log(stdout); - expect(exitCode).toBe(0); expect(stderr).toBeFalsy(); expect(stdout).toContain("main.js");