Repository: webpack/webpack (JavaScript)

Issue:
Importing webpack-bundled ESM into a webpack app gets error due to shadowed variable
<!-- Please don't delete this template because we'll close your issue -->
<!-- Before creating an issue please make sure you are using the latest version of webpack. -->

# Bug report

<!-- Please ask questions on StackOverflow or the webpack Gitter. -->
<!-- https://stackoverflow.com/questions/ask?tags=webpack -->
<!-- https://gitter.im/webpack/webpack -->
<!-- Issues which contain questions or support requests will be closed. -->

**What is the current behavior?**

- Bundling a library into an ES Module with webpack outputs `var __webpack_exports__ = {};` at the top level.
- Trying to include this ES Module in an app also built with webpack, using the eval devtool (as is default with webpack-dev-server), it outputs `__webpack_require__.r(__webpack_exports__);` at the very start of the `eval`'d code. This code seems to be expecting to reference a variable from outside the `eval`, but instead `__webpack_exports__` is **shadowed**.
- At runtime, it gets an error due to `__webpack_exports__` being `undefined`:
    ```
    Uncaught TypeError: Object.defineProperty called on non-object
        at Function.defineProperty (<anonymous>)
        at __webpack_require__.r (app-bundle.js:82:21)
        at eval (library-bundle.esm.js:1:21)
        at ../library/dist/library-bundle.esm.js (app-bundle.js:29:1)
        at __webpack_require__ (app-bundle.js:53:41)
        at eval (app-source.js:2:93)
        at ./app-source.js (app-bundle.js:19:1)
        at __webpack_require__ (app-bundle.js:53:41)
        at app-bundle.js:93:37
        at app-bundle.js:95:12
    ```

**If the current behavior is a bug, please provide the steps to reproduce.**

