code:
/*
	MIT License http://www.opensource.org/licenses/mit-license.php
*/

"use strict";

const { Tracer } = require("chrome-trace-event");
const {
	JAVASCRIPT_MODULE_TYPE_AUTO,
	JAVASCRIPT_MODULE_TYPE_DYNAMIC,
	JAVASCRIPT_MODULE_TYPE_ESM,
	WEBASSEMBLY_MODULE_TYPE_ASYNC,
	WEBASSEMBLY_MODULE_TYPE_SYNC,
	JSON_MODULE_TYPE
} = require("../ModuleTypeConstants");
const createSchemaValidation = require("../util/create-schema-validation");
const { dirname, mkdirpSync } = require("../util/fs");

/** @typedef {import("../../declarations/plugins/debug/ProfilingPlugin").ProfilingPluginOptions} ProfilingPluginOptions */
/** @typedef {import("../Compilation")} Compilation */
/** @typedef {import("../Compiler")} Compiler */
/** @typedef {import("../ContextModuleFactory")} ContextModuleFactory */
/** @typedef {import("../ModuleFactory")} ModuleFactory */
/** @typedef {import("../NormalModuleFactory")} NormalModuleFactory */
/** @typedef {import("../util/fs").IntermediateFileSystem} IntermediateFileSystem */

/** @typedef {TODO} Inspector */

const validate = createSchemaValidation(
	require("../../schemas/plugins/debug/ProfilingPlugin.check.js"),
	() => require("../../schemas/plugins/debug/ProfilingPlugin.json"),
	{
		name: "Profiling Plugin",
		baseDataPath: "options"
	}
);

/** @type {Inspector | undefined} */
let inspector = undefined;

try {
	// eslint-disable-next-line n/no-unsupported-features/node-builtins
	inspector = require("inspector");
} catch (e) {
	console.log("Unable to CPU profile in < node 8.0");
}

class Profiler {
	/**
	 * @param {Inspector} inspector inspector
	 */
	constructor(inspector) {
		this.session = undefined;
		this.inspector = inspector;
		this._startTime = 0;
	}

	hasSession() {
		return this.session !== undefined;
	}

	startProfiling() {
		if (this.inspector === undefined) {
			return Promise.resolve();
		}

		try {
			this.session = new inspector.Session();
			this.session.connect();
		} catch (_) {
			this.session = undefined;
			return Promise.resolve();
		}

		const hrtime = process.hrtime();
		this._startTime = hrtime[0] * 1000000 + Math.round(hrtime[1] / 1000);

		return Promise.all([
			this.sendCommand("Profiler.setSamplingInterval", {
				interval: 100
			}),
			this.sendCommand("Profiler.enable"),
			this.sendCommand("Profiler.start")
		]);
	}

	/**
	 * @param {string} method method name
	 * @param {object} [params] params
	 * @returns {Promise<TODO>} Promise for the result
	 */
	sendCommand(method, params) {
		if (this.hasSession()) {
			return new Promise((res, rej) => {
				return this.session.post(method, params, (err, params) => {
					if (err !== null) {
						rej(err);
					} else {
						res(params);
					}
				});
			});
		} else {
			return Promise.resolve();
		}
	}

	destroy() {
		if (this.hasSession()) {
			this.session.disconnect();
		}

		return Promise.resolve();
	}

	stopProfiling() {
		return this.sendCommand("Profiler.stop").then(({ profile }) => {
			const hrtime = process.hrtime();
			const endTime = hrtime[0] * 1000000 + Math.round(hrtime[1] / 1000);
			// Avoid coverage problems due indirect changes
			/* istanbul ignore next */
			if (profile.startTime < this._startTime || profile.endTime > endTime) {
				// In some cases timestamps mismatch and we need to adjust them
				// Both process.hrtime and the inspector timestamps claim to be relative
				// to a unknown point in time. But they do not guarantee that this is the
				// same point in time.
				const duration = profile.endTime - profile.startTime;
				const ownDuration = endTime - this._startTime;
				const untracked = Math.max(0, ownDuration - duration);
				profile.startTime = this._startTime + untracked / 2;
				profile.endTime = endTime - untracked / 2;
			}
			return { profile };
		});
	}
}

/**
 * an object that wraps Tracer and Profiler with a counter
 * @typedef {object} Trace
 * @property {Tracer} trace instance of Tracer
 * @property {number} counter Counter
 * @property {Profiler} profiler instance of Profiler
 * @property {Function} end the end function
 */

/**
 * @param {IntermediateFileSystem} fs filesystem used for output
 * @param {string} outputPath The location where to write the log.
 * @returns {Trace} The trace object
 */
const createTrace = (fs, outputPath) => {
	const trace = new Tracer();
	const profiler = new Profiler(/** @type {Inspector} */ (inspector));
	if (/\/|\\/.test(outputPath)) {
		const dirPath = dirname(fs, outputPath);
		mkdirpSync(fs, dirPath);
	}
	const fsStream = fs.createWriteStream(outputPath);

	let counter = 0;

	trace.pipe(fsStream);
	// These are critical events that need to be inserted so that tools like
	// chrome dev tools can load the profile.
	trace.instantEvent({
		name: "TracingStartedInPage",
		id: ++counter,
		cat: ["disabled-by-default-devtools.timeline"],
		args: {
			data: {
				sessionId: "-1",
				page: "0xfff",
				frames: [
					{
						frame: "0xfff",
						url: "webpack",
						name: ""
					}
				]
			}
		}
	});

	trace.instantEvent({
		name: "TracingStartedInBrowser",
		id: ++counter,
		cat: ["disabled-by-default-devtools.timeline"],
		args: {
			data: {
				sessionId: "-1"
			}
		}
	});

	return {
		trace,
		counter,
		profiler,
		end: callback => {
			trace.push("]");
			// Wait until the write stream finishes.
			fsStream.on("close", () => {
				callback();
			});
			// Tear down the readable trace stream.
			trace.push(null);
		}
	};
};

const PLUGIN_NAME = "ProfilingPlugin";

class ProfilingPlugin {
	/**
	 * @param {ProfilingPluginOptions=} options options object
	 */
	constructor(options = {}) {
		validate(options);
		this.outputPath = options.outputPath || "events.json";
	}

	/**
	 * Apply the plugin
	 * @param {Compiler} compiler the compiler instance
	 * @returns {void}
	 */
	apply(compiler) {
		const tracer = createTrace(
			/** @type {IntermediateFileSystem} */
			(compiler.intermediateFileSystem),
			this.outputPath
		);
		tracer.profiler.startProfiling();

		// Compiler Hooks
		Object.keys(compiler.hooks).forEach(hookName => {
			const hook = compiler.hooks[hookName];
			if (hook) {
				hook.intercept(makeInterceptorFor("Compiler", tracer)(hookName));
			}
		});

		Object.keys(compiler.resolverFactory.hooks).forEach(hookName => {
			const hook = compiler.resolverFactory.hooks[hookName];
			if (hook) {
				hook.intercept(makeInterceptorFor("Resolver", tracer)(hookName));
			}
		});

		compiler.hooks.compilation.tap(
			PLUGIN_NAME,
			(compilation, { normalModuleFactory, contextModuleFactory }) => {
				interceptAllHooksFor(compilation, tracer, "Compilation");
				interceptAllHooksFor(
					normalModuleFactory,
					tracer,
					"Normal Module Factory"
				);
				interceptAllHooksFor(
					contextModuleFactory,
					tracer,
					"Context Module Factory"
				);
				interceptAllParserHooks(normalModuleFactory, tracer);
				interceptAllJavascriptModulesPluginHooks(compilation, tracer);
			}
		);

		// We need to write out the CPU profile when we are all done.
		compiler.hooks.done.tapAsync(
			{
				name: PLUGIN_NAME,
				stage: Infinity
			},
			(stats, callback) => {
				if (compiler.watchMode) return callback();
				tracer.profiler.stopProfiling().then(parsedResults => {
					if (parsedResults === undefined) {
						tracer.profiler.destroy();
						tracer.end(callback);
						return;
					}

					const cpuStartTime = parsedResults.profile.startTime;
					const cpuEndTime = parsedResults.profile.endTime;

					tracer.trace.completeEvent({
						name: "TaskQueueManager::ProcessTaskFromWorkQueue",
						id: ++tracer.counter,
						cat: ["toplevel"],
						ts: cpuStartTime,
						args: {
							src_file: "../../ipc/ipc_moji_bootstrap.cc",
							src_func: "Accept"
						}
					});

					tracer.trace.completeEvent({
						name: "EvaluateScript",
						id: ++tracer.counter,
						cat: ["devtools.timeline"],
						ts: cpuStartTime,
						dur: cpuEndTime - cpuStartTime,
						args: {
							data: {
								url: "webpack",
								lineNumber: 1,
								columnNumber: 1,
								frame: "0xFFF"
							}
						}
					});

					tracer.trace.instantEvent({
						name: "CpuProfile",
						id: ++tracer.counter,
						cat: ["disabled-by-default-devtools.timeline"],
						ts: cpuEndTime,
						args: {
							data: {
								cpuProfile: parsedResults.profile
							}
						}
					});

					tracer.profiler.destroy();
					tracer.end(callback);
				});
			}
		);
	}
}

/**
 * @param {any} instance instance
 * @param {Trace} tracer tracer
 * @param {string} logLabel log label
 */
const interceptAllHooksFor = (instance, tracer, logLabel) => {
	if (Reflect.has(instance, "hooks")) {
		Object.keys(instance.hooks).forEach(hookName => {
			const hook = instance.hooks[hookName];
			if (hook && !hook._fakeHook) {
				hook.intercept(makeInterceptorFor(logLabel, tracer)(hookName));
			}
		});
	}
};

/**
 * @param {NormalModuleFactory} moduleFactory normal module factory
 * @param {Trace} tracer tracer
 */
const interceptAllParserHooks = (moduleFactory, tracer) => {
	const moduleTypes = [
		JAVASCRIPT_MODULE_TYPE_AUTO,
		JAVASCRIPT_MODULE_TYPE_DYNAMIC,
		JAVASCRIPT_MODULE_TYPE_ESM,
		JSON_MODULE_TYPE,
		WEBASSEMBLY_MODULE_TYPE_ASYNC,
		WEBASSEMBLY_MODULE_TYPE_SYNC
	];

	moduleTypes.forEach(moduleType => {
		moduleFactory.hooks.parser
			.for(moduleType)
			.tap(PLUGIN_NAME, (parser, parserOpts) => {
				interceptAllHooksFor(parser, tracer, "Parser");
			});
	});
};

/**
 * @param {Compilation} compilation compilation
 * @param {Trace} tracer tracer
 */
const interceptAllJavascriptModulesPluginHooks = (compilation, tracer) => {
	interceptAllHooksFor(
		{
			hooks:
				require("../javascript/JavascriptModulesPlugin").getCompilationHooks(
					compilation
				)
		},
		tracer,
		"JavascriptModulesPlugin"
	);
};

const makeInterceptorFor = (instance, tracer) => hookName => ({
	register: tapInfo => {
		const { name, type, fn } = tapInfo;
		const newFn =
			// Don't tap our own hooks to ensure stream can close cleanly
			name === PLUGIN_NAME
				? fn
				: makeNewProfiledTapFn(hookName, tracer, {
						name,
						type,
						fn
					});
		return {
			...tapInfo,
			fn: newFn
		};
	}
});

// TODO improve typing
/** @typedef {(...args: TODO[]) => void | Promise<TODO>} PluginFunction */

/**
 * @param {string} hookName Name of the hook to profile.
 * @param {Trace} tracer The trace object.
 * @param {object} options Options for the profiled fn.
 * @param {string} options.name Plugin name
 * @param {string} options.type Plugin type (sync | async | promise)
 * @param {PluginFunction} options.fn Plugin function
 * @returns {PluginFunction} Chainable hooked function.
 */
