| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152 | /*	MIT License http://www.opensource.org/licenses/mit-license.php	Author Tobias Koppers @sokra*/"use strict";const ConstDependency = require("./dependencies/ConstDependency");/** @typedef {import("./Compiler")} Compiler *//** @typedef {import("./javascript/JavascriptParser")} JavascriptParser */const nestedWebpackRequireTag = Symbol("nested __webpack_require__");class CompatibilityPlugin {	/**	 * Apply the plugin	 * @param {Compiler} compiler the compiler instance	 * @returns {void}	 */	apply(compiler) {		compiler.hooks.compilation.tap(			"CompatibilityPlugin",			(compilation, { normalModuleFactory }) => {				compilation.dependencyTemplates.set(					ConstDependency,					new ConstDependency.Template()				);				normalModuleFactory.hooks.parser					.for("javascript/auto")					.tap("CompatibilityPlugin", (parser, parserOptions) => {						if (							parserOptions.browserify !== undefined &&							!parserOptions.browserify						)							return;						parser.hooks.call							.for("require")							.tap("CompatibilityPlugin", expr => {								// support for browserify style require delegator: "require(o, !0)"								if (expr.arguments.length !== 2) return;								const second = parser.evaluateExpression(expr.arguments[1]);								if (!second.isBoolean()) return;								if (second.asBool() !== true) return;								const dep = new ConstDependency("require", expr.callee.range);								dep.loc = expr.loc;								if (parser.state.current.dependencies.length > 0) {									const last =										parser.state.current.dependencies[											parser.state.current.dependencies.length - 1										];									if (										last.critical &&										last.options &&										last.options.request === "." &&										last.userRequest === "." &&										last.options.recursive									)										parser.state.current.dependencies.pop();								}								parser.state.module.addPresentationalDependency(dep);								return true;							});					});				/**				 * @param {JavascriptParser} parser the parser				 * @returns {void}				 */				const handler = parser => {					// Handle nested requires					parser.hooks.preStatement.tap("CompatibilityPlugin", statement => {						if (							statement.type === "FunctionDeclaration" &&							statement.id &&							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								}							});							return true;						}					});					parser.hooks.pattern						.for("__webpack_require__")						.tap("CompatibilityPlugin", pattern => {							const newName = `__nested_webpack_require_${pattern.range[0]}__`;							parser.tagVariable(pattern.name, nestedWebpackRequireTag, {								name: newName,								declaration: {									updated: false,									loc: pattern.loc,									range: pattern.range								}							});							return true;						});					parser.hooks.expression						.for(nestedWebpackRequireTag)						.tap("CompatibilityPlugin", expr => {							const { name, declaration } = parser.currentTagData;							if (!declaration.updated) {								const dep = new ConstDependency(name, declaration.range);								dep.loc = declaration.loc;								parser.state.module.addPresentationalDependency(dep);								declaration.updated = true;							}							const dep = new ConstDependency(name, expr.range);							dep.loc = expr.loc;							parser.state.module.addPresentationalDependency(dep);							return true;						});					// Handle hashbang					parser.hooks.program.tap(						"CompatibilityPlugin",						(program, comments) => {							if (comments.length === 0) return;							const c = comments[0];							if (c.type === "Line" && c.range[0] === 0) {								if (parser.state.source.slice(0, 2).toString() !== "#!") return;								// this is a hashbang comment								const dep = new ConstDependency("//", 0);								dep.loc = c.loc;								parser.state.module.addPresentationalDependency(dep);							}						}					);				};				normalModuleFactory.hooks.parser					.for("javascript/auto")					.tap("CompatibilityPlugin", handler);				normalModuleFactory.hooks.parser					.for("javascript/dynamic")					.tap("CompatibilityPlugin", handler);				normalModuleFactory.hooks.parser					.for("javascript/esm")					.tap("CompatibilityPlugin", handler);			}		);	}}module.exports = CompatibilityPlugin;
 |