Repository: webpack/webpack (JavaScript)

Issue:
Add logging to DefinePlugin.js
<!-- Thanks for submitting a pull request! Please provide enough information so that others can review your pull request. -->
<!-- Explain the **motivation** for making this change. What existing problem does the pull request solve? -->
<!-- Try to link to an open issue for more information. -->


<!-- In addition to that please answer these questions: -->

This PR adds the changes described in #15778. Once merged, this PR will resolve #15778.

**What kind of change does this PR introduce?**
This change adds logging to `DefinePlugin`.

<!-- E.g. a bugfix, feature, refactoring, build related change, etc… -->

**Did you add tests for your changes?**
No.

<!-- Note that we won't merge your changes if you don't add tests -->

**Does this PR introduce a breaking change?**
No.

<!-- If this PR introduces a breaking change, please describe the impact and a migration path for existing applications. -->

**What needs to be documented once your changes are merged?**
Nothing. In the initial design for this feature, I proposed to use a flag for `DefinePlugin` logs. Once I started working on this feature I realised that it is probably better to use `logger.log(...)` since it fits our use case perfectly.

<!-- List all the information that needs to be added to the documentation after merge -->
<!-- When your changes are merged you will be asked to contribute this to the documentation -->



Hints:
<a href="https://easycla.lfx.linuxfoundation.org/#/?version=2"><img src="https://s3.amazonaws.com/cla-project-logo-prod/cla-signed.svg" alt="CLA Signed" align="left" height="28" width="328" ></a><br/><br />The committers listed above are authorized under a signed CLA.<ul><li>:white_check_mark: login: hdragos / name: Hasmasan Dragos  (34b63116f96cdf044f7de27955ef1cad785cc427)</li></ul>
<!-- identifier: admin-actions -->

*For maintainers only:*

* [ ] <!-- document --> This needs to be documented (issue in webpack/webpack.js.org will be filed when merged)
* [ ] <!-- webpack-4-backport --> This needs to be backported to webpack 4 (issue will be created when merged)
<!-- identifier: head-main -->

Hi @hdragos.

Just a little hint from a friendly bot about the best practice when submitting pull requests:

> Don't submit pull request from your own `main` branch. It's recommended to create a feature branch for the PR.

*You don't have to change it for this PR, just make sure to follow this hint the next time you submit a PR.*
@hdragos Sorry for that, but can you rebase?

Patch:
diff --git a/lib/DefinePlugin.js b/lib/DefinePlugin.js
--- a/lib/DefinePlugin.js
+++ b/lib/DefinePlugin.js
@@ -26,6 +26,7 @@ const createHash = require("./util/createHash");
 /** @typedef {import("./NormalModule")} NormalModule */
 /** @typedef {import("./RuntimeTemplate")} RuntimeTemplate */
 /** @typedef {import("./javascript/JavascriptParser")} JavascriptParser */
+/** @typedef {import("./logging/Logger").Logger} Logger */
 
 /** @typedef {null|undefined|RegExp|Function|string|number|boolean|bigint|undefined} CodeValuePrimitive */
 /** @typedef {RecursiveArrayOrRecord<CodeValuePrimitive|RuntimeValue>} CodeValue */