const makeNewProfiledTapFn = (hookName, tracer, { name, type, fn }) => {
	const defaultCategory = ["blink.user_timing"];

	switch (type) {
		case "promise":
			return (...args) => {
				const id = ++tracer.counter;
				tracer.trace.begin({
					name,
					id,
					cat: defaultCategory
				});
				const promise = /** @type {Promise<*>} */ (fn(...args));
				return promise.then(r => {
					tracer.trace.end({
						name,
						id,
						cat: defaultCategory
					});
					return r;
				});
			};
		case "async":
			return (...args) => {
				const id = ++tracer.counter;
				tracer.trace.begin({
					name,
					id,
					cat: defaultCategory
				});
				const callback = args.pop();
				fn(...args, (...r) => {
					tracer.trace.end({
						name,
						id,
						cat: defaultCategory
					});
					callback(...r);
				});
			};
		case "sync":
			return (...args) => {
				const id = ++tracer.counter;
				// Do not instrument ourself due to the CPU
				// profile needing to be the last event in the trace.
				if (name === PLUGIN_NAME) {
					return fn(...args);
				}

				tracer.trace.begin({
					name,
					id,
					cat: defaultCategory
				});
				let r;
				try {
					r = fn(...args);
				} catch (error) {
					tracer.trace.end({
						name,
						id,
						cat: defaultCategory
					});
					throw error;
				}
				tracer.trace.end({
					name,
					id,
					cat: defaultCategory
				});
				return r;
			};
		default:
			break;
	}
};

module.exports = ProfilingPlugin;
module.exports.Profiler = Profiler;


code:
/*
	MIT License http://www.opensource.org/licenses/mit-license.php
	Author Tobias Koppers @sokra
*/

"use strict";

const RuntimeGlobals = require("../RuntimeGlobals");
const makeSerializable = require("../util/makeSerializable");
const NullDependency = require("./NullDependency");

/** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */
/** @typedef {import("../Dependency")} Dependency */
/** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */
/** @typedef {import("../javascript/JavascriptParser").Range} Range */
/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */

/** @type {Record<string, { definition: string, content: string, requests: string[] }>} */
const DEFINITIONS = {
	f: {
		definition: "var __WEBPACK_AMD_DEFINE_RESULT__;",
		content: `!(__WEBPACK_AMD_DEFINE_RESULT__ = (#).call(exports, ${RuntimeGlobals.require}, exports, module),
		__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__))`,
		requests: [
			RuntimeGlobals.require,
			RuntimeGlobals.exports,
			RuntimeGlobals.module
		]
	},
	o: {
		definition: "",
		content: "!(module.exports = #)",
		requests: [RuntimeGlobals.module]
	},
	of: {
		definition:
			"var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_RESULT__;",
		content: `!(__WEBPACK_AMD_DEFINE_FACTORY__ = (#),
		__WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ?
		(__WEBPACK_AMD_DEFINE_FACTORY__.call(exports, ${RuntimeGlobals.require}, exports, module)) :
		__WEBPACK_AMD_DEFINE_FACTORY__),
		__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__))`,
		requests: [
			RuntimeGlobals.require,
			RuntimeGlobals.exports,
			RuntimeGlobals.module
		]
	},
	af: {
		definition:
			"var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;",
		content: `!(__WEBPACK_AMD_DEFINE_ARRAY__ = #, __WEBPACK_AMD_DEFINE_RESULT__ = (#).apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__),
		__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__))`,
		requests: [RuntimeGlobals.exports, RuntimeGlobals.module]
	},
	ao: {
		definition: "",
		content: "!(#, module.exports = #)",
		requests: [RuntimeGlobals.module]
	},
	aof: {
		definition:
			"var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;",
		content: `!(__WEBPACK_AMD_DEFINE_ARRAY__ = #, __WEBPACK_AMD_DEFINE_FACTORY__ = (#),
		__WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ?
		(__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__),
		__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__))`,
		requests: [RuntimeGlobals.exports, RuntimeGlobals.module]
	},
	lf: {
		definition: "var XXX, XXXmodule;",
		content: `!(XXXmodule = { id: YYY, exports: {}, loaded: false }, XXX = (#).call(XXXmodule.exports, ${RuntimeGlobals.require}, XXXmodule.exports, XXXmodule), XXXmodule.loaded = true, XXX === undefined && (XXX = XXXmodule.exports))`,
		requests: [RuntimeGlobals.require, RuntimeGlobals.module]
	},
	lo: {
		definition: "var XXX;",
		content: "!(XXX = #)",
		requests: []
	},
	lof: {
		definition: "var XXX, XXXfactory, XXXmodule;",
		content: `!(XXXfactory = (#), (typeof XXXfactory === 'function' ? ((XXXmodule = { id: YYY, exports: {}, loaded: false }), (XXX = XXXfactory.call(XXXmodule.exports, ${RuntimeGlobals.require}, XXXmodule.exports, XXXmodule)), (XXXmodule.loaded = true), XXX === undefined && (XXX = XXXmodule.exports)) : XXX = XXXfactory))`,
		requests: [RuntimeGlobals.require, RuntimeGlobals.module]
	},
	laf: {
		definition: "var __WEBPACK_AMD_DEFINE_ARRAY__, XXX, XXXexports;",
		content:
			"!(__WEBPACK_AMD_DEFINE_ARRAY__ = #, XXX = (#).apply(XXXexports = {}, __WEBPACK_AMD_DEFINE_ARRAY__), XXX === undefined && (XXX = XXXexports))",
		requests: []
	},
	lao: {
		definition: "var XXX;",
		content: "!(#, XXX = #)",
		requests: []
	},
	laof: {
		definition: "var XXXarray, XXXfactory, XXXexports, XXX;",
		content: `!(XXXarray = #, XXXfactory = (#),
		(typeof XXXfactory === 'function' ?
			((XXX = XXXfactory.apply(XXXexports = {}, XXXarray)), XXX === undefined && (XXX = XXXexports)) :
			(XXX = XXXfactory)
		))`,
		requests: []
	}
};

class AMDDefineDependency extends NullDependency {
	/**
	 * @param {Range} range range
	 * @param {Range | null} arrayRange array range
	 * @param {Range | null} functionRange function range
	 * @param {Range | null} objectRange object range
	 * @param {boolean | null} namedModule true, when define is called with a name
	 */
	constructor(range, arrayRange, functionRange, objectRange, namedModule) {
		super();
		this.range = range;
		this.arrayRange = arrayRange;
		this.functionRange = functionRange;
		this.objectRange = objectRange;
		this.namedModule = namedModule;
		this.localModule = null;
	}

	get type() {
		return "amd define";
	}

	/**
	 * @param {ObjectSerializerContext} context context
	 */
	serialize(context) {
		const { write } = context;
		write(this.range);
		write(this.arrayRange);
		write(this.functionRange);
		write(this.objectRange);
		write(this.namedModule);
		write(this.localModule);
		super.serialize(context);
	}

	/**
	 * @param {ObjectDeserializerContext} context context
	 */
	deserialize(context) {
		const { read } = context;
		this.range = read();
		this.arrayRange = read();
		this.functionRange = read();
		this.objectRange = read();
		this.namedModule = read();
		this.localModule = read();
		super.deserialize(context);
	}
}

makeSerializable(
	AMDDefineDependency,
	"webpack/lib/dependencies/AMDDefineDependency"
);

AMDDefineDependency.Template = class AMDDefineDependencyTemplate extends (
	NullDependency.Template
) {
	/**
	 * @param {Dependency} dependency the dependency for which the template should be applied
	 * @param {ReplaceSource} source the current replace source which can be modified
	 * @param {DependencyTemplateContext} templateContext the context object
	 * @returns {void}
	 */
	apply(dependency, source, { runtimeRequirements }) {
		const dep = /** @type {AMDDefineDependency} */ (dependency);
		const branch = this.branch(dep);
		const { definition, content, requests } = DEFINITIONS[branch];
		for (const req of requests) {
			runtimeRequirements.add(req);
		}
		this.replace(dep, source, definition, content);
	}

	/**
	 * @param {AMDDefineDependency} dependency dependency
	 * @returns {string} variable name
	 */
	localModuleVar(dependency) {
		return (
			dependency.localModule &&
			dependency.localModule.used &&
			dependency.localModule.variableName()
		);
	}

	/**
	 * @param {AMDDefineDependency} dependency dependency
	 * @returns {string} branch
	 */
	branch(dependency) {
		const localModuleVar = this.localModuleVar(dependency) ? "l" : "";
		const arrayRange = dependency.arrayRange ? "a" : "";
		const objectRange = dependency.objectRange ? "o" : "";
		const functionRange = dependency.functionRange ? "f" : "";
		return localModuleVar + arrayRange + objectRange + functionRange;
	}

	/**
	 * @param {AMDDefineDependency} dependency dependency
	 * @param {ReplaceSource} source source
	 * @param {string} definition definition
	 * @param {string} text text
	 */
	replace(dependency, source, definition, text) {
		const localModuleVar = this.localModuleVar(dependency);
		if (localModuleVar) {
			text = text.replace(/XXX/g, localModuleVar.replace(/\$/g, "$$$$"));
			definition = definition.replace(
				/XXX/g,
				localModuleVar.replace(/\$/g, "$$$$")
			);
		}

		if (dependency.namedModule) {
			text = text.replace(/YYY/g, JSON.stringify(dependency.namedModule));
		}

		const texts = text.split("#");

		if (definition) source.insert(0, definition);

		let current = dependency.range[0];
		if (dependency.arrayRange) {
			source.replace(
				current,
				dependency.arrayRange[0] - 1,
				/** @type {string} */ (texts.shift())
			);
			current = dependency.arrayRange[1];
		}

		if (dependency.objectRange) {
			source.replace(
				current,
				dependency.objectRange[0] - 1,
				/** @type {string} */ (texts.shift())
			);
			current = dependency.objectRange[1];
		} else if (dependency.functionRange) {
			source.replace(
				current,
				dependency.functionRange[0] - 1,
				/** @type {string} */ (texts.shift())
			);
			current = dependency.functionRange[1];
		}
		source.replace(
			current,
			dependency.range[1] - 1,
			/** @type {string} */ (texts.shift())
		);
		if (texts.length > 0) throw new Error("Implementation error");
	}
};

module.exports = AMDDefineDependency;

license: mit


code:
/*
	MIT License http://www.opensource.org/licenses/mit-license.php
	Author Tobias Koppers @sokra
*/

"use strict";

const RuntimeGlobals = require("../RuntimeGlobals");
const AMDDefineDependency = require("./AMDDefineDependency");
const AMDRequireArrayDependency = require("./AMDRequireArrayDependency");
const AMDRequireContextDependency = require("./AMDRequireContextDependency");
const AMDRequireItemDependency = require("./AMDRequireItemDependency");
const ConstDependency = require("./ConstDependency");
const ContextDependencyHelpers = require("./ContextDependencyHelpers");
const DynamicExports = require("./DynamicExports");
const LocalModuleDependency = require("./LocalModuleDependency");
const { addLocalModule, getLocalModule } = require("./LocalModulesHelpers");

/** @typedef {import("estree").ArrowFunctionExpression} ArrowFunctionExpression */
/** @typedef {import("estree").CallExpression} CallExpression */
/** @typedef {import("estree").Expression} Expression */
/** @typedef {import("estree").FunctionExpression} FunctionExpression */
/** @typedef {import("estree").Literal} Literal */
/** @typedef {import("estree").SpreadElement} SpreadElement */
/** @typedef {import("../../declarations/WebpackOptions").JavascriptParserOptions} JavascriptParserOptions */
/** @typedef {import("../Dependency").DependencyLocation} DependencyLocation */
/** @typedef {import("../javascript/BasicEvaluatedExpression")} BasicEvaluatedExpression */
/** @typedef {import("../javascript/JavascriptParser")} JavascriptParser */
/** @typedef {import("../javascript/JavascriptParser").Range} Range */

