From 51066846326bcae5f9793d3496325213342d3dd2 Mon Sep 17 00:00:00 2001 From: Alexander Akait <4567934+alexander-akait@users.noreply.github.com> Date: Fri, 13 Dec 2024 19:22:16 +0300 Subject: [PATCH] fix: allow require `webpack.config.js` in ESM format (#4346) --- .eslintignore | 1 + packages/webpack-cli/src/webpack-cli.ts | 1 + .../babel-commonjs/babel-esm.test.js | 2 -- .../config-format/babel-esm/babel-esm.test.js | 12 ------------ .../build/config-format/babel-esm/package.json | 6 ------ .../esm-require-await/index.test.js | 18 ++++++++++++++++++ .../{babel-esm => esm-require-await}/main.js | 0 .../esm-require-await/webpack.config.js | 13 +++++++++++++ .../config-format/esm-require/index.test.js | 18 ++++++++++++++++++ test/build/config-format/esm-require/main.js | 1 + .../webpack.config.js} | 0 11 files changed, 52 insertions(+), 20 deletions(-) delete mode 100644 test/build/config-format/babel-esm/babel-esm.test.js delete mode 100644 test/build/config-format/babel-esm/package.json create mode 100644 test/build/config-format/esm-require-await/index.test.js rename test/build/config-format/{babel-esm => esm-require-await}/main.js (100%) create mode 100644 test/build/config-format/esm-require-await/webpack.config.js create mode 100644 test/build/config-format/esm-require/index.test.js create mode 100644 test/build/config-format/esm-require/main.js rename test/build/config-format/{babel-esm/webpack.config.babel.js => esm-require/webpack.config.js} (100%) diff --git a/.eslintignore b/.eslintignore index 91718ffa7a2..844c3971e3f 100644 --- a/.eslintignore +++ b/.eslintignore @@ -10,4 +10,5 @@ test/**/index.js test/build/config/error-commonjs/syntax-error.js test/build/config/error-mjs/syntax-error.mjs 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 diff --git a/packages/webpack-cli/src/webpack-cli.ts b/packages/webpack-cli/src/webpack-cli.ts index a4a82de9c78..312d4bd98cf 100644 --- a/packages/webpack-cli/src/webpack-cli.ts +++ b/packages/webpack-cli/src/webpack-cli.ts @@ -351,6 +351,7 @@ class WebpackCLI implements IWebpackCLI { require("./utils/dynamic-import-loader")(); if ( ((error as ImportLoaderError).code === "ERR_REQUIRE_ESM" || + (error as ImportLoaderError).code === "ERR_REQUIRE_ASYNC_MODULE" || process.env.WEBPACK_CLI_FORCE_LOAD_ESM_CONFIG) && pathToFileURL && dynamicImportLoader diff --git a/test/build/config-format/babel-commonjs/babel-esm.test.js b/test/build/config-format/babel-commonjs/babel-esm.test.js index d3d43c33882..383d46566dc 100644 --- a/test/build/config-format/babel-commonjs/babel-esm.test.js +++ b/test/build/config-format/babel-commonjs/babel-esm.test.js @@ -5,8 +5,6 @@ describe("webpack cli", () => { it("should support mjs config format", async () => { const { exitCode, stderr, stdout } = await run(__dirname, ["-c", "webpack.config.babel.js"]); - console.log(stderr); - expect(exitCode).toBe(0); expect(stderr).toBeFalsy(); expect(stdout).toBeTruthy(); diff --git a/test/build/config-format/babel-esm/babel-esm.test.js b/test/build/config-format/babel-esm/babel-esm.test.js deleted file mode 100644 index 383d46566dc..00000000000 --- a/test/build/config-format/babel-esm/babel-esm.test.js +++ /dev/null @@ -1,12 +0,0 @@ -// eslint-disable-next-line n/no-unpublished-require -const { run } = require("../../../utils/test-utils"); - -describe("webpack cli", () => { - it("should support mjs config format", async () => { - const { exitCode, stderr, stdout } = await run(__dirname, ["-c", "webpack.config.babel.js"]); - - expect(exitCode).toBe(0); - expect(stderr).toBeFalsy(); - expect(stdout).toBeTruthy(); - }); -}); diff --git a/test/build/config-format/babel-esm/package.json b/test/build/config-format/babel-esm/package.json deleted file mode 100644 index aa65b114f15..00000000000 --- a/test/build/config-format/babel-esm/package.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "type": "module", - "engines": { - "node": ">=14.15.0" - } -} diff --git a/test/build/config-format/esm-require-await/index.test.js b/test/build/config-format/esm-require-await/index.test.js new file mode 100644 index 00000000000..0dc300d0584 --- /dev/null +++ b/test/build/config-format/esm-require-await/index.test.js @@ -0,0 +1,18 @@ +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 >= 22 && minor >= 11) || 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/babel-esm/main.js b/test/build/config-format/esm-require-await/main.js similarity index 100% rename from test/build/config-format/babel-esm/main.js rename to test/build/config-format/esm-require-await/main.js diff --git a/test/build/config-format/esm-require-await/webpack.config.js b/test/build/config-format/esm-require-await/webpack.config.js new file mode 100644 index 00000000000..44d22682863 --- /dev/null +++ b/test/build/config-format/esm-require-await/webpack.config.js @@ -0,0 +1,13 @@ +import { fileURLToPath } from "url"; +import path from "path"; + +const mode = await "development"; + +export default { + mode, + 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-require/index.test.js b/test/build/config-format/esm-require/index.test.js new file mode 100644 index 00000000000..0dc300d0584 --- /dev/null +++ b/test/build/config-format/esm-require/index.test.js @@ -0,0 +1,18 @@ +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 >= 22 && minor >= 11) || 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 new file mode 100644 index 00000000000..ecbe8cd001a --- /dev/null +++ b/test/build/config-format/esm-require/main.js @@ -0,0 +1 @@ +console.log("You know who"); diff --git a/test/build/config-format/babel-esm/webpack.config.babel.js b/test/build/config-format/esm-require/webpack.config.js similarity index 100% rename from test/build/config-format/babel-esm/webpack.config.babel.js rename to test/build/config-format/esm-require/webpack.config.js