| 
									
										
										
										
											2013-01-31 09:33:11 +08:00
										 |  |  | /* | 
					
						
							|  |  |  | 	MIT License http://www.opensource.org/licenses/mit-license.php
 | 
					
						
							|  |  |  | 	Author Tobias Koppers @sokra | 
					
						
							|  |  |  | */ | 
					
						
							| 
									
										
										
										
											2018-07-30 23:08:51 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-11 01:27:53 +08:00
										 |  |  | "use strict"; | 
					
						
							| 
									
										
										
										
											2014-06-18 04:46:24 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-11 01:27:53 +08:00
										 |  |  | const ContextElementDependency = require("./dependencies/ContextElementDependency"); | 
					
						
							| 
									
										
										
										
											2019-06-11 19:09:42 +08:00
										 |  |  | const { join } = require("./util/fs"); | 
					
						
							| 
									
										
										
										
											2017-03-11 01:27:53 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-17 06:33:17 +08:00
										 |  |  | /** @typedef {import("./Compiler")} Compiler */ | 
					
						
							| 
									
										
										
										
											2025-03-11 08:28:01 +08:00
										 |  |  | /** @typedef {import("./ContextModule").ContextModuleOptions} ContextModuleOptions */ | 
					
						
							| 
									
										
										
										
											2024-03-12 00:33:52 +08:00
										 |  |  | /** @typedef {import("./util/fs").InputFileSystem} InputFileSystem */ | 
					
						
							| 
									
										
										
										
											2023-06-17 06:33:17 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-03-11 08:28:01 +08:00
										 |  |  | /** @typedef {Record<string, string>} NewContentCreateContextMap */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-11 01:27:53 +08:00
										 |  |  | class ContextReplacementPlugin { | 
					
						
							| 
									
										
										
										
											2023-06-17 06:33:17 +08:00
										 |  |  | 	/** | 
					
						
							|  |  |  | 	 * @param {RegExp} resourceRegExp A regular expression that determines which files will be selected | 
					
						
							| 
									
										
										
										
											2025-03-11 08:28:01 +08:00
										 |  |  | 	 * @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 | 
					
						
							| 
									
										
										
										
											2024-08-15 02:38:08 +08:00
										 |  |  | 	 * @param {RegExp=} newContentRegExp A regular expression that determines which files will be selected | 
					
						
							| 
									
										
										
										
											2023-06-17 06:33:17 +08:00
										 |  |  | 	 */ | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 	constructor( | 
					
						
							|  |  |  | 		resourceRegExp, | 
					
						
							|  |  |  | 		newContentResource, | 
					
						
							|  |  |  | 		newContentRecursive, | 
					
						
							|  |  |  | 		newContentRegExp | 
					
						
							|  |  |  | 	) { | 
					
						
							| 
									
										
										
										
											2017-03-11 01:27:53 +08:00
										 |  |  | 		this.resourceRegExp = resourceRegExp; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-03-11 08:28:01 +08:00
										 |  |  | 		// new webpack.ContextReplacementPlugin(/selector/, (context) => { /* Logic */ });
 | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 		if (typeof newContentResource === "function") { | 
					
						
							| 
									
										
										
										
											2017-03-11 01:27:53 +08:00
										 |  |  | 			this.newContentCallback = newContentResource; | 
					
						
							| 
									
										
										
										
											2025-03-11 08:28:01 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		// new ContextReplacementPlugin(/selector/, './folder', { './request': './request' });
 | 
					
						
							|  |  |  | 		else if ( | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 			typeof newContentResource === "string" && | 
					
						
							|  |  |  | 			typeof newContentRecursive === "object" | 
					
						
							|  |  |  | 		) { | 
					
						
							| 
									
										
										
										
											2017-03-11 01:27:53 +08:00
										 |  |  | 			this.newContentResource = newContentResource; | 
					
						
							| 
									
										
										
										
											2025-03-11 08:28:01 +08:00
										 |  |  | 			/** | 
					
						
							|  |  |  | 			 * @param {InputFileSystem} fs input file system | 
					
						
							|  |  |  | 			 * @param {(err: null | Error, newContentRecursive: NewContentCreateContextMap) => void} callback callback | 
					
						
							|  |  |  | 			 */ | 
					
						
							| 
									
										
										
										
											2017-03-11 01:27:53 +08:00
										 |  |  | 			this.newContentCreateContextMap = (fs, callback) => { | 
					
						
							| 
									
										
										
										
											2025-03-11 08:28:01 +08:00
										 |  |  | 				callback( | 
					
						
							|  |  |  | 					null, | 
					
						
							|  |  |  | 					/** @type {NewContentCreateContextMap} */ (newContentRecursive) | 
					
						
							|  |  |  | 				); | 
					
						
							| 
									
										
										
										
											2017-03-11 01:27:53 +08:00
										 |  |  | 			}; | 
					
						
							| 
									
										
										
										
											2025-03-11 08:28:01 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		// new ContextReplacementPlugin(/selector/, './folder', (context) => { /* Logic */ });
 | 
					
						
							|  |  |  | 		else if ( | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 			typeof newContentResource === "string" && | 
					
						
							|  |  |  | 			typeof newContentRecursive === "function" | 
					
						
							|  |  |  | 		) { | 
					
						
							| 
									
										
										
										
											2017-03-11 01:27:53 +08:00
										 |  |  | 			this.newContentResource = newContentResource; | 
					
						
							|  |  |  | 			this.newContentCreateContextMap = newContentRecursive; | 
					
						
							|  |  |  | 		} else { | 
					
						
							| 
									
										
										
										
											2025-03-11 08:28:01 +08:00
										 |  |  | 			// new webpack.ContextReplacementPlugin(/selector/, false, /reg-exp/);
 | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 			if (typeof newContentResource !== "string") { | 
					
						
							| 
									
										
										
										
											2025-03-11 08:28:01 +08:00
										 |  |  | 				newContentRegExp = /** @type {RegExp} */ (newContentRecursive); | 
					
						
							|  |  |  | 				newContentRecursive = /** @type {boolean} */ (newContentResource); | 
					
						
							| 
									
										
										
										
											2017-03-11 01:27:53 +08:00
										 |  |  | 				newContentResource = undefined; | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2025-03-11 08:28:01 +08:00
										 |  |  | 			// new webpack.ContextReplacementPlugin(/selector/, /de|fr|hu/);
 | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 			if (typeof newContentRecursive !== "boolean") { | 
					
						
							| 
									
										
										
										
											2025-03-11 08:28:01 +08:00
										 |  |  | 				newContentRegExp = /** @type {RegExp} */ (newContentRecursive); | 
					
						
							| 
									
										
										
										
											2017-03-11 01:27:53 +08:00
										 |  |  | 				newContentRecursive = undefined; | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2025-03-11 08:28:01 +08:00
										 |  |  | 			// 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); | 
					
						
							| 
									
										
										
										
											2014-10-23 16:58:26 +08:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2014-06-18 04:38:17 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-03-11 01:27:53 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-17 06:33:17 +08:00
										 |  |  | 	/** | 
					
						
							|  |  |  | 	 * Apply the plugin | 
					
						
							|  |  |  | 	 * @param {Compiler} compiler the compiler instance | 
					
						
							|  |  |  | 	 * @returns {void} | 
					
						
							|  |  |  | 	 */ | 
					
						
							| 
									
										
										
										
											2017-03-11 01:27:53 +08:00
										 |  |  | 	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; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 		compiler.hooks.contextModuleFactory.tap("ContextReplacementPlugin", cmf => { | 
					
						
							|  |  |  | 			cmf.hooks.beforeResolve.tap("ContextReplacementPlugin", result => { | 
					
						
							|  |  |  | 				if (!result) return; | 
					
						
							|  |  |  | 				if (resourceRegExp.test(result.request)) { | 
					
						
							| 
									
										
										
										
											2018-08-17 05:49:30 +08:00
										 |  |  | 					if (newContentResource !== undefined) { | 
					
						
							| 
									
										
										
										
											2017-03-11 01:27:53 +08:00
										 |  |  | 						result.request = newContentResource; | 
					
						
							| 
									
										
										
										
											2018-05-29 20:50:40 +08:00
										 |  |  | 					} | 
					
						
							| 
									
										
										
										
											2018-08-17 05:49:30 +08:00
										 |  |  | 					if (newContentRecursive !== undefined) { | 
					
						
							| 
									
										
										
										
											2017-03-11 01:27:53 +08:00
										 |  |  | 						result.recursive = newContentRecursive; | 
					
						
							| 
									
										
										
										
											2018-05-29 20:50:40 +08:00
										 |  |  | 					} | 
					
						
							| 
									
										
										
										
											2018-08-17 05:49:30 +08:00
										 |  |  | 					if (newContentRegExp !== undefined) { | 
					
						
							| 
									
										
										
										
											2017-03-11 01:27:53 +08:00
										 |  |  | 						result.regExp = newContentRegExp; | 
					
						
							| 
									
										
										
										
											2018-05-29 20:50:40 +08:00
										 |  |  | 					} | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 					if (typeof newContentCallback === "function") { | 
					
						
							| 
									
										
										
										
											2017-03-11 01:27:53 +08:00
										 |  |  | 						newContentCallback(result); | 
					
						
							|  |  |  | 					} else { | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 						for (const d of result.dependencies) { | 
					
						
							|  |  |  | 							if (d.critical) d.critical = false; | 
					
						
							| 
									
										
										
										
											2018-01-22 20:52:43 +08:00
										 |  |  | 						} | 
					
						
							| 
									
										
										
										
											2017-03-11 01:27:53 +08:00
										 |  |  | 					} | 
					
						
							| 
									
										
										
										
											2014-10-23 16:58:26 +08:00
										 |  |  | 				} | 
					
						
							| 
									
										
										
										
											2017-12-14 21:38:53 +08:00
										 |  |  | 				return result; | 
					
						
							| 
									
										
										
										
											2017-03-11 01:27:53 +08:00
										 |  |  | 			}); | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 			cmf.hooks.afterResolve.tap("ContextReplacementPlugin", result => { | 
					
						
							|  |  |  | 				if (!result) return; | 
					
						
							|  |  |  | 				if (resourceRegExp.test(result.resource)) { | 
					
						
							| 
									
										
										
										
											2018-08-17 05:49:30 +08:00
										 |  |  | 					if (newContentResource !== undefined) { | 
					
						
							| 
									
										
										
										
											2019-06-11 19:09:42 +08:00
										 |  |  | 						if ( | 
					
						
							|  |  |  | 							newContentResource.startsWith("/") || | 
					
						
							|  |  |  | 							(newContentResource.length > 1 && newContentResource[1] === ":") | 
					
						
							|  |  |  | 						) { | 
					
						
							|  |  |  | 							result.resource = newContentResource; | 
					
						
							|  |  |  | 						} else { | 
					
						
							|  |  |  | 							result.resource = join( | 
					
						
							| 
									
										
										
										
											2024-03-12 00:33:52 +08:00
										 |  |  | 								/** @type {InputFileSystem} */ (compiler.inputFileSystem), | 
					
						
							| 
									
										
										
										
											2019-06-11 19:09:42 +08:00
										 |  |  | 								result.resource, | 
					
						
							|  |  |  | 								newContentResource | 
					
						
							|  |  |  | 							); | 
					
						
							|  |  |  | 						} | 
					
						
							| 
									
										
										
										
											2018-05-29 20:50:40 +08:00
										 |  |  | 					} | 
					
						
							| 
									
										
										
										
											2018-08-17 05:49:30 +08:00
										 |  |  | 					if (newContentRecursive !== undefined) { | 
					
						
							| 
									
										
										
										
											2017-03-11 01:27:53 +08:00
										 |  |  | 						result.recursive = newContentRecursive; | 
					
						
							| 
									
										
										
										
											2018-05-29 20:50:40 +08:00
										 |  |  | 					} | 
					
						
							| 
									
										
										
										
											2018-08-17 05:49:30 +08:00
										 |  |  | 					if (newContentRegExp !== undefined) { | 
					
						
							| 
									
										
										
										
											2017-03-11 01:27:53 +08:00
										 |  |  | 						result.regExp = newContentRegExp; | 
					
						
							| 
									
										
										
										
											2018-05-29 20:50:40 +08:00
										 |  |  | 					} | 
					
						
							|  |  |  | 					if (typeof newContentCreateContextMap === "function") { | 
					
						
							| 
									
										
										
										
											2021-05-11 15:31:46 +08:00
										 |  |  | 						result.resolveDependencies = | 
					
						
							|  |  |  | 							createResolveDependenciesFromContextMap( | 
					
						
							|  |  |  | 								newContentCreateContextMap | 
					
						
							|  |  |  | 							); | 
					
						
							| 
									
										
										
										
											2018-05-29 20:50:40 +08:00
										 |  |  | 					} | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 					if (typeof newContentCallback === "function") { | 
					
						
							| 
									
										
										
										
											2017-03-11 01:27:53 +08:00
										 |  |  | 						const origResource = result.resource; | 
					
						
							|  |  |  | 						newContentCallback(result); | 
					
						
							| 
									
										
										
										
											2019-06-11 19:09:42 +08:00
										 |  |  | 						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( | 
					
						
							| 
									
										
										
										
											2024-03-12 00:33:52 +08:00
										 |  |  | 								/** @type {InputFileSystem} */ (compiler.inputFileSystem), | 
					
						
							| 
									
										
										
										
											2019-06-11 19:09:42 +08:00
										 |  |  | 								origResource, | 
					
						
							|  |  |  | 								result.resource | 
					
						
							|  |  |  | 							); | 
					
						
							| 
									
										
										
										
											2017-03-11 01:27:53 +08:00
										 |  |  | 						} | 
					
						
							|  |  |  | 					} else { | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 						for (const d of result.dependencies) { | 
					
						
							|  |  |  | 							if (d.critical) d.critical = false; | 
					
						
							| 
									
										
										
										
											2018-01-22 20:52:43 +08:00
										 |  |  | 						} | 
					
						
							| 
									
										
										
										
											2014-10-23 16:58:26 +08:00
										 |  |  | 					} | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2017-12-14 21:38:53 +08:00
										 |  |  | 				return result; | 
					
						
							| 
									
										
										
										
											2017-03-11 01:27:53 +08:00
										 |  |  | 			}); | 
					
						
							| 
									
										
										
										
											2013-01-31 09:33:11 +08:00
										 |  |  | 		}); | 
					
						
							| 
									
										
										
										
											2017-03-11 01:27:53 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2016-01-07 02:56:17 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-03-11 08:28:01 +08:00
										 |  |  | /** | 
					
						
							|  |  |  |  * @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) => { | 
					
						
							| 
									
										
										
										
											2017-03-11 01:27:53 +08:00
										 |  |  | 		createContextMap(fs, (err, map) => { | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 			if (err) return callback(err); | 
					
						
							| 
									
										
										
										
											2024-07-31 11:31:11 +08:00
										 |  |  | 			const dependencies = Object.keys(map).map( | 
					
						
							|  |  |  | 				key => | 
					
						
							|  |  |  | 					new ContextElementDependency( | 
					
						
							|  |  |  | 						map[key] + options.resourceQuery + options.resourceFragment, | 
					
						
							|  |  |  | 						key, | 
					
						
							| 
									
										
										
										
											2025-03-11 08:28:01 +08:00
										 |  |  | 						options.typePrefix, | 
					
						
							|  |  |  | 						/** @type {string} */ (options.category), | 
					
						
							| 
									
										
										
										
											2024-07-31 11:31:11 +08:00
										 |  |  | 						options.referencedExports | 
					
						
							|  |  |  | 					) | 
					
						
							|  |  |  | 			); | 
					
						
							| 
									
										
										
										
											2016-01-07 02:56:17 +08:00
										 |  |  | 			callback(null, dependencies); | 
					
						
							|  |  |  | 		}); | 
					
						
							| 
									
										
										
										
											2017-01-11 17:51:58 +08:00
										 |  |  | 	}; | 
					
						
							| 
									
										
										
										
											2017-03-11 01:27:53 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | module.exports = ContextReplacementPlugin; |