/**
 * @param {Expression | SpreadElement} expr expression
 * @returns {boolean} true if it's a bound function expression
 */
const isBoundFunctionExpression = expr => {
	if (expr.type !== "CallExpression") return false;
	if (expr.callee.type !== "MemberExpression") return false;
	if (expr.callee.computed) return false;
	if (expr.callee.object.type !== "FunctionExpression") return false;
	if (expr.callee.property.type !== "Identifier") return false;
	if (expr.callee.property.name !== "bind") return false;
	return true;
};

/** @typedef {FunctionExpression | ArrowFunctionExpression} UnboundFunctionExpression */

/**
 * @param {Expression | SpreadElement} expr expression
 * @returns {boolean} true when unbound function expression
 */
const isUnboundFunctionExpression = expr => {
	if (expr.type === "FunctionExpression") return true;
	if (expr.type === "ArrowFunctionExpression") return true;
	return false;
};

/**
 * @param {Expression | SpreadElement} expr expression
 * @returns {boolean} true when callable
 */
const isCallable = expr => {
	if (isUnboundFunctionExpression(expr)) return true;
	if (isBoundFunctionExpression(expr)) return true;
	return false;
};

class AMDDefineDependencyParserPlugin {
	/**
	 * @param {JavascriptParserOptions} options parserOptions
	 */
	constructor(options) {
		this.options = options;
	}

	/**
	 * @param {JavascriptParser} parser the parser
	 * @returns {void}
	 */
	apply(parser) {
		parser.hooks.call
			.for("define")
			.tap(
				"AMDDefineDependencyParserPlugin",
				this.processCallDefine.bind(this, parser)
			);
	}

	/**
	 * @param {JavascriptParser} parser the parser
	 * @param {CallExpression} expr call expression
	 * @param {BasicEvaluatedExpression} param param
	 * @param {Record<number, string>} identifiers identifiers
	 * @param {string=} namedModule named module
	 * @returns {boolean | undefined} result
	 */
	processArray(parser, expr, param, identifiers, namedModule) {
		if (param.isArray()) {
			/** @type {BasicEvaluatedExpression[]} */
			(param.items).forEach((param, idx) => {
				if (
					param.isString() &&
					["require", "module", "exports"].includes(
						/** @type {string} */ (param.string)
					)
				)
					identifiers[/** @type {number} */ (idx)] = param.string;
				const result = this.processItem(parser, expr, param, namedModule);
				if (result === undefined) {
					this.processContext(parser, expr, param);
				}
			});
			return true;
		} else if (param.isConstArray()) {
			/** @type {(string | LocalModuleDependency | AMDRequireItemDependency)[]} */
			const deps = [];
			/** @type {string[]} */
			(param.array).forEach((request, idx) => {
				let dep;
				let localModule;
				if (request === "require") {
					identifiers[idx] = request;
					dep = RuntimeGlobals.require;
				} else if (["exports", "module"].includes(request)) {
					identifiers[idx] = request;
					dep = request;
				} else if ((localModule = getLocalModule(parser.state, request))) {
					localModule.flagUsed();
					dep = new LocalModuleDependency(localModule, undefined, false);
					dep.loc = /** @type {DependencyLocation} */ (expr.loc);
					parser.state.module.addPresentationalDependency(dep);
				} else {
					dep = this.newRequireItemDependency(request);
					dep.loc = /** @type {DependencyLocation} */ (expr.loc);
					dep.optional = !!parser.scope.inTry;
					parser.state.current.addDependency(dep);
				}
				deps.push(dep);
			});
			const dep = this.newRequireArrayDependency(
				deps,
				/** @type {Range} */ (param.range)
			);
			dep.loc = /** @type {DependencyLocation} */ (expr.loc);
			dep.optional = !!parser.scope.inTry;
			parser.state.module.addPresentationalDependency(dep);
			return true;
		}
	}

	/**
	 * @param {JavascriptParser} parser the parser
	 * @param {CallExpression} expr call expression
	 * @param {BasicEvaluatedExpression} param param
	 * @param {string=} namedModule named module
	 * @returns {boolean | undefined} result
	 */
	processItem(parser, expr, param, namedModule) {
		if (param.isConditional()) {
			/** @type {BasicEvaluatedExpression[]} */
			(param.options).forEach(param => {
				const result = this.processItem(parser, expr, param);
				if (result === undefined) {
					this.processContext(parser, expr, param);
				}
			});
			return true;
		} else if (param.isString()) {
			let dep, localModule;
			if (param.string === "require") {
				dep = new ConstDependency(
					RuntimeGlobals.require,
					/** @type {Range} */ (param.range),
					[RuntimeGlobals.require]
				);
			} else if (param.string === "exports") {
				dep = new ConstDependency(
					"exports",
					/** @type {Range} */ (param.range),
					[RuntimeGlobals.exports]
				);
			} else if (param.string === "module") {
				dep = new ConstDependency(
					"module",
					/** @type {Range} */ (param.range),
					[RuntimeGlobals.module]
				);
			} else if (
				(localModule = getLocalModule(
					parser.state,
					/** @type {string} */ (param.string),
					namedModule
				))
			) {
				localModule.flagUsed();
				dep = new LocalModuleDependency(localModule, param.range, false);
			} else {
				dep = this.newRequireItemDependency(
					/** @type {string} */ (param.string),
					param.range
				);
				dep.optional = !!parser.scope.inTry;
				parser.state.current.addDependency(dep);
				return true;
			}
			dep.loc = /** @type {DependencyLocation} */ (expr.loc);
			parser.state.module.addPresentationalDependency(dep);
			return true;
		}
	}

	/**
	 * @param {JavascriptParser} parser the parser
	 * @param {CallExpression} expr call expression
	 * @param {BasicEvaluatedExpression} param param
	 * @returns {boolean | undefined} result
	 */
	processContext(parser, expr, param) {
		const dep = ContextDependencyHelpers.create(
			AMDRequireContextDependency,
			/** @type {Range} */ (param.range),
			param,
			expr,
			this.options,
			{
				category: "amd"
			},
			parser
		);
		if (!dep) return;
		dep.loc = /** @type {DependencyLocation} */ (expr.loc);
		dep.optional = !!parser.scope.inTry;
		parser.state.current.addDependency(dep);
		return true;
	}

	/**
	 * @param {JavascriptParser} parser the parser
	 * @param {CallExpression} expr call expression
	 * @returns {boolean | undefined} result
	 */
	processCallDefine(parser, expr) {
		let array, fn, obj, namedModule;
		switch (expr.arguments.length) {
			case 1:
				if (isCallable(expr.arguments[0])) {
					// define(f() {…})
					fn = expr.arguments[0];
				} else if (expr.arguments[0].type === "ObjectExpression") {
					// define({…})
					obj = expr.arguments[0];
				} else {
					// define(expr)
					// unclear if function or object
					obj = fn = expr.arguments[0];
				}
				break;
			case 2:
				if (expr.arguments[0].type === "Literal") {
					namedModule = expr.arguments[0].value;
					// define("…", …)
					if (isCallable(expr.arguments[1])) {
						// define("…", f() {…})
						fn = expr.arguments[1];
					} else if (expr.arguments[1].type === "ObjectExpression") {
						// define("…", {…})
						obj = expr.arguments[1];
					} else {
						// define("…", expr)
						// unclear if function or object
						obj = fn = expr.arguments[1];
					}
				} else {
					array = expr.arguments[0];
					if (isCallable(expr.arguments[1])) {
						// define([…], f() {})
						fn = expr.arguments[1];
					} else if (expr.arguments[1].type === "ObjectExpression") {
						// define([…], {…})
						obj = expr.arguments[1];
					} else {
						// define([…], expr)
						// unclear if function or object
						obj = fn = expr.arguments[1];
					}
				}
				break;
			case 3:
				// define("…", […], f() {…})
				namedModule = /** @type {TODO} */ (expr).arguments[0].value;
				array = expr.arguments[1];
				if (isCallable(expr.arguments[2])) {
					// define("…", […], f() {})
					fn = expr.arguments[2];
				} else if (expr.arguments[2].type === "ObjectExpression") {
					// define("…", […], {…})
					obj = expr.arguments[2];
				} else {
					// define("…", […], expr)
					// unclear if function or object
					obj = fn = expr.arguments[2];
				}
				break;
			default:
				return;
		}
		DynamicExports.bailout(parser.state);
		let fnParams = null;
		let fnParamsOffset = 0;
		if (fn) {
			if (isUnboundFunctionExpression(fn)) {
				fnParams = /** @type {UnboundFunctionExpression} */ (fn).params;
			} else if (isBoundFunctionExpression(fn)) {
				fnParams = /** @type {TODO} */ (fn).callee.object.params;
				fnParamsOffset = /** @type {TODO} */ (fn).arguments.length - 1;
				if (fnParamsOffset < 0) {
					fnParamsOffset = 0;
				}
			}
		}
		let fnRenames = new Map();
		if (array) {
			/** @type {Record<number, string>} */
			const identifiers = {};
			const param = parser.evaluateExpression(array);
			const result = this.processArray(
				parser,
				expr,
				param,
				identifiers,
				namedModule
			);
			if (!result) return;
			if (fnParams) {
				fnParams = fnParams.slice(fnParamsOffset).filter((param, idx) => {
					if (identifiers[idx]) {
						fnRenames.set(param.name, parser.getVariableInfo(identifiers[idx]));
						return false;
					}
					return true;
				});
			}
		} else {
			const identifiers = ["require", "exports", "module"];
			if (fnParams) {
				fnParams = fnParams.slice(fnParamsOffset).filter((param, idx) => {
					if (identifiers[idx]) {
						fnRenames.set(param.name, parser.getVariableInfo(identifiers[idx]));
						return false;
					}
					return true;
				});
			}
		}
		/** @type {boolean | undefined} */
		let inTry;
		if (fn && isUnboundFunctionExpression(fn)) {
			inTry = parser.scope.inTry;
			parser.inScope(fnParams, () => {
				for (const [name, varInfo] of fnRenames) {
					parser.setVariable(name, varInfo);
				}
				parser.scope.inTry = /** @type {boolean} */ (inTry);
				if (fn.body.type === "BlockStatement") {
					parser.detectMode(fn.body.body);
					const prev = parser.prevStatement;
					parser.preWalkStatement(fn.body);
					parser.prevStatement = prev;
					parser.walkStatement(fn.body);
				} else {
					parser.walkExpression(fn.body);
				}
			});
		} else if (fn && isBoundFunctionExpression(fn)) {
			inTry = parser.scope.inTry;
			parser.inScope(
				/** @type {TODO} */
				(fn).callee.object.params.filter(
					i => !["require", "module", "exports"].includes(i.name)
				),
				() => {
					for (const [name, varInfo] of fnRenames) {
						parser.setVariable(name, varInfo);
					}
					parser.scope.inTry = /** @type {boolean} */ (inTry);
					if (fn.callee.object.body.type === "BlockStatement") {
						parser.detectMode(fn.callee.object.body.body);
						const prev = parser.prevStatement;
						parser.preWalkStatement(fn.callee.object.body);
						parser.prevStatement = prev;
						parser.walkStatement(fn.callee.object.body);
					} else {
						parser.walkExpression(fn.callee.object.body);
					}
				}
			);
			if (/** @type {TODO} */ (fn).arguments) {
				parser.walkExpressions(/** @type {TODO} */ (fn).arguments);
			}
		} else if (fn || obj) {
			parser.walkExpression(fn || obj);
		}

		const dep = this.newDefineDependency(
			/** @type {Range} */ (expr.range),
			array ? /** @type {Range} */ (array.range) : null,
			fn ? /** @type {Range} */ (fn.range) : null,
			obj ? /** @type {Range} */ (obj.range) : null,
			namedModule ? namedModule : null
		);
		dep.loc = /** @type {DependencyLocation} */ (expr.loc);
		if (namedModule) {
			dep.localModule = addLocalModule(parser.state, namedModule);
		}
		parser.state.module.addPresentationalDependency(dep);
		return true;
	}

