| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204 | /*	MIT License http://www.opensource.org/licenses/mit-license.php	Author Tobias Koppers @sokra*/"use strict";const ContextElementDependency = require("./dependencies/ContextElementDependency");const { join } = require("./util/fs");/** @typedef {import("./Compiler")} Compiler *//** @typedef {import("./ContextModule").ContextModuleOptions} ContextModuleOptions *//** @typedef {import("./util/fs").InputFileSystem} InputFileSystem *//** @typedef {Record<string, string>} NewContentCreateContextMap */const PLUGIN_NAME = "ContextReplacementPlugin";class ContextReplacementPlugin {	/**	 * @param {RegExp} resourceRegExp A regular expression that determines which files will be selected	 * @param {(string | ((context: TODO) => void) | RegExp | boolean)=} newContentResource A new resource to replace the match	 * @param {(boolean | NewContentCreateContextMap | RegExp)=} newContentRecursive If true, all subdirectories are searched for matches	 * @param {RegExp=} newContentRegExp A regular expression that determines which files will be selected	 */	constructor(		resourceRegExp,		newContentResource,		newContentRecursive,		newContentRegExp	) {		this.resourceRegExp = resourceRegExp;		// new webpack.ContextReplacementPlugin(/selector/, (context) => { /* Logic */ });		if (typeof newContentResource === "function") {			this.newContentCallback = newContentResource;		}		// new ContextReplacementPlugin(/selector/, './folder', { './request': './request' });		else if (			typeof newContentResource === "string" &&			typeof newContentRecursive === "object"		) {			this.newContentResource = newContentResource;			/**			 * @param {InputFileSystem} fs input file system			 * @param {(err: null | Error, newContentRecursive: NewContentCreateContextMap) => void} callback callback			 */			this.newContentCreateContextMap = (fs, callback) => {				callback(					null,					/** @type {NewContentCreateContextMap} */ (newContentRecursive)				);			};		}		// new ContextReplacementPlugin(/selector/, './folder', (context) => { /* Logic */ });		else if (			typeof newContentResource === "string" &&			typeof newContentRecursive === "function"		) {			this.newContentResource = newContentResource;			this.newContentCreateContextMap = newContentRecursive;		} else {			// new webpack.ContextReplacementPlugin(/selector/, false, /reg-exp/);			if (typeof newContentResource !== "string") {				newContentRegExp = /** @type {RegExp} */ (newContentRecursive);				newContentRecursive = /** @type {boolean} */ (newContentResource);				newContentResource = undefined;			}			// new webpack.ContextReplacementPlugin(/selector/, /de|fr|hu/);			if (typeof newContentRecursive !== "boolean") {				newContentRegExp = /** @type {RegExp} */ (newContentRecursive);				newContentRecursive = undefined;			}			// new webpack.ContextReplacementPlugin(/selector/, './folder', false, /selector/);			this.newContentResource =				/** @type {string | undefined} */				(newContentResource);			this.newContentRecursive =				/** @type {boolean | undefined} */				(newContentRecursive);			this.newContentRegExp =				/** @type {RegExp | undefined} */				(newContentRegExp);		}	}	/**	 * Apply the plugin	 * @param {Compiler} compiler the compiler instance	 * @returns {void}	 */	apply(compiler) {		const resourceRegExp = this.resourceRegExp;		const newContentCallback = this.newContentCallback;		const newContentResource = this.newContentResource;		const newContentRecursive = this.newContentRecursive;		const newContentRegExp = this.newContentRegExp;		const newContentCreateContextMap = this.newContentCreateContextMap;		compiler.hooks.contextModuleFactory.tap(PLUGIN_NAME, cmf => {			cmf.hooks.beforeResolve.tap(PLUGIN_NAME, result => {				if (!result) return;				if (resourceRegExp.test(result.request)) {					if (newContentResource !== undefined) {						result.request = newContentResource;					}					if (newContentRecursive !== undefined) {						result.recursive = newContentRecursive;					}					if (newContentRegExp !== undefined) {						result.regExp = newContentRegExp;					}					if (typeof newContentCallback === "function") {						newContentCallback(result);					} else {						for (const d of result.dependencies) {							if (d.critical) d.critical = false;						}					}				}				return result;			});			cmf.hooks.afterResolve.tap(PLUGIN_NAME, result => {				if (!result) return;				if (resourceRegExp.test(result.resource)) {					if (newContentResource !== undefined) {						if (							newContentResource.startsWith("/") ||							(newContentResource.length > 1 && newContentResource[1] === ":")						) {							result.resource = newContentResource;						} else {							result.resource = join(								/** @type {InputFileSystem} */								(compiler.inputFileSystem),								result.resource,								newContentResource							);						}					}					if (newContentRecursive !== undefined) {						result.recursive = newContentRecursive;					}					if (newContentRegExp !== undefined) {						result.regExp = newContentRegExp;					}					if (typeof newContentCreateContextMap === "function") {						result.resolveDependencies =							createResolveDependenciesFromContextMap(								newContentCreateContextMap							);					}					if (typeof newContentCallback === "function") {						const origResource = result.resource;						newContentCallback(result);						if (							result.resource !== origResource &&							!result.resource.startsWith("/") &&							(result.resource.length <= 1 || result.resource[1] !== ":")						) {							// When the function changed it to an relative path							result.resource = join(								/** @type {InputFileSystem} */								(compiler.inputFileSystem),								origResource,								result.resource							);						}					} else {						for (const d of result.dependencies) {							if (d.critical) d.critical = false;						}					}				}				return result;			});		});	}}/** * @param {(fs: InputFileSystem, callback: (err: null | Error, map: NewContentCreateContextMap) => void) => void} createContextMap create context map function * @returns {(fs: InputFileSystem, options: ContextModuleOptions, callback: (err: null | Error, dependencies?: ContextElementDependency[]) => void) => void} resolve resolve dependencies from context map function */const createResolveDependenciesFromContextMap =	createContextMap => (fs, options, callback) => {		createContextMap(fs, (err, map) => {			if (err) return callback(err);			const dependencies = Object.keys(map).map(				key =>					new ContextElementDependency(						map[key] + options.resourceQuery + options.resourceFragment,						key,						options.typePrefix,						/** @type {string} */						(options.category),						options.referencedExports					)			);			callback(null, dependencies);		});	};module.exports = ContextReplacementPlugin;
 |