You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
	
	
		
			218 lines
		
	
	
		
			7.1 KiB
		
	
	
	
		
			JavaScript
		
	
		
		
			
		
	
	
			218 lines
		
	
	
		
			7.1 KiB
		
	
	
	
		
			JavaScript
		
	
| 
											9 months ago
										 | /* | ||
|  | 	MIT License http://www.opensource.org/licenses/mit-license.php
 | ||
|  | 	Author Tobias Koppers @sokra | ||
|  | */ | ||
|  | 
 | ||
|  | "use strict"; | ||
|  | 
 | ||
|  | const { ConcatSource, RawSource } = require("webpack-sources"); | ||
|  | const ModuleFilenameHelpers = require("./ModuleFilenameHelpers"); | ||
|  | const NormalModule = require("./NormalModule"); | ||
|  | const RuntimeGlobals = require("./RuntimeGlobals"); | ||
|  | const SourceMapDevToolModuleOptionsPlugin = require("./SourceMapDevToolModuleOptionsPlugin"); | ||
|  | const JavascriptModulesPlugin = require("./javascript/JavascriptModulesPlugin"); | ||
|  | const ConcatenatedModule = require("./optimize/ConcatenatedModule"); | ||
|  | const { makePathsAbsolute } = require("./util/identifier"); | ||
|  | 
 | ||
|  | /** @typedef {import("webpack-sources").Source} Source */ | ||
|  | /** @typedef {import("../declarations/WebpackOptions").DevTool} DevToolOptions */ | ||
|  | /** @typedef {import("../declarations/plugins/SourceMapDevToolPlugin").SourceMapDevToolPluginOptions} SourceMapDevToolPluginOptions */ | ||
|  | /** @typedef {import("./Compiler")} Compiler */ | ||
|  | /** @typedef {import("./NormalModule").SourceMap} SourceMap */ | ||
|  | 
 | ||
|  | /** @type {WeakMap<Source, Source>} */ | ||
|  | const cache = new WeakMap(); | ||
|  | 
 | ||
|  | const devtoolWarning = new RawSource(`/*
 | ||
|  |  * ATTENTION: An "eval-source-map" devtool has been used. | ||
|  |  * This devtool is neither made for production nor for readable output files. | ||
|  |  * It uses "eval()" calls to create a separate source file with attached SourceMaps in the browser devtools. | ||
|  |  * If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/)
 | ||
|  |  * or disable the default devtool with "devtool: false". | ||
|  |  * If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/).
 | ||
|  |  */ | ||
|  | `);
 | ||
|  | 
 | ||