	/**
	 * @param {Range} range range
	 * @param {Range | null} arrayRange array range
	 * @param {Range | null} functionRange function range
	 * @param {Range | null} objectRange object range
	 * @param {boolean | null} namedModule true, when define is called with a name
	 * @returns {AMDDefineDependency} AMDDefineDependency
	 */
	newDefineDependency(
		range,
		arrayRange,
		functionRange,
		objectRange,
		namedModule
	) {
		return new AMDDefineDependency(
			range,
			arrayRange,
			functionRange,
			objectRange,
			namedModule
		);
	}

	/**
	 * @param {TODO[]} depsArray deps array
	 * @param {Range} range range
	 * @returns {AMDRequireArrayDependency} AMDRequireArrayDependency
	 */
	newRequireArrayDependency(depsArray, range) {
		return new AMDRequireArrayDependency(depsArray, range);
	}

	/**
	 * @param {string} request request
	 * @param {Range=} range range
	 * @returns {AMDRequireItemDependency} AMDRequireItemDependency
	 */
	newRequireItemDependency(request, range) {
		return new AMDRequireItemDependency(request, range);
	}
}

module.exports = AMDDefineDependencyParserPlugin;


code:
/*
	MIT License http://www.opensource.org/licenses/mit-license.php
	Author Tobias Koppers @sokra
*/

"use strict";

const {
	JAVASCRIPT_MODULE_TYPE_AUTO,
	JAVASCRIPT_MODULE_TYPE_DYNAMIC
} = require("../ModuleTypeConstants");
const RuntimeGlobals = require("../RuntimeGlobals");
const {
	approve,
	evaluateToIdentifier,
	evaluateToString,
	toConstantDependency
} = require("../javascript/JavascriptParserHelpers");

const AMDDefineDependency = require("./AMDDefineDependency");
const AMDDefineDependencyParserPlugin = require("./AMDDefineDependencyParserPlugin");
const AMDRequireArrayDependency = require("./AMDRequireArrayDependency");
const AMDRequireContextDependency = require("./AMDRequireContextDependency");
const AMDRequireDependenciesBlockParserPlugin = require("./AMDRequireDependenciesBlockParserPlugin");
const AMDRequireDependency = require("./AMDRequireDependency");
const AMDRequireItemDependency = require("./AMDRequireItemDependency");
const {
	AMDDefineRuntimeModule,
	AMDOptionsRuntimeModule
} = require("./AMDRuntimeModules");
const ConstDependency = require("./ConstDependency");
const LocalModuleDependency = require("./LocalModuleDependency");
const UnsupportedDependency = require("./UnsupportedDependency");

/** @typedef {import("../../declarations/WebpackOptions").JavascriptParserOptions} JavascriptParserOptions */
/** @typedef {import("../../declarations/WebpackOptions").ModuleOptionsNormalized} ModuleOptions */
/** @typedef {import("../Compiler")} Compiler */
/** @typedef {import("../Dependency").DependencyLocation} DependencyLocation */
/** @typedef {import("../javascript/JavascriptParser")} Parser */
/** @typedef {import("../javascript/JavascriptParser").Range} Range */

const PLUGIN_NAME = "AMDPlugin";

class AMDPlugin {
	/**
	 * @param {Record<string, any>} amdOptions the AMD options
	 */
	constructor(amdOptions) {
		this.amdOptions = amdOptions;
	}

	/**
	 * Apply the plugin
	 * @param {Compiler} compiler the compiler instance
	 * @returns {void}
	 */
	apply(compiler) {
		const amdOptions = this.amdOptions;
		compiler.hooks.compilation.tap(
			PLUGIN_NAME,
			(compilation, { contextModuleFactory, normalModuleFactory }) => {
				compilation.dependencyTemplates.set(
					AMDRequireDependency,
					new AMDRequireDependency.Template()
				);

				compilation.dependencyFactories.set(
					AMDRequireItemDependency,
					normalModuleFactory
				);
				compilation.dependencyTemplates.set(
					AMDRequireItemDependency,
					new AMDRequireItemDependency.Template()
				);

				compilation.dependencyTemplates.set(
					AMDRequireArrayDependency,
					new AMDRequireArrayDependency.Template()
				);

				compilation.dependencyFactories.set(
					AMDRequireContextDependency,
					contextModuleFactory
				);
				compilation.dependencyTemplates.set(
					AMDRequireContextDependency,
					new AMDRequireContextDependency.Template()
				);

				compilation.dependencyTemplates.set(
					AMDDefineDependency,
					new AMDDefineDependency.Template()
				);

				compilation.dependencyTemplates.set(
					UnsupportedDependency,
					new UnsupportedDependency.Template()
				);

				compilation.dependencyTemplates.set(
					LocalModuleDependency,
					new LocalModuleDependency.Template()
				);

				compilation.hooks.runtimeRequirementInModule
					.for(RuntimeGlobals.amdDefine)
					.tap(PLUGIN_NAME, (module, set) => {
						set.add(RuntimeGlobals.require);
					});

				compilation.hooks.runtimeRequirementInModule
					.for(RuntimeGlobals.amdOptions)
					.tap(PLUGIN_NAME, (module, set) => {
						set.add(RuntimeGlobals.requireScope);
					});

				compilation.hooks.runtimeRequirementInTree
					.for(RuntimeGlobals.amdDefine)
					.tap(PLUGIN_NAME, (chunk, set) => {
						compilation.addRuntimeModule(chunk, new AMDDefineRuntimeModule());
					});

				compilation.hooks.runtimeRequirementInTree
					.for(RuntimeGlobals.amdOptions)
					.tap(PLUGIN_NAME, (chunk, set) => {
						compilation.addRuntimeModule(
							chunk,
							new AMDOptionsRuntimeModule(amdOptions)
						);
					});

				/**
				 * @param {Parser} parser parser parser
				 * @param {JavascriptParserOptions} parserOptions parserOptions
				 * @returns {void}
				 */
				const handler = (parser, parserOptions) => {
					if (parserOptions.amd !== undefined && !parserOptions.amd) return;

					/**
					 * @param {string} optionExpr option expression
					 * @param {string} rootName root name
					 * @param {function(): TODO} getMembers callback
					 */
					const tapOptionsHooks = (optionExpr, rootName, getMembers) => {
						parser.hooks.expression
							.for(optionExpr)
							.tap(
								PLUGIN_NAME,
								toConstantDependency(parser, RuntimeGlobals.amdOptions, [
									RuntimeGlobals.amdOptions
								])
							);
						parser.hooks.evaluateIdentifier
							.for(optionExpr)
							.tap(
								PLUGIN_NAME,
								evaluateToIdentifier(optionExpr, rootName, getMembers, true)
							);
						parser.hooks.evaluateTypeof
							.for(optionExpr)
							.tap(PLUGIN_NAME, evaluateToString("object"));
						parser.hooks.typeof
							.for(optionExpr)
							.tap(
								PLUGIN_NAME,
								toConstantDependency(parser, JSON.stringify("object"))
							);
					};

					new AMDRequireDependenciesBlockParserPlugin(parserOptions).apply(
						parser
					);
					new AMDDefineDependencyParserPlugin(parserOptions).apply(parser);

					tapOptionsHooks("define.amd", "define", () => "amd");
					tapOptionsHooks("require.amd", "require", () => ["amd"]);
					tapOptionsHooks(
						"__webpack_amd_options__",
						"__webpack_amd_options__",
						() => []
					);

					parser.hooks.expression.for("define").tap(PLUGIN_NAME, expr => {
						const dep = new ConstDependency(
							RuntimeGlobals.amdDefine,
							/** @type {Range} */ (expr.range),
							[RuntimeGlobals.amdDefine]
						);
						dep.loc = /** @type {DependencyLocation} */ (expr.loc);
						parser.state.module.addPresentationalDependency(dep);
						return true;
					});
					parser.hooks.typeof
						.for("define")
						.tap(
							PLUGIN_NAME,
							toConstantDependency(parser, JSON.stringify("function"))
						);
					parser.hooks.evaluateTypeof
						.for("define")
						.tap(PLUGIN_NAME, evaluateToString("function"));
					parser.hooks.canRename.for("define").tap(PLUGIN_NAME, approve);
					parser.hooks.rename.for("define").tap(PLUGIN_NAME, expr => {
						const dep = new ConstDependency(
							RuntimeGlobals.amdDefine,
							/** @type {Range} */ (expr.range),
							[RuntimeGlobals.amdDefine]
						);
						dep.loc = /** @type {DependencyLocation} */ (expr.loc);
						parser.state.module.addPresentationalDependency(dep);
						return false;
					});
					parser.hooks.typeof
						.for("require")
						.tap(
							PLUGIN_NAME,
							toConstantDependency(parser, JSON.stringify("function"))
						);
					parser.hooks.evaluateTypeof
						.for("require")
						.tap(PLUGIN_NAME, evaluateToString("function"));
				};

				normalModuleFactory.hooks.parser
					.for(JAVASCRIPT_MODULE_TYPE_AUTO)
					.tap(PLUGIN_NAME, handler);
				normalModuleFactory.hooks.parser
					.for(JAVASCRIPT_MODULE_TYPE_DYNAMIC)
					.tap(PLUGIN_NAME, handler);
			}
		);
	}
}

module.exports = AMDPlugin;


code:
/*
	MIT License http://www.opensource.org/licenses/mit-license.php
	Author Tobias Koppers @sokra
*/

"use strict";

const DependencyTemplate = require("../DependencyTemplate");
const makeSerializable = require("../util/makeSerializable");
const NullDependency = require("./NullDependency");

/** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */
/** @typedef {import("../Dependency")} Dependency */
/** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */
/** @typedef {import("../javascript/JavascriptParser").Range} Range */
/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
/** @typedef {import("./AMDRequireItemDependency")} AMDRequireItemDependency */
/** @typedef {import("./LocalModuleDependency")} LocalModuleDependency */

class AMDRequireArrayDependency extends NullDependency {
	/**
	 * @param {(string | LocalModuleDependency | AMDRequireItemDependency)[]} depsArray deps array
	 * @param {Range} range range
	 */
	constructor(depsArray, range) {
		super();

		this.depsArray = depsArray;
		this.range = range;
	}

	get type() {
		return "amd require array";
	}

	get category() {
		return "amd";
	}

	/**
	 * @param {ObjectSerializerContext} context context
	 */
	serialize(context) {
		const { write } = context;

		write(this.depsArray);
		write(this.range);

		super.serialize(context);
	}

	/**
	 * @param {ObjectDeserializerContext} context context
	 */
	deserialize(context) {
		const { read } = context;

		this.depsArray = read();
		this.range = read();

		super.deserialize(context);
	}
}

makeSerializable(
	AMDRequireArrayDependency,
	"webpack/lib/dependencies/AMDRequireArrayDependency"
);

