Repository: webpack/webpack (JavaScript)

Issue:
update default target when `output.module=true`
<!-- Please don't delete this template or we'll close your issue -->

## Feature request

update defaults when bundling esm library

<!-- Issues that contain questions or support requests will be closed. -->
<!-- Before creating an issue please make sure you are using the latest version of webpack. -->
<!-- Check if this feature needs to be implemented in a plugin or loader instead -->
<!-- If yes: file the issue on the plugin/loader repo -->
<!-- Features related to the development server should be filed on this repo instead -->

**What is the expected behavior?**

with
```js
output: {
   module: true
}
```
webpack should set default `output.environment.module=true`


**What is motivation or use case for adding/changing the behavior?**

when building esm bundle/library output environment  should support es modules

**How should this be implemented in your opinion?**

update defaults

**Are you willing to work on this yourself?**
yes



Hints:
@vankop I think we can do it only in the next major release, because externals, plugins and chunk loading can be different and do not support ESM output
this is work only with `experiments.outputModule=true`, so it should be ok..
See also https://github.com/webpack/webpack/discussions/15291 and https://github.com/webpack/webpack/issues/15290.

Patch:
diff --git a/lib/config/defaults.js b/lib/config/defaults.js
--- a/lib/config/defaults.js
+++ b/lib/config/defaults.js
@@ -907,6 +907,7 @@ const applyOutputDefaults = (
 	D(output, "strictModuleExceptionHandling", false);
 
 	const optimistic = v => v || v === undefined;
+	const conditionallyOptimistic = (v, c) => (v === undefined && c) || v;
 	F(
 		output.environment,
 		"arrowFunction",
@@ -920,8 +921,12 @@ const applyOutputDefaults = (
 	);
 	F(output.environment, "forOf", () => tp && optimistic(tp.forOf));
 	F(output.environment, "bigIntLiteral", () => tp && tp.bigIntLiteral);
-	F(output.environment, "dynamicImport", () => tp && tp.dynamicImport);
-	F(output.environment, "module", () => tp && tp.module);
+	F(output.environment, "dynamicImport", () =>
+		conditionallyOptimistic(tp && tp.dynamicImport, output.module)
+	);
+	F(output.environment, "module", () =>
+		conditionallyOptimistic(tp && tp.module, output.module)
+	);
 
 	const { trustedTypes } = output;
 	if (trustedTypes) {


Test patch:
diff --git a/test/Defaults.unittest.js b/test/Defaults.unittest.js
--- a/test/Defaults.unittest.js
+++ b/test/Defaults.unittest.js
@@ -882,6 +882,12 @@ describe("Defaults", () => {
 		-     "chunkFilename": "[name].js",
 		+     "chunkFilename": "[name].mjs",
 		@@ ... @@
+		-       "dynamicImport": undefined,
+		+       "dynamicImport": true,
+		@@ ... @@
+		-       "module": undefined,
+		+       "module": true,
+		@@ ... @@
 		-     "filename": "[name].js",
 		+     "filename": "[name].mjs",
 		@@ ... @@
diff --git a/test/configCases/output-module/check-defaults/errors.js b/test/configCases/output-module/check-defaults/errors.js
new file mode 100644
--- /dev/null
+++ b/test/configCases/output-module/check-defaults/errors.js
@@ -0,0 +1,3 @@
+module.exports = [
+	[/For the selected environment is no default ESM chunk format available/]
+];
diff --git a/test/configCases/output-module/check-defaults/index.js b/test/configCases/output-module/check-defaults/index.js
new file mode 100644
--- /dev/null
+++ b/test/configCases/output-module/check-defaults/index.js
@@ -0,0 +1,3 @@
+it("should compile and run", () => {
+	expect(import.meta.url).toBe(import.meta.url);
+});
diff --git a/test/configCases/output-module/check-defaults/webpack.config.js b/test/configCases/output-module/check-defaults/webpack.config.js
new file mode 100644
--- /dev/null
+++ b/test/configCases/output-module/check-defaults/webpack.config.js
@@ -0,0 +1,17 @@
+/** @type {import("../../../../").Configuration[]} */
+module.exports = [
+	{
+		experiments: {
+			outputModule: true
+		},
+		devtool: false,
+		target: "web"
+	},
+	{
+		experiments: {
+			outputModule: true
+		},
+		devtool: false,
+		target: "node10"
+	}
+];