|  | class EvalSourceMapDevToolPlugin { | ||
|  | 	/** | ||
|  | 	 * @param {SourceMapDevToolPluginOptions|string} inputOptions Options object | ||
|  | 	 */ | ||
|  | 	constructor(inputOptions) { | ||
|  | 		/** @type {SourceMapDevToolPluginOptions} */ | ||
|  | 		let options; | ||
|  | 		if (typeof inputOptions === "string") { | ||
|  | 			options = { | ||
|  | 				append: inputOptions | ||
|  | 			}; | ||
|  | 		} else { | ||
|  | 			options = inputOptions; | ||
|  | 		} | ||
|  | 		this.sourceMapComment = | ||
|  | 			options.append && typeof options.append !== "function" | ||
|  | 				? options.append | ||
|  | 				: "//# sourceURL=[module]\n//# sourceMappingURL=[url]"; | ||
|  | 		this.moduleFilenameTemplate = | ||
|  | 			options.moduleFilenameTemplate || | ||
|  | 			"webpack://[namespace]/[resource-path]?[hash]"; | ||
|  | 		this.namespace = options.namespace || ""; | ||
|  | 		this.options = options; | ||
|  | 	} | ||
|  | 
 | ||
|  | 	/** | ||
|  | 	 * Apply the plugin | ||
|  | 	 * @param {Compiler} compiler the compiler instance | ||
|  | 	 * @returns {void} | ||
|  | 	 */ | ||
|  | 	apply(compiler) { | ||
|  | 		const options = this.options; | ||
|  | 		compiler.hooks.compilation.tap( | ||
|  | 			"EvalSourceMapDevToolPlugin", | ||
|  | 			compilation => { | ||
|  | 				const hooks = JavascriptModulesPlugin.getCompilationHooks(compilation); | ||
|  | 				new SourceMapDevToolModuleOptionsPlugin(options).apply(compilation); | ||
|  | 				const matchModule = ModuleFilenameHelpers.matchObject.bind( | ||
|  | 					ModuleFilenameHelpers, | ||
|  | 					options | ||
|  | 				); | ||
|  | 				hooks.renderModuleContent.tap( | ||
|  | 					"EvalSourceMapDevToolPlugin", | ||
|  | 					(source, m, { runtimeTemplate, chunkGraph }) => { | ||
|  | 						const cachedSource = cache.get(source); | ||
|  | 						if (cachedSource !== undefined) { | ||
|  | 							return cachedSource; | ||
|  | 						} | ||
|  | 
 | ||
|  | 						/** | ||
|  | 						 * @param {Source} r result | ||
|  | 						 * @returns {Source} result | ||
|  | 						 */ | ||
|  | 						const result = r => { | ||
|  | 							cache.set(source, r); | ||
|  | 							return r; | ||
|  | 						}; | ||
|  | 
 | ||
|  | 						if (m instanceof NormalModule) { | ||
|  | 							const module = /** @type {NormalModule} */ (m); | ||
|  | 							if (!matchModule(module.resource)) { | ||
|  | 								return result(source); | ||
|  | 							} | ||
|  | 						} else if (m instanceof ConcatenatedModule) { | ||
|  | 							const concatModule = /** @type {ConcatenatedModule} */ (m); | ||
|  | 							if (concatModule.rootModule instanceof NormalModule) { | ||
|  | 								const module = /** @type {NormalModule} */ ( | ||
|  | 									concatModule.rootModule | ||
|  | 								); | ||
|  | 								if (!matchModule(module.resource)) { | ||
|  | 									return result(source); | ||
|  | 								} | ||
|  | 							} else { | ||
|  | 								return result(source); | ||
|  | 							} | ||
|  | 						} else { | ||
|  | 							return result(source); | ||
|  | 						} | ||
|  | 
 | ||
|  | 						/** @type {SourceMap} */ | ||
|  | 						let sourceMap; | ||
|  | 						let content; | ||
|  | 						if (source.sourceAndMap) { | ||
|  | 							const sourceAndMap = source.sourceAndMap(options); | ||
|  | 							sourceMap = /** @type {SourceMap} */ (sourceAndMap.map); | ||
|  | 							content = sourceAndMap.source; | ||
|  | 						} else { | ||
|  | 							sourceMap = /** @type {SourceMap} */ (source.map(options)); | ||
|  | 							content = source.source(); | ||
|  | 						} | ||
|  | 						if (!sourceMap) { | ||
|  | 							return result(source); | ||
|  | 						} | ||
|  | 
 | ||
|  | 						// Clone (flat) the sourcemap to ensure that the mutations below do not persist.
 | ||
|  | 						sourceMap = { ...sourceMap }; | ||
|  | 						const context = compiler.options.context; | ||
|  | 						const root = compiler.root; | ||
|  | 						const modules = sourceMap.sources.map(source => { | ||
|  | 							if (!source.startsWith("webpack://")) return source; | ||
|  | 							source = makePathsAbsolute(context, source.slice(10), root); | ||
|  | 							const module = compilation.findModule(source); | ||
|  | 							return module || source; | ||
|  | 						}); | ||
|  | 						let moduleFilenames = modules.map(module => { | ||
|  | 							return ModuleFilenameHelpers.createFilename( | ||
|  | 								module, | ||
|  | 								{ | ||
|  | 									moduleFilenameTemplate: this.moduleFilenameTemplate, | ||
|  | 									namespace: this.namespace | ||
|  | 								}, | ||
|  | 								{ | ||
|  | 									requestShortener: runtimeTemplate.requestShortener, | ||
|  | 									chunkGraph, | ||
|  | 									hashFunction: compilation.outputOptions.hashFunction | ||
|  | 								} | ||
|  | 							); | ||
|  | 						}); | ||
|  | 						moduleFilenames = ModuleFilenameHelpers.replaceDuplicates( | ||
|  | 							moduleFilenames, | ||
|  | 							(filename, i, n) => { | ||
|  | 								for (let j = 0; j < n; j++) filename += "*"; | ||
|  | 								return filename; | ||
|  | 							} | ||
|  | 						); | ||
|  | 						sourceMap.sources = moduleFilenames; | ||
|  | 						if (options.noSources) { | ||
|  | 							sourceMap.sourcesContent = undefined; | ||
|  | 						} | ||
|  | 						sourceMap.sourceRoot = options.sourceRoot || ""; | ||
|  | 						const moduleId = chunkGraph.getModuleId(m); | ||
|  | 						sourceMap.file = | ||
|  | 							typeof moduleId === "number" ? `${moduleId}.js` : moduleId; | ||
|  | 
 | ||
|  | 						const footer = | ||
|  | 							this.sourceMapComment.replace( | ||
|  | 								/\[url\]/g, | ||
|  | 								`data:application/json;charset=utf-8;base64,${Buffer.from( | ||
|  | 									JSON.stringify(sourceMap), | ||
|  | 									"utf8" | ||
|  | 								).toString("base64")}`
 | ||
|  | 							) + `\n//# sourceURL=webpack-internal:///${moduleId}\n`; // workaround for chrome bug
 | ||
|  | 
 | ||
|  | 						return result( | ||
|  | 							new RawSource( | ||
|  | 								`eval(${ | ||
|  | 									compilation.outputOptions.trustedTypes | ||
|  | 										? `${RuntimeGlobals.createScript}(${JSON.stringify( | ||
|  | 												content + footer | ||
|  | 										  )})`
 | ||
|  | 										: JSON.stringify(content + footer) | ||
|  | 								});`
 | ||
|  | 							) | ||
|  | 						); | ||
|  | 					} | ||
|  | 				); | ||
|  | 				hooks.inlineInRuntimeBailout.tap( | ||
|  | 					"EvalDevToolModulePlugin", | ||
|  | 					() => "the eval-source-map devtool is used." | ||
|  | 				); | ||
|  | 				hooks.render.tap( | ||
|  | 					"EvalSourceMapDevToolPlugin", | ||
|  | 					source => new ConcatSource(devtoolWarning, source) | ||
|  | 				); | ||
|  | 				hooks.chunkHash.tap("EvalSourceMapDevToolPlugin", (chunk, hash) => { | ||
|  | 					hash.update("EvalSourceMapDevToolPlugin"); | ||
|  | 					hash.update("2"); | ||
|  | 				}); | ||
|  | 				if (compilation.outputOptions.trustedTypes) { | ||
|  | 					compilation.hooks.additionalModuleRuntimeRequirements.tap( | ||
|  | 						"EvalSourceMapDevToolPlugin", | ||
|  | 						(module, set, context) => { | ||
|  | 							set.add(RuntimeGlobals.createScript); | ||
|  | 						} | ||
|  | 					); | ||
|  | 				} | ||
|  | 			} | ||
|  | 		); | ||
|  | 	} | ||
|  | } | ||
|  | 
 | ||
|  | module.exports = EvalSourceMapDevToolPlugin; |