AMDRequireArrayDependency.Template = class AMDRequireArrayDependencyTemplate extends (
	DependencyTemplate
) {
	/**
	 * @param {Dependency} dependency the dependency for which the template should be applied
	 * @param {ReplaceSource} source the current replace source which can be modified
	 * @param {DependencyTemplateContext} templateContext the context object
	 * @returns {void}
	 */
	apply(dependency, source, templateContext) {
		const dep = /** @type {AMDRequireArrayDependency} */ (dependency);
		const content = this.getContent(dep, templateContext);
		source.replace(dep.range[0], dep.range[1] - 1, content);
	}

	/**
	 * @param {AMDRequireArrayDependency} dep the dependency for which the template should be applied
	 * @param {DependencyTemplateContext} templateContext the context object
	 * @returns {string} content
	 */
	getContent(dep, templateContext) {
		const requires = dep.depsArray.map(dependency => {
			return this.contentForDependency(dependency, templateContext);
		});
		return `[${requires.join(", ")}]`;
	}

	/**
	 * @param {TODO} dep the dependency for which the template should be applied
	 * @param {DependencyTemplateContext} templateContext the context object
	 * @returns {string} content
	 */
	contentForDependency(
		dep,
		{ runtimeTemplate, moduleGraph, chunkGraph, runtimeRequirements }
	) {
		if (typeof dep === "string") {
			return dep;
		}

		if (dep.localModule) {
			return dep.localModule.variableName();
		} else {
			return runtimeTemplate.moduleExports({
				module: moduleGraph.getModule(dep),
				chunkGraph,
				request: dep.request,
				runtimeRequirements
			});
		}
	}
};

module.exports = AMDRequireArrayDependency;


code:
/*
	MIT License http://www.opensource.org/licenses/mit-license.php
	Author Tobias Koppers @sokra
*/

"use strict";

const makeSerializable = require("../util/makeSerializable");
const ContextDependency = require("./ContextDependency");

/** @typedef {import("../javascript/JavascriptParser").Range} Range */
/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */

class AMDRequireContextDependency extends ContextDependency {
	/**
	 * @param {TODO} options options
	 * @param {Range} range range
	 * @param {Range} valueRange value range
	 */
	constructor(options, range, valueRange) {
		super(options);

		this.range = range;
		this.valueRange = valueRange;
	}

	get type() {
		return "amd require context";
	}

	get category() {
		return "amd";
	}

	/**
	 * @param {ObjectSerializerContext} context context
	 */
	serialize(context) {
		const { write } = context;

		write(this.range);
		write(this.valueRange);

		super.serialize(context);
	}

	/**
	 * @param {ObjectDeserializerContext} context context
	 */
	deserialize(context) {
		const { read } = context;

		this.range = read();
		this.valueRange = read();

		super.deserialize(context);
	}
}

makeSerializable(
	AMDRequireContextDependency,
	"webpack/lib/dependencies/AMDRequireContextDependency"
);

AMDRequireContextDependency.Template = require("./ContextDependencyTemplateAsRequireCall");

module.exports = AMDRequireContextDependency;


code:
/*
	MIT License http://www.opensource.org/licenses/mit-license.php
	Author Tobias Koppers @sokra
*/

"use strict";

const AsyncDependenciesBlock = require("../AsyncDependenciesBlock");
const makeSerializable = require("../util/makeSerializable");

/** @typedef {import("../Dependency").DependencyLocation} DependencyLocation */

class AMDRequireDependenciesBlock extends AsyncDependenciesBlock {
	/**
	 * @param {DependencyLocation} loc location info
	 * @param {string=} request request
	 */
	constructor(loc, request) {
		super(null, loc, request);
	}
}

makeSerializable(
	AMDRequireDependenciesBlock,
	"webpack/lib/dependencies/AMDRequireDependenciesBlock"
);

module.exports = AMDRequireDependenciesBlock;


code:
/*
	MIT License http://www.opensource.org/licenses/mit-license.php
	Author Tobias Koppers @sokra
*/

"use strict";

const RuntimeGlobals = require("../RuntimeGlobals");
const UnsupportedFeatureWarning = require("../UnsupportedFeatureWarning");
const AMDRequireArrayDependency = require("./AMDRequireArrayDependency");
const AMDRequireContextDependency = require("./AMDRequireContextDependency");
const AMDRequireDependenciesBlock = require("./AMDRequireDependenciesBlock");
const AMDRequireDependency = require("./AMDRequireDependency");
const AMDRequireItemDependency = require("./AMDRequireItemDependency");
const ConstDependency = require("./ConstDependency");
const ContextDependencyHelpers = require("./ContextDependencyHelpers");
const LocalModuleDependency = require("./LocalModuleDependency");
const { getLocalModule } = require("./LocalModulesHelpers");
const UnsupportedDependency = require("./UnsupportedDependency");
const getFunctionExpression = require("./getFunctionExpression");

/** @typedef {import("estree").CallExpression} CallExpression */
/** @typedef {import("estree").Expression} Expression */
/** @typedef {import("estree").Identifier} Identifier */
/** @typedef {import("estree").SourceLocation} SourceLocation */
/** @typedef {import("estree").SpreadElement} SpreadElement */
/** @typedef {import("../../declarations/WebpackOptions").JavascriptParserOptions} JavascriptParserOptions */
/** @typedef {import("../Dependency").DependencyLocation} DependencyLocation */
/** @typedef {import("../Module").BuildInfo} BuildInfo */
/** @typedef {import("../javascript/BasicEvaluatedExpression")} BasicEvaluatedExpression */
/** @typedef {import("../javascript/JavascriptParser")} JavascriptParser */
/** @typedef {import("../javascript/JavascriptParser").Range} Range */

class AMDRequireDependenciesBlockParserPlugin {
	/**
	 * @param {JavascriptParserOptions} options parserOptions
	 */
	constructor(options) {
		this.options = options;
	}

	/**
	 * @param {JavascriptParser} parser the parser
	 * @param {Expression | SpreadElement} expression expression
	 * @returns {boolean} need bind this
	 */
	processFunctionArgument(parser, expression) {
		let bindThis = true;
		const fnData = getFunctionExpression(expression);
		if (fnData) {
			parser.inScope(
				fnData.fn.params.filter(i => {
					return !["require", "module", "exports"].includes(
						/** @type {Identifier} */ (i).name
					);
				}),
				() => {
					if (fnData.fn.body.type === "BlockStatement") {
						parser.walkStatement(fnData.fn.body);
					} else {
						parser.walkExpression(fnData.fn.body);
					}
				}
			);
			parser.walkExpressions(fnData.expressions);
			if (fnData.needThis === false) {
				bindThis = false;
			}
		} else {
			parser.walkExpression(expression);
		}
		return bindThis;
	}

	/**
	 * @param {JavascriptParser} parser the parser
	 * @returns {void}
	 */
	apply(parser) {
		parser.hooks.call
			.for("require")
			.tap(
				"AMDRequireDependenciesBlockParserPlugin",
				this.processCallRequire.bind(this, parser)
			);
	}

	/**
	 * @param {JavascriptParser} parser the parser
	 * @param {CallExpression} expr call expression
	 * @param {BasicEvaluatedExpression} param param
	 * @returns {boolean | undefined} result
	 */
	processArray(parser, expr, param) {
		if (param.isArray()) {
			for (const p of /** @type {BasicEvaluatedExpression[]} */ (param.items)) {
				const result = this.processItem(parser, expr, p);
				if (result === undefined) {
					this.processContext(parser, expr, p);
				}
			}
			return true;
		} else if (param.isConstArray()) {
			/** @type {(string | LocalModuleDependency | AMDRequireItemDependency)[]} */
			const deps = [];
			for (const request of /** @type {any[]} */ (param.array)) {
				let dep, localModule;
				if (request === "require") {
					dep = RuntimeGlobals.require;
				} else if (["exports", "module"].includes(request)) {
					dep = request;
				} else if ((localModule = getLocalModule(parser.state, request))) {
					localModule.flagUsed();
					dep = new LocalModuleDependency(localModule, undefined, false);
					dep.loc = /** @type {DependencyLocation} */ (expr.loc);
					parser.state.module.addPresentationalDependency(dep);
				} else {
					dep = this.newRequireItemDependency(request);
					dep.loc = /** @type {DependencyLocation} */ (expr.loc);
					dep.optional = !!parser.scope.inTry;
					parser.state.current.addDependency(dep);
				}
				deps.push(dep);
			}
			const dep = this.newRequireArrayDependency(
				deps,
				/** @type {Range} */ (param.range)
			);
			dep.loc = /** @type {DependencyLocation} */ (expr.loc);
			dep.optional = !!parser.scope.inTry;
			parser.state.module.addPresentationalDependency(dep);
			return true;
		}
	}

	/**
	 * @param {JavascriptParser} parser the parser
	 * @param {CallExpression} expr call expression
	 * @param {BasicEvaluatedExpression} param param
	 * @returns {boolean | undefined} result
	 */
	processItem(parser, expr, param) {
		if (param.isConditional()) {
			for (const p of /** @type {BasicEvaluatedExpression[]} */ (
				param.options
			)) {
				const result = this.processItem(parser, expr, p);
				if (result === undefined) {
					this.processContext(parser, expr, p);
				}
			}
			return true;
		} else if (param.isString()) {
			let dep, localModule;
			if (param.string === "require") {
				dep = new ConstDependency(
					RuntimeGlobals.require,
					/** @type {TODO} */ (param.string),
					[RuntimeGlobals.require]
				);
			} else if (param.string === "module") {
				dep = new ConstDependency(
					/** @type {BuildInfo} */
					(parser.state.module.buildInfo).moduleArgument,
					/** @type {Range} */ (param.range),
					[RuntimeGlobals.module]
				);
			} else if (param.string === "exports") {
				dep = new ConstDependency(
					/** @type {BuildInfo} */
					(parser.state.module.buildInfo).exportsArgument,
					/** @type {Range} */ (param.range),
					[RuntimeGlobals.exports]
				);
			} else if (
				(localModule = getLocalModule(
					parser.state,
					/** @type {string} */ (param.string)
				))
			) {
				localModule.flagUsed();
				dep = new LocalModuleDependency(localModule, param.range, false);
			} else {
				dep = this.newRequireItemDependency(
					/** @type {string} */ (param.string),
					param.range
				);
				dep.loc = /** @type {DependencyLocation} */ (expr.loc);
				dep.optional = !!parser.scope.inTry;
				parser.state.current.addDependency(dep);
				return true;
			}
			dep.loc = /** @type {DependencyLocation} */ (expr.loc);
			parser.state.module.addPresentationalDependency(dep);
			return true;
		}
	}

	/**
	 * @param {JavascriptParser} parser the parser
	 * @param {CallExpression} expr call expression
	 * @param {BasicEvaluatedExpression} param param
	 * @returns {boolean | undefined} result
	 */
	processContext(parser, expr, param) {
		const dep = ContextDependencyHelpers.create(
			AMDRequireContextDependency,
			/** @type {Range} */ (param.range),
			param,
			expr,
			this.options,
			{
				category: "amd"
			},
			parser
		);
		if (!dep) return;
		dep.loc = /** @type {DependencyLocation} */ (expr.loc);
		dep.optional = !!parser.scope.inTry;
		parser.state.current.addDependency(dep);
		return true;
	}

	/**
	 * @param {BasicEvaluatedExpression} param param
	 * @returns {string | undefined} result
	 */
	processArrayForRequestString(param) {
		if (param.isArray()) {
			const result =
				/** @type {BasicEvaluatedExpression[]} */
				(param.items).map(item => this.processItemForRequestString(item));
			if (result.every(Boolean)) return result.join(" ");
		} else if (param.isConstArray()) {
			return /** @type {string[]} */ (param.array).join(" ");
		}
	}