@@ -117,6 +118,7 @@ class RuntimeValue {
  * @param {Map<string, string | Set<string>>} valueCacheVersions valueCacheVersions
  * @param {string} key the defined key
  * @param {RuntimeTemplate} runtimeTemplate the runtime template
+ * @param {Logger} logger the logger object
  * @param {boolean|undefined|null=} asiSafe asi safe (undefined: unknown, null: unneeded)
  * @param {Set<string>|undefined=} objKeys used keys
  * @returns {string} code converted to string that evaluates
@@ -127,6 +129,7 @@ const stringifyObj = (
 	valueCacheVersions,
 	key,
 	runtimeTemplate,
+	logger,
 	asiSafe,
 	objKeys
 ) => {
@@ -135,7 +138,15 @@ const stringifyObj = (
 	if (arr) {
 		code = `[${obj
 			.map(code =>
-				toCode(code, parser, valueCacheVersions, key, runtimeTemplate, null)
+				toCode(
+					code,
+					parser,
+					valueCacheVersions,
+					key,
+					runtimeTemplate,
+					logger,
+					null
+				)
 			)
 			.join(",")}]`;
 	} else {
@@ -150,7 +161,15 @@ const stringifyObj = (
 				return (
 					JSON.stringify(key) +
 					":" +
-					toCode(code, parser, valueCacheVersions, key, runtimeTemplate, null)
+					toCode(
+						code,
+						parser,
+						valueCacheVersions,
+						key,
+						runtimeTemplate,
+						logger,
+						null
+					)
 				);
 			})
 			.join(",")}}`;
@@ -175,6 +194,7 @@ const stringifyObj = (
  * @param {Map<string, string | Set<string>>} valueCacheVersions valueCacheVersions
  * @param {string} key the defined key
  * @param {RuntimeTemplate} runtimeTemplate the runtime template
+ * @param {Logger} logger the logger object
  * @param {boolean|undefined|null=} asiSafe asi safe (undefined: unknown, null: unneeded)
  * @param {Set<string>|undefined=} objKeys used keys
  * @returns {string} code converted to string that evaluates
@@ -185,51 +205,62 @@ const toCode = (
 	valueCacheVersions,
 	key,
 	runtimeTemplate,
+	logger,
 	asiSafe,
 	objKeys
 ) => {
-	if (code === null) {
-		return "null";
-	}
-	if (code === undefined) {
-		return "undefined";
-	}
-	if (Object.is(code, -0)) {
-		return "-0";
-	}
-	if (code instanceof RuntimeValue) {
-		return toCode(
-			code.exec(parser, valueCacheVersions, key),
-			parser,
-			valueCacheVersions,
-			key,
-			runtimeTemplate,
-			asiSafe
-		);
-	}
-	if (code instanceof RegExp && code.toString) {
-		return code.toString();
-	}
-	if (typeof code === "function" && code.toString) {
-		return "(" + code.toString() + ")";
-	}
-	if (typeof code === "object") {
-		return stringifyObj(
-			code,
-			parser,
-			valueCacheVersions,
-			key,
-			runtimeTemplate,
-			asiSafe,
-			objKeys
-		);
-	}
-	if (typeof code === "bigint") {
-		return runtimeTemplate.supportsBigIntLiteral()
-			? `${code}n`
-			: `BigInt("${code}")`;
-	}
-	return code + "";
+	const transformToCode = () => {
+		if (code === null) {
+			return "null";
+		}
+		if (code === undefined) {
+			return "undefined";
+		}
+		if (Object.is(code, -0)) {
+			return "-0";
+		}
+		if (code instanceof RuntimeValue) {
+			return toCode(
+				code.exec(parser, valueCacheVersions, key),
+				parser,
+				valueCacheVersions,
+				key,
+				runtimeTemplate,
+				logger,
+				asiSafe
+			);
+		}
+		if (code instanceof RegExp && code.toString) {
+			return code.toString();
+		}
+		if (typeof code === "function" && code.toString) {
+			return "(" + code.toString() + ")";
+		}
+		if (typeof code === "object") {
+			return stringifyObj(
+				code,
+				parser,
+				valueCacheVersions,
+				key,
+				runtimeTemplate,
+				logger,
+				asiSafe,
+				objKeys
+			);
+		}
+		if (typeof code === "bigint") {
+			return runtimeTemplate.supportsBigIntLiteral()
+				? `${code}n`
+				: `BigInt("${code}")`;
+		}
+		return code + "";
+	};
+
+	const strCode = transformToCode();
+
+	logger.log(`Replaced "${key}" with "${strCode}"`);
+
+	return strCode;
 };
 
 const toCacheVersion = code => {
@@ -300,6 +331,7 @@ class DefinePlugin {
 		compiler.hooks.compilation.tap(
 			PLUGIN_NAME,
 			(compilation, { normalModuleFactory }) => {
+				const logger = compilation.getLogger("webpack.DefinePlugin");
 				compilation.dependencyTemplates.set(
 					ConstDependency,
 					new ConstDependency.Template()
@@ -421,6 +453,7 @@ class DefinePlugin {
 											compilation.valueCacheVersions,
 											key,
 											runtimeTemplate,
+											logger,
 											null
 										)
 									);
@@ -436,6 +469,7 @@ class DefinePlugin {
 									compilation.valueCacheVersions,
 									originalKey,
 									runtimeTemplate,
+									logger,
 									!parser.isAsiPosition(expr.range[0]),
 									parser.destructuringAssignmentPropertiesFor(expr)
 								);
@@ -470,6 +504,7 @@ class DefinePlugin {
 								compilation.valueCacheVersions,
 								originalKey,
 								runtimeTemplate,
+								logger,
 								null
 							);
 							const typeofCode = isTypeof
@@ -488,6 +523,7 @@ class DefinePlugin {
 								compilation.valueCacheVersions,
 								originalKey,
 								runtimeTemplate,
+								logger,
 								null
 							);
 							const typeofCode = isTypeof
@@ -534,6 +570,7 @@ class DefinePlugin {
 								compilation.valueCacheVersions,
 								key,
 								runtimeTemplate,
+								logger,
 								!parser.isAsiPosition(expr.range[0]),
 								parser.destructuringAssignmentPropertiesFor(expr)
 							);


Test patch:
diff --git a/test/__snapshots__/StatsTestCases.basictest.js.snap b/test/__snapshots__/StatsTestCases.basictest.js.snap
--- a/test/__snapshots__/StatsTestCases.basictest.js.snap
+++ b/test/__snapshots__/StatsTestCases.basictest.js.snap
@@ -860,6 +860,14 @@ webpack x.x.x compiled successfully in X ms
 
 asset both.js 1.4 KiB [emitted] (name: main)
 ./index.js 24 bytes [built] [code generated]
+webpack x.x.x compiled successfully in X ms
+
+asset 123.js 1.4 KiB [emitted] (name: main)
+./index.js 24 bytes [built] [code generated]
+
+DEBUG LOG from webpack.DefinePlugin
+    Replaced \\"VALUE\\" with \\"123\\"
+
 webpack x.x.x compiled successfully in X ms"
 `;
 
diff --git a/test/statsCases/define-plugin/webpack.config.js b/test/statsCases/define-plugin/webpack.config.js
--- a/test/statsCases/define-plugin/webpack.config.js
+++ b/test/statsCases/define-plugin/webpack.config.js
@@ -56,5 +56,26 @@ module.exports = [
 				)
 			})
 		]
+	},
+
+	{
+		mode: "production",
+		entry: "./index",
+		output: {
+			filename: "123.js"
+		},
+		infrastructureLogging: {
+			debug: /DefinePlugin/,
+			level: "none"
+		},
+		stats: {
+			loggingDebug: /DefinePlugin/,
+			logging: "none"
+		},
+		plugins: [
+			new webpack.DefinePlugin({
+				VALUE: "123"
+			})
+		]
 	}
 ];