[Here is a minimal reproduction](https://github.com/1j01/webpack-issue-16744), with instructions in the README.

<!-- A great way to do this is to provide your configuration via a GitHub repository -->
<!-- The most helpful is a minimal reproduction with instructions on how to reproduce -->
<!-- Repositories with too many files or large `webpack.config.js` files are not suitable -->
<!-- Please only add small code snippets directly into this issue -->
<!-- https://gist.github.com is a good place for longer code snippets -->
<!-- If your issue is caused by a plugin or loader, please create an issue on the loader/plugin repository instead -->

**What is the expected behavior?**

I don't know whether the library or app bundle output should change, or both,
but the app should be able to `import` or `require` the library without error.

<!-- "It should work" is not a helpful explanation -->
<!-- Explain exactly how it should behave -->

**Other relevant information:**
webpack version: 5.75.0  
Node.js version: v19.0.0  
Operating System: Ubuntu  
Additional tools: webpack-cli@5.0.1  



Hints:

Patch:
diff --git a/lib/CompatibilityPlugin.js b/lib/CompatibilityPlugin.js
--- a/lib/CompatibilityPlugin.js
+++ b/lib/CompatibilityPlugin.js
@@ -15,7 +15,7 @@ const ConstDependency = require("./dependencies/ConstDependency");
 /** @typedef {import("./Compiler")} Compiler */
 /** @typedef {import("./javascript/JavascriptParser")} JavascriptParser */
 
-const nestedWebpackRequireTag = Symbol("nested __webpack_require__");
+const nestedWebpackIdentifierTag = Symbol("nested webpack identifier");
 const PLUGIN_NAME = "CompatibilityPlugin";
 
 class CompatibilityPlugin {
@@ -82,14 +82,18 @@ class CompatibilityPlugin {
 							statement.id.name === "__webpack_require__"
 						) {
 							const newName = `__nested_webpack_require_${statement.range[0]}__`;
-							parser.tagVariable(statement.id.name, nestedWebpackRequireTag, {
-								name: newName,
-								declaration: {
-									updated: false,
-									loc: statement.id.loc,
-									range: statement.id.range
+							parser.tagVariable(
+								statement.id.name,
+								nestedWebpackIdentifierTag,
+								{
+									name: newName,
+									declaration: {
+										updated: false,
+										loc: statement.id.loc,
+										range: statement.id.range
+									}
 								}
-							});
+							);
 							return true;
 						}
 					});
@@ -97,7 +101,7 @@ class CompatibilityPlugin {
 						.for("__webpack_require__")
 						.tap(PLUGIN_NAME, pattern => {
 							const newName = `__nested_webpack_require_${pattern.range[0]}__`;
-							parser.tagVariable(pattern.name, nestedWebpackRequireTag, {
+							parser.tagVariable(pattern.name, nestedWebpackIdentifierTag, {
 								name: newName,
 								declaration: {
 									updated: false,
@@ -107,8 +111,21 @@ class CompatibilityPlugin {
 							});
 							return true;
 						});
+					parser.hooks.pattern
+						.for("__webpack_exports__")
+						.tap(PLUGIN_NAME, pattern => {
+							parser.tagVariable(pattern.name, nestedWebpackIdentifierTag, {
+								name: "__nested_webpack_exports__",
+								declaration: {
+									updated: false,
+									loc: pattern.loc,
+									range: pattern.range
+								}
+							});
+							return true;
+						});
 					parser.hooks.expression
-						.for(nestedWebpackRequireTag)
+						.for(nestedWebpackIdentifierTag)
 						.tap(PLUGIN_NAME, expr => {
 							const { name, declaration } = parser.currentTagData;
 							if (!declaration.updated) {


Test patch:
diff --git a/test/configCases/output-module/reuse-webpack-esm-library/index.js b/test/configCases/output-module/reuse-webpack-esm-library/index.js
new file mode 100644
--- /dev/null
+++ b/test/configCases/output-module/reuse-webpack-esm-library/index.js
@@ -0,0 +1,5 @@
+import { useCall } from "./lib";
+
+it("should compile and run", () => {
+	expect(useCall()).toBe(1);
+});
diff --git a/test/configCases/output-module/reuse-webpack-esm-library/lib.js b/test/configCases/output-module/reuse-webpack-esm-library/lib.js
new file mode 100644
--- /dev/null
+++ b/test/configCases/output-module/reuse-webpack-esm-library/lib.js
@@ -0,0 +1,95 @@
+import * as __WEBPACK_EXTERNAL_MODULE_react__ from "react";
+/******/ var __webpack_modules__ = ({
+
+	/***/ "react":
+	/*!************************!*\
+		!*** external "react" ***!
+		\************************/
+	/***/ ((module) => {
+
+		var x = y => { var x = {}; __webpack_require__.d(x, y); return x; }
+		var y = x => () => x
+		module.exports = __WEBPACK_EXTERNAL_MODULE_react__;
+
+		/***/ })
+
+	/******/ });
+/************************************************************************/
+/******/ // The module cache
+/******/ var __webpack_module_cache__ = {};
+/******/
+/******/ // The require function
+/******/ function __webpack_require__(moduleId) {
+	/******/ 	// Check if module is in cache
+	/******/ 	var cachedModule = __webpack_module_cache__[moduleId];
+	/******/ 	if (cachedModule !== undefined) {
+		/******/ 		return cachedModule.exports;
+		/******/ 	}
+	/******/ 	// Create a new module (and put it into the cache)
+	/******/ 	var module = __webpack_module_cache__[moduleId] = {
+		/******/ 		// no module.id needed
+		/******/ 		// no module.loaded needed
+		/******/ 		exports: {}
+		/******/ 	};
+	/******/
+	/******/ 	// Execute the module function
+	/******/ 	__webpack_modules__[moduleId](module, module.exports, __webpack_require__);
+	/******/
+	/******/ 	// Return the exports of the module
+	/******/ 	return module.exports;
+	/******/ }
+/******/
+/************************************************************************/
+/******/ /* webpack/runtime/define property getters */
+/******/ (() => {
+	/******/ 	// define getter functions for harmony exports
+	/******/ 	__webpack_require__.d = (exports, definition) => {
+		/******/ 		for(var key in definition) {
+			/******/ 			if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
+				/******/ 				Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
+				/******/ 			}
+			/******/ 		}
+		/******/ 	};
+	/******/ })();
+/******/
+/******/ /* webpack/runtime/hasOwnProperty shorthand */
+/******/ (() => {
+	/******/ 	__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
+	/******/ })();
+/******/
+/******/ /* webpack/runtime/make namespace object */
+/******/ (() => {
+	/******/ 	// define __esModule on exports
+	/******/ 	__webpack_require__.r = (exports) => {
+		/******/ 		if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
+			/******/ 			Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
+			/******/ 		}
+		/******/ 		Object.defineProperty(exports, '__esModule', { value: true });
+		/******/ 	};
+	/******/ })();
+/******/
+/************************************************************************/
+var __webpack_exports__ = {};
+// This entry need to be wrapped in an IIFE because it need to be isolated against other modules in the chunk.
+(() => {
+	/*!***************************!*\
+		!*** ./src/store/call.ts ***!
+		\***************************/
+	__webpack_require__.r(__webpack_exports__);
+	/* harmony export */ __webpack_require__.d(__webpack_exports__, {
+		/* harmony export */   "useCall": () => (/* binding */ useCall),
+		/* harmony export */   "withCallManager": () => (/* binding */ withCallManager)
+		/* harmony export */ });
+	/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react */ "react");
+
+	function withCallManager() {
+		return react__WEBPACK_IMPORTED_MODULE_0__.createElement(1);
+	}
+	function useCall() {
+		return withCallManager();
+	}
+})();
+
+var __webpack_exports__useCall = __webpack_exports__.useCall;
+var __webpack_exports__withCallManager = __webpack_exports__.withCallManager;
+export { __webpack_exports__useCall as useCall, __webpack_exports__withCallManager as withCallManager };
diff --git a/test/configCases/output-module/reuse-webpack-esm-library/react.js b/test/configCases/output-module/reuse-webpack-esm-library/react.js
new file mode 100644
--- /dev/null
+++ b/test/configCases/output-module/reuse-webpack-esm-library/react.js
@@ -0,0 +1 @@
+export function createElement(a) { return a; }
diff --git a/test/configCases/output-module/reuse-webpack-esm-library/webpack.config.js b/test/configCases/output-module/reuse-webpack-esm-library/webpack.config.js
new file mode 100644
--- /dev/null
+++ b/test/configCases/output-module/reuse-webpack-esm-library/webpack.config.js
@@ -0,0 +1,14 @@
+const path = require("path");
+/** @type {import("../../../../").Configuration} */
+module.exports = {
+	mode: "development",
+	devtool: "eval",
+	optimization: {
+		concatenateModules: false
+	},
+	resolve: {
+		alias: {
+			react: path.resolve(__dirname, "react")
+		}
+	}
+};