	/**
	 * @param {BasicEvaluatedExpression} param param
	 * @returns {string | undefined} result
	 */
	processItemForRequestString(param) {
		if (param.isConditional()) {
			const result =
				/** @type {BasicEvaluatedExpression[]} */
				(param.options).map(item => this.processItemForRequestString(item));
			if (result.every(Boolean)) return result.join("|");
		} else if (param.isString()) {
			return param.string;
		}
	}

	/**
	 * @param {JavascriptParser} parser the parser
	 * @param {CallExpression} expr call expression
	 * @returns {boolean | undefined} result
	 */
	processCallRequire(parser, expr) {
		/** @type {BasicEvaluatedExpression | undefined} */
		let param;
		/** @type {AMDRequireDependenciesBlock | undefined | null} */
		let depBlock;
		/** @type {AMDRequireDependency | undefined} */
		let dep;
		/** @type {boolean | undefined} */
		let result;

		const old = parser.state.current;

		if (expr.arguments.length >= 1) {
			param = parser.evaluateExpression(expr.arguments[0]);
			depBlock = this.newRequireDependenciesBlock(
				/** @type {DependencyLocation} */ (expr.loc),
				/** @type {string} */ (this.processArrayForRequestString(param))
			);
			dep = this.newRequireDependency(
				/** @type {Range} */ (expr.range),
				/** @type {Range} */ (param.range),
				expr.arguments.length > 1
					? /** @type {Range} */ (expr.arguments[1].range)
					: null,
				expr.arguments.length > 2
					? /** @type {Range} */ (expr.arguments[2].range)
					: null
			);
			dep.loc = /** @type {DependencyLocation} */ (expr.loc);
			depBlock.addDependency(dep);

			parser.state.current = /** @type {TODO} */ (depBlock);
		}

		if (expr.arguments.length === 1) {
			parser.inScope([], () => {
				result = this.processArray(
					parser,
					expr,
					/** @type {BasicEvaluatedExpression} */ (param)
				);
			});
			parser.state.current = old;
			if (!result) return;
			parser.state.current.addBlock(
				/** @type {AMDRequireDependenciesBlock} */ (depBlock)
			);
			return true;
		}

		if (expr.arguments.length === 2 || expr.arguments.length === 3) {
			try {
				parser.inScope([], () => {
					result = this.processArray(
						parser,
						expr,
						/** @type {BasicEvaluatedExpression} */ (param)
					);
				});
				if (!result) {
					const dep = new UnsupportedDependency(
						"unsupported",
						/** @type {Range} */ (expr.range)
					);
					old.addPresentationalDependency(dep);
					if (parser.state.module) {
						parser.state.module.addError(
							new UnsupportedFeatureWarning(
								"Cannot statically analyse 'require(…, …)' in line " +
									/** @type {SourceLocation} */ (expr.loc).start.line,
								/** @type {DependencyLocation} */ (expr.loc)
							)
						);
					}
					depBlock = null;
					return true;
				}
				/** @type {AMDRequireDependency} */
				(dep).functionBindThis = this.processFunctionArgument(
					parser,
					expr.arguments[1]
				);
				if (expr.arguments.length === 3) {
					/** @type {AMDRequireDependency} */
					(dep).errorCallbackBindThis = this.processFunctionArgument(
						parser,
						expr.arguments[2]
					);
				}
			} finally {
				parser.state.current = old;
				if (depBlock) parser.state.current.addBlock(depBlock);
			}
			return true;
		}
	}

	/**
	 * @param {DependencyLocation} loc location
	 * @param {string} request request
	 * @returns {AMDRequireDependenciesBlock} AMDRequireDependenciesBlock
	 */
	newRequireDependenciesBlock(loc, request) {
		return new AMDRequireDependenciesBlock(loc, request);
	}

	/**
	 * @param {Range} outerRange outer range
	 * @param {Range} arrayRange array range
	 * @param {Range | null} functionRange function range
	 * @param {Range | null} errorCallbackRange error callback range
	 * @returns {AMDRequireDependency} dependency
	 */
	newRequireDependency(
		outerRange,
		arrayRange,
		functionRange,
		errorCallbackRange
	) {
		return new AMDRequireDependency(
			outerRange,
			arrayRange,
			functionRange,
			errorCallbackRange
		);
	}

	/**
	 * @param {string} request request
	 * @param {Range=} range range
	 * @returns {AMDRequireItemDependency} AMDRequireItemDependency
	 */
	newRequireItemDependency(request, range) {
		return new AMDRequireItemDependency(request, range);
	}

	/**
	 * @param {(string | LocalModuleDependency | AMDRequireItemDependency)[]} depsArray deps array
	 * @param {Range} range range
	 * @returns {AMDRequireArrayDependency} AMDRequireArrayDependency
	 */
	newRequireArrayDependency(depsArray, range) {
		return new AMDRequireArrayDependency(depsArray, range);
	}
}
module.exports = AMDRequireDependenciesBlockParserPlugin;


code:
/*
	MIT License http://www.opensource.org/licenses/mit-license.php
	Author Tobias Koppers @sokra
*/

"use strict";

const RuntimeGlobals = require("../RuntimeGlobals");
const makeSerializable = require("../util/makeSerializable");
const NullDependency = require("./NullDependency");

/** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */
/** @typedef {import("../AsyncDependenciesBlock")} AsyncDependenciesBlock */
/** @typedef {import("../Dependency")} Dependency */
/** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */
/** @typedef {import("../javascript/JavascriptParser").Range} Range */
/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */

class AMDRequireDependency extends NullDependency {
	/**
	 * @param {Range} outerRange outer range
	 * @param {Range} arrayRange array range
	 * @param {Range | null} functionRange function range
	 * @param {Range | null} errorCallbackRange error callback range
	 */
	constructor(outerRange, arrayRange, functionRange, errorCallbackRange) {
		super();

		this.outerRange = outerRange;
		this.arrayRange = arrayRange;
		this.functionRange = functionRange;
		this.errorCallbackRange = errorCallbackRange;
		this.functionBindThis = false;
		this.errorCallbackBindThis = false;
	}

	get category() {
		return "amd";
	}

	/**
	 * @param {ObjectSerializerContext} context context
	 */
	serialize(context) {
		const { write } = context;

		write(this.outerRange);
		write(this.arrayRange);
		write(this.functionRange);
		write(this.errorCallbackRange);
		write(this.functionBindThis);
		write(this.errorCallbackBindThis);

		super.serialize(context);
	}

	/**
	 * @param {ObjectDeserializerContext} context context
	 */
	deserialize(context) {
		const { read } = context;

		this.outerRange = read();
		this.arrayRange = read();
		this.functionRange = read();
		this.errorCallbackRange = read();
		this.functionBindThis = read();
		this.errorCallbackBindThis = read();

		super.deserialize(context);
	}
}

makeSerializable(
	AMDRequireDependency,
	"webpack/lib/dependencies/AMDRequireDependency"
);

AMDRequireDependency.Template = class AMDRequireDependencyTemplate extends (
	NullDependency.Template
) {
	/**
	 * @param {Dependency} dependency the dependency for which the template should be applied
	 * @param {ReplaceSource} source the current replace source which can be modified
	 * @param {DependencyTemplateContext} templateContext the context object
	 * @returns {void}
	 */
	apply(
		dependency,
		source,
		{ runtimeTemplate, moduleGraph, chunkGraph, runtimeRequirements }
	) {
		const dep = /** @type {AMDRequireDependency} */ (dependency);
		const depBlock = /** @type {AsyncDependenciesBlock} */ (
			moduleGraph.getParentBlock(dep)
		);
		const promise = runtimeTemplate.blockPromise({
			chunkGraph,
			block: depBlock,
			message: "AMD require",
			runtimeRequirements
		});

		// has array range but no function range
		if (dep.arrayRange && !dep.functionRange) {
			const startBlock = `${promise}.then(function() {`;
			const endBlock = `;})['catch'](${RuntimeGlobals.uncaughtErrorHandler})`;
			runtimeRequirements.add(RuntimeGlobals.uncaughtErrorHandler);

			source.replace(dep.outerRange[0], dep.arrayRange[0] - 1, startBlock);

			source.replace(dep.arrayRange[1], dep.outerRange[1] - 1, endBlock);

			return;
		}

		// has function range but no array range
		if (dep.functionRange && !dep.arrayRange) {
			const startBlock = `${promise}.then((`;
			const endBlock = `).bind(exports, ${RuntimeGlobals.require}, exports, module))['catch'](${RuntimeGlobals.uncaughtErrorHandler})`;
			runtimeRequirements.add(RuntimeGlobals.uncaughtErrorHandler);

			source.replace(dep.outerRange[0], dep.functionRange[0] - 1, startBlock);

			source.replace(dep.functionRange[1], dep.outerRange[1] - 1, endBlock);

			return;
		}

		// has array range, function range, and errorCallbackRange
		if (dep.arrayRange && dep.functionRange && dep.errorCallbackRange) {
			const startBlock = `${promise}.then(function() { `;
			const errorRangeBlock = `}${
				dep.functionBindThis ? ".bind(this)" : ""
			})['catch'](`;
			const endBlock = `${dep.errorCallbackBindThis ? ".bind(this)" : ""})`;

			source.replace(dep.outerRange[0], dep.arrayRange[0] - 1, startBlock);

			source.insert(dep.arrayRange[0], "var __WEBPACK_AMD_REQUIRE_ARRAY__ = ");

			source.replace(dep.arrayRange[1], dep.functionRange[0] - 1, "; (");

			source.insert(
				dep.functionRange[1],
				").apply(null, __WEBPACK_AMD_REQUIRE_ARRAY__);"
			);

			source.replace(
				dep.functionRange[1],
				dep.errorCallbackRange[0] - 1,
				errorRangeBlock
			);

			source.replace(
				dep.errorCallbackRange[1],
				dep.outerRange[1] - 1,
				endBlock
			);

			return;
		}

		// has array range, function range, but no errorCallbackRange
		if (dep.arrayRange && dep.functionRange) {
			const startBlock = `${promise}.then(function() { `;
			const endBlock = `}${
				dep.functionBindThis ? ".bind(this)" : ""
			})['catch'](${RuntimeGlobals.uncaughtErrorHandler})`;
			runtimeRequirements.add(RuntimeGlobals.uncaughtErrorHandler);

			source.replace(dep.outerRange[0], dep.arrayRange[0] - 1, startBlock);

			source.insert(dep.arrayRange[0], "var __WEBPACK_AMD_REQUIRE_ARRAY__ = ");

			source.replace(dep.arrayRange[1], dep.functionRange[0] - 1, "; (");

			source.insert(
				dep.functionRange[1],
				").apply(null, __WEBPACK_AMD_REQUIRE_ARRAY__);"
			);

			source.replace(dep.functionRange[1], dep.outerRange[1] - 1, endBlock);
		}
	}
};

module.exports = AMDRequireDependency;


code:
/*
	MIT License http://www.opensource.org/licenses/mit-license.php
	Author Tobias Koppers @sokra
*/

"use strict";

const makeSerializable = require("../util/makeSerializable");
const ModuleDependency = require("./ModuleDependency");
const ModuleDependencyTemplateAsRequireId = require("./ModuleDependencyTemplateAsRequireId");

/** @typedef {import("../javascript/JavascriptParser").Range} Range */

class AMDRequireItemDependency extends ModuleDependency {
	/**
	 * @param {string} request the request string
	 * @param {Range=} range location in source code
	 */
	constructor(request, range) {
		super(request);

		this.range = range;
	}

	get type() {
		return "amd require";
	}

	get category() {
		return "amd";
	}
}

makeSerializable(
	AMDRequireItemDependency,
	"webpack/lib/dependencies/AMDRequireItemDependency"
);

AMDRequireItemDependency.Template = ModuleDependencyTemplateAsRequireId;

module.exports = AMDRequireItemDependency;


code:
/*
	MIT License http://www.opensource.org/licenses/mit-license.php
*/

"use strict";

const RuntimeGlobals = require("../RuntimeGlobals");
const RuntimeModule = require("../RuntimeModule");
const Template = require("../Template");

class AMDDefineRuntimeModule extends RuntimeModule {
	constructor() {
		super("amd define");
	}

	/**
	 * @returns {string | null} runtime code
	 */
	generate() {
		return Template.asString([
			`${RuntimeGlobals.amdDefine} = function () {`,
			Template.indent("throw new Error('define cannot be used indirect');"),
			"};"
		]);
	}
}

class AMDOptionsRuntimeModule extends RuntimeModule {
	/**
	 * @param {Record<string, boolean | number | string>} options the AMD options
	 */
	constructor(options) {
		super("amd options");
		this.options = options;
	}

	/**
	 * @returns {string | null} runtime code
	 */
	generate() {
		return Template.asString([
			`${RuntimeGlobals.amdOptions} = ${JSON.stringify(this.options)};`
		]);
	}
}

exports.AMDDefineRuntimeModule = AMDDefineRuntimeModule;
exports.AMDOptionsRuntimeModule = AMDOptionsRuntimeModule;


code:
/*
	MIT License http://www.opensource.org/licenses/mit-license.php
	Author Florent Cailhol @ooflorent
*/

"use strict";

const DependencyTemplate = require("../DependencyTemplate");
const InitFragment = require("../InitFragment");
const makeSerializable = require("../util/makeSerializable");
const NullDependency = require("./NullDependency");

/** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */
/** @typedef {import("../ChunkGraph")} ChunkGraph */
/** @typedef {import("../Dependency")} Dependency */
/** @typedef {import("../Dependency").UpdateHashContext} UpdateHashContext */
/** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */
/** @typedef {import("../DependencyTemplates")} DependencyTemplates */
/** @typedef {import("../ModuleGraph")} ModuleGraph */
/** @typedef {import("../RuntimeTemplate")} RuntimeTemplate */
/** @typedef {import("../javascript/JavascriptParser").Range} Range */
/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
/** @typedef {import("../util/Hash")} Hash */

class CachedConstDependency extends NullDependency {
	/**
	 * @param {string} expression expression
	 * @param {Range} range range
	 * @param {string} identifier identifier
	 */
	constructor(expression, range, identifier) {
		super();

		this.expression = expression;
		this.range = range;
		this.identifier = identifier;
		this._hashUpdate = undefined;
	}

	/**
	 * @returns {string} hash update
	 */
	_createHashUpdate() {
		return `${this.identifier}${this.range}${this.expression}`;
	}

	/**
	 * Update the hash
	 * @param {Hash} hash hash to be updated
	 * @param {UpdateHashContext} context context
	 * @returns {void}
	 */
	updateHash(hash, context) {
		if (this._hashUpdate === undefined)
			this._hashUpdate = this._createHashUpdate();
		hash.update(this._hashUpdate);
	}

	/**
	 * @param {ObjectSerializerContext} context context
	 */
	serialize(context) {
		const { write } = context;

		write(this.expression);
		write(this.range);
		write(this.identifier);

		super.serialize(context);
	}

	/**
	 * @param {ObjectDeserializerContext} context context
	 */
	deserialize(context) {
		const { read } = context;

		this.expression = read();
		this.range = read();
		this.identifier = read();

		super.deserialize(context);
	}
}

makeSerializable(
	CachedConstDependency,
	"webpack/lib/dependencies/CachedConstDependency"
);

CachedConstDependency.Template = class CachedConstDependencyTemplate extends (
	DependencyTemplate
) {
	/**
	 * @param {Dependency} dependency the dependency for which the template should be applied
	 * @param {ReplaceSource} source the current replace source which can be modified
	 * @param {DependencyTemplateContext} templateContext the context object
	 * @returns {void}
	 */
	apply(
		dependency,
		source,
		{ runtimeTemplate, dependencyTemplates, initFragments }
	) {
		const dep = /** @type {CachedConstDependency} */ (dependency);

		initFragments.push(
			new InitFragment(
				`var ${dep.identifier} = ${dep.expression};\n`,
				InitFragment.STAGE_CONSTANTS,
				0,
				`const ${dep.identifier}`
			)
		);

		if (typeof dep.range === "number") {
			source.insert(dep.range, dep.identifier);

			return;
		}

		source.replace(dep.range[0], dep.range[1] - 1, dep.identifier);
	}
};

module.exports = CachedConstDependency;


code:
/*
	MIT License http://www.opensource.org/licenses/mit-license.php
	Author Tobias Koppers @sokra
*/

"use strict";

const RuntimeGlobals = require("../RuntimeGlobals");

/** @typedef {import("../Module")} Module */
/** @typedef {import("../Module").RuntimeRequirements} RuntimeRequirements */
/** @typedef {"exports" | "module.exports" | "this" | "Object.defineProperty(exports)" | "Object.defineProperty(module.exports)" | "Object.defineProperty(this)"} CommonJSDependencyBaseKeywords */

/**
 * @param {CommonJSDependencyBaseKeywords} depBase commonjs dependency base
 * @param {Module} module module
 * @param {RuntimeRequirements} runtimeRequirements runtime requirements
 * @returns {[string, string]} type and base
 */
exports.handleDependencyBase = (depBase, module, runtimeRequirements) => {
	let base = undefined;
	let type;
	switch (depBase) {
		case "exports":
			runtimeRequirements.add(RuntimeGlobals.exports);
			base = module.exportsArgument;
			type = "expression";
			break;
		case "module.exports":
			runtimeRequirements.add(RuntimeGlobals.module);
			base = `${module.moduleArgument}.exports`;
			type = "expression";
			break;
		case "this":
			runtimeRequirements.add(RuntimeGlobals.thisAsExports);
			base = "this";
			type = "expression";
			break;
		case "Object.defineProperty(exports)":
			runtimeRequirements.add(RuntimeGlobals.exports);
			base = module.exportsArgument;
			type = "Object.defineProperty";
			break;
		case "Object.defineProperty(module.exports)":
			runtimeRequirements.add(RuntimeGlobals.module);
			base = `${module.moduleArgument}.exports`;
			type = "Object.defineProperty";
			break;
		case "Object.defineProperty(this)":
			runtimeRequirements.add(RuntimeGlobals.thisAsExports);
			base = "this";
			type = "Object.defineProperty";
			break;
		default:
			throw new Error(`Unsupported base ${depBase}`);
	}

	return [type, base];
};


code:
/*
	MIT License http://www.opensource.org/licenses/mit-license.php
	Author Tobias Koppers @sokra
*/

"use strict";

const Dependency = require("../Dependency");
const { UsageState } = require("../ExportsInfo");
const Template = require("../Template");
const { equals } = require("../util/ArrayHelpers");
const makeSerializable = require("../util/makeSerializable");
const propertyAccess = require("../util/propertyAccess");
const { handleDependencyBase } = require("./CommonJsDependencyHelpers");
const ModuleDependency = require("./ModuleDependency");
const processExportInfo = require("./processExportInfo");

/** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */
/** @typedef {import("../Dependency").ExportsSpec} ExportsSpec */
/** @typedef {import("../Dependency").ReferencedExport} ReferencedExport */
/** @typedef {import("../Dependency").TRANSITIVE} TRANSITIVE */
/** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */
/** @typedef {import("../ExportsInfo")} ExportsInfo */
/** @typedef {import("../ExportsInfo").ExportInfo} ExportInfo */
/** @typedef {import("../Module")} Module */
/** @typedef {import("../ModuleGraph")} ModuleGraph */
/** @typedef {import("../javascript/JavascriptParser").Range} Range */
/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
/** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */
/** @typedef {import("./CommonJsDependencyHelpers").CommonJSDependencyBaseKeywords} CommonJSDependencyBaseKeywords */

const idsSymbol = Symbol("CommonJsExportRequireDependency.ids");

const EMPTY_OBJECT = {};

class CommonJsExportRequireDependency extends ModuleDependency {
	/**
	 * @param {Range} range range
	 * @param {Range | null} valueRange value range
	 * @param {CommonJSDependencyBaseKeywords} base base
	 * @param {string[]} names names
	 * @param {string} request request
	 * @param {string[]} ids ids
	 * @param {boolean} resultUsed true, when the result is used
	 */
	constructor(range, valueRange, base, names, request, ids, resultUsed) {
		super(request);
		this.range = range;
		this.valueRange = valueRange;
		this.base = base;
		this.names = names;
		this.ids = ids;
		this.resultUsed = resultUsed;
		this.asiSafe = undefined;
	}

	get type() {
		return "cjs export require";
	}

	/**
	 * @returns {boolean | TRANSITIVE} true, when changes to the referenced module could affect the referencing module; TRANSITIVE, when changes to the referenced module could affect referencing modules of the referencing module
	 */
	couldAffectReferencingModule() {
		return Dependency.TRANSITIVE;
	}

	/**
	 * @param {ModuleGraph} moduleGraph the module graph
	 * @returns {string[]} the imported id
	 */
	getIds(moduleGraph) {
		return (
			/** @type {TODO} */ (moduleGraph.getMeta(this))[idsSymbol] || this.ids
		);
	}

	/**
	 * @param {ModuleGraph} moduleGraph the module graph
	 * @param {string[]} ids the imported ids
	 * @returns {void}
	 */
	setIds(moduleGraph, ids) {
		/** @type {TODO} */ (moduleGraph.getMeta(this))[idsSymbol] = ids;
	}

	/**
	 * Returns list of exports referenced by this dependency
	 * @param {ModuleGraph} moduleGraph module graph
	 * @param {RuntimeSpec} runtime the runtime for which the module is analysed
	 * @returns {(string[] | ReferencedExport)[]} referenced exports
	 */
	getReferencedExports(moduleGraph, runtime) {
		const ids = this.getIds(moduleGraph);
		const getFullResult = () => {
			if (ids.length === 0) {
				return Dependency.EXPORTS_OBJECT_REFERENCED;
			} else {
				return [
					{
						name: ids,
						canMangle: false
					}
				];
			}
		};
		if (this.resultUsed) return getFullResult();
		/** @type {ExportsInfo | undefined} */
		let exportsInfo = moduleGraph.getExportsInfo(
			/** @type {Module} */ (moduleGraph.getParentModule(this))
		);
		for (const name of this.names) {
			const exportInfo = /** @type {ExportInfo} */ (
				exportsInfo.getReadOnlyExportInfo(name)
			);
			const used = exportInfo.getUsed(runtime);
			if (used === UsageState.Unused) return Dependency.NO_EXPORTS_REFERENCED;
			if (used !== UsageState.OnlyPropertiesUsed) return getFullResult();
			exportsInfo = exportInfo.exportsInfo;
			if (!exportsInfo) return getFullResult();
		}
		if (exportsInfo.otherExportsInfo.getUsed(runtime) !== UsageState.Unused) {
			return getFullResult();
		}
		/** @type {string[][]} */
		const referencedExports = [];
		for (const exportInfo of exportsInfo.orderedExports) {
			processExportInfo(
				runtime,
				referencedExports,
				ids.concat(exportInfo.name),
				exportInfo,
				false
			);
		}
		return referencedExports.map(name => ({
			name,
			canMangle: false
		}));
	}

	/**
	 * Returns the exported names
	 * @param {ModuleGraph} moduleGraph module graph
	 * @returns {ExportsSpec | undefined} export names
	 */
	getExports(moduleGraph) {
		const ids = this.getIds(moduleGraph);
		if (this.names.length === 1) {
			const name = this.names[0];
			const from = moduleGraph.getConnection(this);
			if (!from) return;
			return {
				exports: [
					{
						name,
						from,
						export: ids.length === 0 ? null : ids,
						// we can't mangle names that are in an empty object
						// because one could access the prototype property
						// when export isn't set yet
						canMangle: !(name in EMPTY_OBJECT) && false
					}
				],
				dependencies: [from.module]
			};
		} else if (this.names.length > 0) {
			const name = this.names[0];
			return {
				exports: [
					{
						name,
						// we can't mangle names that are in an empty object
						// because one could access the prototype property
						// when export isn't set yet
						canMangle: !(name in EMPTY_OBJECT) && false
					}
				],
				dependencies: undefined
			};
		} else {
			const from = moduleGraph.getConnection(this);
			if (!from) return;
			const reexportInfo = this.getStarReexports(
				moduleGraph,
				undefined,
				from.module
			);
			if (reexportInfo) {
				return {
					exports: Array.from(
						/** @type {TODO} */ (reexportInfo).exports,
						name => {
							return {
								name,
								from,
								export: ids.concat(name),
								canMangle: !(name in EMPTY_OBJECT) && false
							};
						}
					),
					// TODO handle deep reexports
					dependencies: [from.module]
				};
			} else {
				return {
					exports: true,
					from: ids.length === 0 ? from : undefined,
					canMangle: false,
					dependencies: [from.module]
				};
			}
		}
	}

	/**
	 * @param {ModuleGraph} moduleGraph the module graph
	 * @param {RuntimeSpec} runtime the runtime
	 * @param {Module} importedModule the imported module (optional)
	 * @returns {{exports?: Set<string>, checked?: Set<string>} | undefined} information
	 */
	getStarReexports(
		moduleGraph,
		runtime,
		importedModule = /** @type {Module} */ (moduleGraph.getModule(this))
	) {
		/** @type {ExportsInfo | undefined} */
		let importedExportsInfo = moduleGraph.getExportsInfo(importedModule);
		const ids = this.getIds(moduleGraph);
		if (ids.length > 0)
			importedExportsInfo = importedExportsInfo.getNestedExportsInfo(ids);
		/** @type {ExportsInfo | undefined} */
		let exportsInfo = moduleGraph.getExportsInfo(
			/** @type {Module} */ (moduleGraph.getParentModule(this))
		);
		if (this.names.length > 0)
			exportsInfo = exportsInfo.getNestedExportsInfo(this.names);

		const noExtraExports =
			importedExportsInfo &&
			importedExportsInfo.otherExportsInfo.provided === false;
		const noExtraImports =
			exportsInfo &&
			exportsInfo.otherExportsInfo.getUsed(runtime) === UsageState.Unused;

		if (!noExtraExports && !noExtraImports) {
			return;
		}

		const isNamespaceImport =
			importedModule.getExportsType(moduleGraph, false) === "namespace";

		/** @type {Set<string>} */
		const exports = new Set();
		/** @type {Set<string>} */
		const checked = new Set();

		if (noExtraImports) {
			for (const exportInfo of /** @type {ExportsInfo} */ (exportsInfo)
				.orderedExports) {
				const name = exportInfo.name;
				if (exportInfo.getUsed(runtime) === UsageState.Unused) continue;
				if (name === "__esModule" && isNamespaceImport) {
					exports.add(name);
				} else if (importedExportsInfo) {
					const importedExportInfo =
						importedExportsInfo.getReadOnlyExportInfo(name);
					if (importedExportInfo.provided === false) continue;
					exports.add(name);
					if (importedExportInfo.provided === true) continue;
					checked.add(name);
				} else {
					exports.add(name);
					checked.add(name);
				}
			}
		} else if (noExtraExports) {
			for (const importedExportInfo of /** @type {ExportsInfo} */ (
				importedExportsInfo
			).orderedExports) {
				const name = importedExportInfo.name;
				if (importedExportInfo.provided === false) continue;
				if (exportsInfo) {
					const exportInfo = exportsInfo.getReadOnlyExportInfo(name);
					if (exportInfo.getUsed(runtime) === UsageState.Unused) continue;
				}
				exports.add(name);
				if (importedExportInfo.provided === true) continue;
				checked.add(name);
			}
			if (isNamespaceImport) {
				exports.add("__esModule");
				checked.delete("__esModule");
			}
		}

		return { exports, checked };
	}

	/**
	 * @param {ObjectSerializerContext} context context
	 */
	serialize(context) {
		const { write } = context;
		write(this.asiSafe);
		write(this.range);
		write(this.valueRange);
		write(this.base);
		write(this.names);
		write(this.ids);
		write(this.resultUsed);
		super.serialize(context);
	}

	/**
	 * @param {ObjectDeserializerContext} context context
	 */
	deserialize(context) {
		const { read } = context;
		this.asiSafe = read();
		this.range = read();
		this.valueRange = read();
		this.base = read();
		this.names = read();
		this.ids = read();
		this.resultUsed = read();
		super.deserialize(context);
	}
}

makeSerializable(
	CommonJsExportRequireDependency,
	"webpack/lib/dependencies/CommonJsExportRequireDependency"
);

CommonJsExportRequireDependency.Template = class CommonJsExportRequireDependencyTemplate extends (
	ModuleDependency.Template
) {
	/**
	 * @param {Dependency} dependency the dependency for which the template should be applied
	 * @param {ReplaceSource} source the current replace source which can be modified
	 * @param {DependencyTemplateContext} templateContext the context object
	 * @returns {void}
	 */
	apply(
		dependency,
		source,
		{
			module,
			runtimeTemplate,
			chunkGraph,
			moduleGraph,
			runtimeRequirements,
			runtime
		}
	) {
		const dep = /** @type {CommonJsExportRequireDependency} */ (dependency);
		const used = moduleGraph
			.getExportsInfo(module)
			.getUsedName(dep.names, runtime);

		const [type, base] = handleDependencyBase(
			dep.base,
			module,
			runtimeRequirements
		);

		const importedModule = moduleGraph.getModule(dep);
		let requireExpr = runtimeTemplate.moduleExports({
			module: importedModule,
			chunkGraph,
			request: dep.request,
			weak: dep.weak,
			runtimeRequirements
		});
		if (importedModule) {
			const ids = dep.getIds(moduleGraph);
			const usedImported = moduleGraph
				.getExportsInfo(importedModule)
				.getUsedName(ids, runtime);
			if (usedImported) {
				const comment = equals(usedImported, ids)
					? ""
					: Template.toNormalComment(propertyAccess(ids)) + " ";
				requireExpr += `${comment}${propertyAccess(usedImported)}`;
			}
		}

		switch (type) {
			case "expression":
				source.replace(
					dep.range[0],
					dep.range[1] - 1,
					used
						? `${base}${propertyAccess(used)} = ${requireExpr}`
						: `/* unused reexport */ ${requireExpr}`
				);
				return;
			case "Object.defineProperty":
				throw new Error("TODO");
			default:
				throw new Error("Unexpected type");
		}
	}
};

module.exports = CommonJsExportRequireDependency;


code:
/*
	MIT License http://www.opensource.org/licenses/mit-license.php
	Author Tobias Koppers @sokra
*/

"use strict";

const InitFragment = require("../InitFragment");
const makeSerializable = require("../util/makeSerializable");
const propertyAccess = require("../util/propertyAccess");
const { handleDependencyBase } = require("./CommonJsDependencyHelpers");
const NullDependency = require("./NullDependency");

/** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */
/** @typedef {import("../Dependency")} Dependency */
/** @typedef {import("../Dependency").ExportsSpec} ExportsSpec */
/** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */
/** @typedef {import("../ModuleGraph")} ModuleGraph */
/** @typedef {import("../javascript/JavascriptParser").Range} Range */
/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
/** @typedef {import("./CommonJsDependencyHelpers").CommonJSDependencyBaseKeywords} CommonJSDependencyBaseKeywords */

const EMPTY_OBJECT = {};

class CommonJsExportsDependency extends NullDependency {
	/**
	 * @param {Range} range range
	 * @param {Range | null} valueRange value range
	 * @param {CommonJSDependencyBaseKeywords} base base
	 * @param {string[]} names names
	 */
	constructor(range, valueRange, base, names) {
		super();
		this.range = range;
		this.valueRange = valueRange;
		this.base = base;
		this.names = names;
	}

	get type() {
		return "cjs exports";
	}

	/**
	 * Returns the exported names
	 * @param {ModuleGraph} moduleGraph module graph
	 * @returns {ExportsSpec | undefined} export names
	 */
	getExports(moduleGraph) {
		const name = this.names[0];
		return {
			exports: [
				{
					name,
					// we can't mangle names that are in an empty object
					// because one could access the prototype property
					// when export isn't set yet
					canMangle: !(name in EMPTY_OBJECT)
				}
			],
			dependencies: undefined
		};
	}

	/**
	 * @param {ObjectSerializerContext} context context
	 */
	serialize(context) {
		const { write } = context;
		write(this.range);
		write(this.valueRange);
		write(this.base);
		write(this.names);
		super.serialize(context);
	}

	/**
	 * @param {ObjectDeserializerContext} context context
	 */
	deserialize(context) {
		const { read } = context;
		this.range = read();
		this.valueRange = read();
		this.base = read();
		this.names = read();
		super.deserialize(context);
	}
}

makeSerializable(
	CommonJsExportsDependency,
	"webpack/lib/dependencies/CommonJsExportsDependency"
);

CommonJsExportsDependency.Template = class CommonJsExportsDependencyTemplate extends (
	NullDependency.Template
) {
	/**
	 * @param {Dependency} dependency the dependency for which the template should be applied
	 * @param {ReplaceSource} source the current replace source which can be modified
	 * @param {DependencyTemplateContext} templateContext the context object
	 * @returns {void}
	 */
	apply(
		dependency,
		source,
		{ module, moduleGraph, initFragments, runtimeRequirements, runtime }
	) {
		const dep = /** @type {CommonJsExportsDependency} */ (dependency);
		const used = moduleGraph
			.getExportsInfo(module)
			.getUsedName(dep.names, runtime);

		const [type, base] = handleDependencyBase(
			dep.base,
			module,
			runtimeRequirements
		);

		switch (type) {
			case "expression":
				if (!used) {
					initFragments.push(
						new InitFragment(
							"var __webpack_unused_export__;\n",
							InitFragment.STAGE_CONSTANTS,
							0,
							"__webpack_unused_export__"
						)
					);
					source.replace(
						dep.range[0],
						dep.range[1] - 1,
						"__webpack_unused_export__"
					);
					return;
				}
				source.replace(
					dep.range[0],
					dep.range[1] - 1,
					`${base}${propertyAccess(used)}`
				);
				return;
			case "Object.defineProperty":
				if (!used) {
					initFragments.push(
						new InitFragment(
							"var __webpack_unused_export__;\n",
							InitFragment.STAGE_CONSTANTS,
							0,
							"__webpack_unused_export__"
						)
					);
					source.replace(
						dep.range[0],
						/** @type {Range} */ (dep.valueRange)[0] - 1,
						"__webpack_unused_export__ = ("
					);
					source.replace(
						/** @type {Range} */ (dep.valueRange)[1],
						dep.range[1] - 1,
						")"
					);
					return;
				}
				source.replace(
					dep.range[0],
					/** @type {Range} */ (dep.valueRange)[0] - 1,
					`Object.defineProperty(${base}${propertyAccess(
						used.slice(0, -1)
					)}, ${JSON.stringify(used[used.length - 1])}, (`
				);
				source.replace(
					/** @type {Range} */ (dep.valueRange)[1],
					dep.range[1] - 1,
					"))"
				);
				return;
		}
	}
};

module.exports = CommonJsExportsDependency;