| 
									
										
										
										
											2013-03-26 23:54:41 +08:00
										 |  |  | /* | 
					
						
							|  |  |  | 	MIT License http://www.opensource.org/licenses/mit-license.php
 | 
					
						
							|  |  |  | 	Author Tobias Koppers @sokra | 
					
						
							|  |  |  | */ | 
					
						
							| 
									
										
										
										
											2017-04-06 20:46:40 +08:00
										 |  |  | "use strict"; | 
					
						
							| 
									
										
										
										
											2013-03-26 23:54:41 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-06 20:46:40 +08:00
										 |  |  | const path = require("path"); | 
					
						
							|  |  |  | const ConcatSource = require("webpack-sources").ConcatSource; | 
					
						
							|  |  |  | const RawSource = require("webpack-sources").RawSource; | 
					
						
							|  |  |  | const ModuleFilenameHelpers = require("./ModuleFilenameHelpers"); | 
					
						
							|  |  |  | const SourceMapDevToolModuleOptionsPlugin = require("./SourceMapDevToolModuleOptionsPlugin"); | 
					
						
							| 
									
										
										
										
											2017-11-23 17:59:29 +08:00
										 |  |  | const createHash = require("./util/createHash"); | 
					
						
							| 
									
										
										
										
											2017-04-06 20:46:40 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-29 17:19:28 +08:00
										 |  |  | const validateOptions = require("schema-utils"); | 
					
						
							| 
									
										
										
										
											2017-11-11 20:05:55 +08:00
										 |  |  | const schema = require("../schemas/plugins/SourceMapDevToolPlugin.json"); | 
					
						
							| 
									
										
										
										
											2017-10-28 05:23:38 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-06 20:46:40 +08:00
										 |  |  | const basename = (name) => { | 
					
						
							| 
									
										
										
										
											2018-01-12 00:58:39 +08:00
										 |  |  | 	if(!name.includes("/")) return name; | 
					
						
							| 
									
										
										
										
											2017-04-06 20:46:40 +08:00
										 |  |  | 	return name.substr(name.lastIndexOf("/") + 1); | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-08 18:32:05 +08:00
										 |  |  | const getTaskForFile = (file, chunk, options, compilation) => { | 
					
						
							| 
									
										
										
										
											2017-07-17 13:15:42 +08:00
										 |  |  | 	const asset = compilation.assets[file]; | 
					
						
							|  |  |  | 	if(asset.__SourceMapDevToolFile === file && asset.__SourceMapDevToolData) { | 
					
						
							|  |  |  | 		const data = asset.__SourceMapDevToolData; | 
					
						
							|  |  |  | 		for(const cachedFile in data) { | 
					
						
							|  |  |  | 			compilation.assets[cachedFile] = data[cachedFile]; | 
					
						
							|  |  |  | 			if(cachedFile !== file) | 
					
						
							|  |  |  | 				chunk.files.push(cachedFile); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	let source, sourceMap; | 
					
						
							|  |  |  | 	if(asset.sourceAndMap) { | 
					
						
							|  |  |  | 		const sourceAndMap = asset.sourceAndMap(options); | 
					
						
							|  |  |  | 		sourceMap = sourceAndMap.map; | 
					
						
							|  |  |  | 		source = sourceAndMap.source; | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		sourceMap = asset.map(options); | 
					
						
							|  |  |  | 		source = asset.source(); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if(sourceMap) { | 
					
						
							|  |  |  | 		return { | 
					
						
							|  |  |  | 			chunk, | 
					
						
							|  |  |  | 			file, | 
					
						
							|  |  |  | 			asset, | 
					
						
							|  |  |  | 			source, | 
					
						
							| 
									
										
										
										
											2017-07-18 20:28:12 +08:00
										 |  |  | 			sourceMap, | 
					
						
							|  |  |  | 			modules: undefined | 
					
						
							| 
									
										
										
										
											2017-07-17 13:15:42 +08:00
										 |  |  | 		}; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-11-08 18:32:05 +08:00
										 |  |  | }; | 
					
						
							| 
									
										
										
										
											2017-07-17 13:15:42 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-06 20:46:40 +08:00
										 |  |  | class SourceMapDevToolPlugin { | 
					
						
							|  |  |  | 	constructor(options) { | 
					
						
							|  |  |  | 		if(arguments.length > 1) | 
					
						
							|  |  |  | 			throw new Error("SourceMapDevToolPlugin only takes one argument (pass an options object)"); | 
					
						
							| 
									
										
										
										
											2017-10-28 05:23:38 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-11 20:05:55 +08:00
										 |  |  | 		validateOptions(schema, options || {}, "SourceMap DevTool Plugin"); | 
					
						
							| 
									
										
										
										
											2017-10-28 05:23:38 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-06 20:46:40 +08:00
										 |  |  | 		if(!options) options = {}; | 
					
						
							|  |  |  | 		this.sourceMapFilename = options.filename; | 
					
						
							|  |  |  | 		this.sourceMappingURLComment = options.append === false ? false : options.append || "\n//# sourceMappingURL=[url]"; | 
					
						
							| 
									
										
										
										
											2017-10-18 06:48:04 +08:00
										 |  |  | 		this.moduleFilenameTemplate = options.moduleFilenameTemplate || "webpack://[namespace]/[resourcePath]"; | 
					
						
							|  |  |  | 		this.fallbackModuleFilenameTemplate = options.fallbackModuleFilenameTemplate || "webpack://[namespace]/[resourcePath]?[hash]"; | 
					
						
							| 
									
										
										
										
											2017-10-20 04:23:28 +08:00
										 |  |  | 		this.namespace = options.namespace || ""; | 
					
						
							| 
									
										
										
										
											2017-04-06 20:46:40 +08:00
										 |  |  | 		this.options = options; | 
					
						
							| 
									
										
										
										
											2015-02-19 08:11:29 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-04-06 20:46:40 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	apply(compiler) { | 
					
						
							|  |  |  | 		const sourceMapFilename = this.sourceMapFilename; | 
					
						
							|  |  |  | 		const sourceMappingURLComment = this.sourceMappingURLComment; | 
					
						
							|  |  |  | 		const moduleFilenameTemplate = this.moduleFilenameTemplate; | 
					
						
							| 
									
										
										
										
											2017-10-20 04:23:28 +08:00
										 |  |  | 		const namespace = this.namespace; | 
					
						
							| 
									
										
										
										
											2017-04-06 20:46:40 +08:00
										 |  |  | 		const fallbackModuleFilenameTemplate = this.fallbackModuleFilenameTemplate; | 
					
						
							| 
									
										
										
										
											2017-12-01 17:44:22 +08:00
										 |  |  | 		const requestShortener = compiler.requestShortener; | 
					
						
							| 
									
										
										
										
											2017-04-06 20:46:40 +08:00
										 |  |  | 		const options = this.options; | 
					
						
							|  |  |  | 		options.test = options.test || /\.(js|css)($|\?)/i; | 
					
						
							| 
									
										
										
										
											2017-07-17 13:15:42 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		const matchObject = ModuleFilenameHelpers.matchObject.bind(undefined, options); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-06 22:01:25 +08:00
										 |  |  | 		compiler.hooks.compilation.tap("SourceMapDevToolPlugin", (compilation) => { | 
					
						
							| 
									
										
										
										
											2017-04-06 20:46:40 +08:00
										 |  |  | 			new SourceMapDevToolModuleOptionsPlugin(options).apply(compilation); | 
					
						
							| 
									
										
										
										
											2017-07-17 13:15:42 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-03 17:34:54 +08:00
										 |  |  | 			compilation.hooks.afterOptimizeChunkAssets.tap({ | 
					
						
							|  |  |  | 				name: "SourceMapDevToolPlugin", | 
					
						
							|  |  |  | 				context: true | 
					
						
							|  |  |  | 			}, (context, chunks) => { | 
					
						
							| 
									
										
										
										
											2017-07-07 18:51:55 +08:00
										 |  |  | 				const moduleToSourceNameMapping = new Map(); | 
					
						
							| 
									
										
										
										
											2018-01-03 17:34:54 +08:00
										 |  |  | 				const reportProgress = (context && context.reportProgress) ? context.reportProgress : () => {}; | 
					
						
							| 
									
										
										
										
											2017-07-17 13:15:42 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-04 22:41:26 +08:00
										 |  |  | 				const files = []; | 
					
						
							| 
									
										
										
										
											2017-11-08 18:32:05 +08:00
										 |  |  | 				chunks.forEach(chunk => { | 
					
						
							| 
									
										
										
										
											2017-07-18 20:28:12 +08:00
										 |  |  | 					chunk.files.forEach(file => { | 
					
						
							| 
									
										
										
										
											2017-07-17 13:15:42 +08:00
										 |  |  | 						if(matchObject(file)) { | 
					
						
							| 
									
										
										
										
											2018-01-04 22:41:26 +08:00
										 |  |  | 							files.push({ | 
					
						
							|  |  |  | 								file, | 
					
						
							|  |  |  | 								chunk | 
					
						
							|  |  |  | 							}); | 
					
						
							| 
									
										
										
										
											2017-07-07 18:51:55 +08:00
										 |  |  | 						} | 
					
						
							| 
									
										
										
										
											2017-07-18 20:28:12 +08:00
										 |  |  | 					}); | 
					
						
							| 
									
										
										
										
											2017-04-06 20:46:40 +08:00
										 |  |  | 				}); | 
					
						
							| 
									
										
										
										
											2017-07-17 13:15:42 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-04 22:41:26 +08:00
										 |  |  | 				reportProgress(0.0); | 
					
						
							|  |  |  | 				const tasks = []; | 
					
						
							| 
									
										
										
										
											2018-01-05 00:27:55 +08:00
										 |  |  | 				files.forEach(({ | 
					
						
							|  |  |  | 					file, | 
					
						
							|  |  |  | 					chunk | 
					
						
							|  |  |  | 				}, idx) => { | 
					
						
							| 
									
										
										
										
											2018-01-04 22:41:26 +08:00
										 |  |  | 					reportProgress(0.5 * idx / files.length, file, "generate SourceMap"); | 
					
						
							|  |  |  | 					const task = getTaskForFile(file, chunk, options, compilation); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					if(task) { | 
					
						
							|  |  |  | 						const modules = task.sourceMap.sources.map(source => { | 
					
						
							|  |  |  | 							const module = compilation.findModule(source); | 
					
						
							|  |  |  | 							return module || source; | 
					
						
							|  |  |  | 						}); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 						for(let idx = 0; idx < modules.length; idx++) { | 
					
						
							|  |  |  | 							const module = modules[idx]; | 
					
						
							|  |  |  | 							if(!moduleToSourceNameMapping.get(module)) { | 
					
						
							|  |  |  | 								moduleToSourceNameMapping.set(module, ModuleFilenameHelpers.createFilename(module, { | 
					
						
							|  |  |  | 									moduleFilenameTemplate: moduleFilenameTemplate, | 
					
						
							|  |  |  | 									namespace: namespace | 
					
						
							|  |  |  | 								}, requestShortener)); | 
					
						
							|  |  |  | 							} | 
					
						
							|  |  |  | 						} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 						task.modules = modules; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 						tasks.push(task); | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				}); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				reportProgress(0.5, "resolve sources"); | 
					
						
							| 
									
										
										
										
											2017-07-07 18:51:55 +08:00
										 |  |  | 				const usedNamesSet = new Set(moduleToSourceNameMapping.values()); | 
					
						
							|  |  |  | 				const conflictDetectionSet = new Set(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				// all modules in defined order (longest identifier first)
 | 
					
						
							|  |  |  | 				const allModules = Array.from(moduleToSourceNameMapping.keys()).sort((a, b) => { | 
					
						
							|  |  |  | 					const ai = typeof a === "string" ? a : a.identifier(); | 
					
						
							|  |  |  | 					const bi = typeof b === "string" ? b : b.identifier(); | 
					
						
							|  |  |  | 					return ai.length - bi.length; | 
					
						
							| 
									
										
										
										
											2017-04-06 20:46:40 +08:00
										 |  |  | 				}); | 
					
						
							| 
									
										
										
										
											2017-07-07 18:51:55 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 				// find modules with conflicting source names
 | 
					
						
							| 
									
										
										
										
											2017-08-29 20:52:09 +08:00
										 |  |  | 				for(let idx = 0; idx < allModules.length; idx++) { | 
					
						
							|  |  |  | 					const module = allModules[idx]; | 
					
						
							| 
									
										
										
										
											2017-07-07 18:51:55 +08:00
										 |  |  | 					let sourceName = moduleToSourceNameMapping.get(module); | 
					
						
							|  |  |  | 					let hasName = conflictDetectionSet.has(sourceName); | 
					
						
							|  |  |  | 					if(!hasName) { | 
					
						
							|  |  |  | 						conflictDetectionSet.add(sourceName); | 
					
						
							|  |  |  | 						continue; | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					// try the fallback name first
 | 
					
						
							| 
									
										
										
										
											2017-10-19 06:24:59 +08:00
										 |  |  | 					sourceName = ModuleFilenameHelpers.createFilename(module, { | 
					
						
							|  |  |  | 						moduleFilenameTemplate: fallbackModuleFilenameTemplate, | 
					
						
							|  |  |  | 						namespace: namespace | 
					
						
							|  |  |  | 					}, requestShortener); | 
					
						
							| 
									
										
										
										
											2017-07-07 18:51:55 +08:00
										 |  |  | 					hasName = usedNamesSet.has(sourceName); | 
					
						
							|  |  |  | 					if(!hasName) { | 
					
						
							|  |  |  | 						moduleToSourceNameMapping.set(module, sourceName); | 
					
						
							|  |  |  | 						usedNamesSet.add(sourceName); | 
					
						
							|  |  |  | 						continue; | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					// elsewise just append stars until we have a valid name
 | 
					
						
							| 
									
										
										
										
											2017-07-08 18:25:52 +08:00
										 |  |  | 					while(hasName) { | 
					
						
							| 
									
										
										
										
											2017-07-07 18:51:55 +08:00
										 |  |  | 						sourceName += "*"; | 
					
						
							|  |  |  | 						hasName = usedNamesSet.has(sourceName); | 
					
						
							| 
									
										
										
										
											2017-07-08 18:25:52 +08:00
										 |  |  | 					} | 
					
						
							| 
									
										
										
										
											2017-07-07 18:51:55 +08:00
										 |  |  | 					moduleToSourceNameMapping.set(module, sourceName); | 
					
						
							|  |  |  | 					usedNamesSet.add(sourceName); | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2018-01-03 17:34:54 +08:00
										 |  |  | 				tasks.forEach((task, index) => { | 
					
						
							| 
									
										
										
										
											2018-01-04 22:41:26 +08:00
										 |  |  | 					reportProgress(0.5 + 0.5 * index / tasks.length, task.file, "attach SourceMap"); | 
					
						
							| 
									
										
										
										
											2017-04-06 20:46:40 +08:00
										 |  |  | 					const chunk = task.chunk; | 
					
						
							|  |  |  | 					const file = task.file; | 
					
						
							|  |  |  | 					const asset = task.asset; | 
					
						
							|  |  |  | 					const sourceMap = task.sourceMap; | 
					
						
							|  |  |  | 					const source = task.source; | 
					
						
							|  |  |  | 					const modules = task.modules; | 
					
						
							| 
									
										
										
										
											2017-07-07 18:51:55 +08:00
										 |  |  | 					const moduleFilenames = modules.map(m => moduleToSourceNameMapping.get(m)); | 
					
						
							| 
									
										
										
										
											2017-04-06 20:46:40 +08:00
										 |  |  | 					sourceMap.sources = moduleFilenames; | 
					
						
							|  |  |  | 					if(sourceMap.sourcesContent && !options.noSources) { | 
					
						
							| 
									
										
										
										
											2017-10-29 07:19:42 +08:00
										 |  |  | 						sourceMap.sourcesContent = sourceMap.sourcesContent.map((content, i) => typeof content === "string" ? `${content}\n\n\n${ModuleFilenameHelpers.createFooter(modules[i], requestShortener)}` : null); | 
					
						
							| 
									
										
										
										
											2015-04-03 18:38:56 +08:00
										 |  |  | 					} else { | 
					
						
							| 
									
										
										
										
											2017-04-06 20:46:40 +08:00
										 |  |  | 						sourceMap.sourcesContent = undefined; | 
					
						
							| 
									
										
										
										
											2015-04-03 18:38:56 +08:00
										 |  |  | 					} | 
					
						
							| 
									
										
										
										
											2017-04-06 20:46:40 +08:00
										 |  |  | 					sourceMap.sourceRoot = options.sourceRoot || ""; | 
					
						
							|  |  |  | 					sourceMap.file = file; | 
					
						
							|  |  |  | 					asset.__SourceMapDevToolFile = file; | 
					
						
							|  |  |  | 					asset.__SourceMapDevToolData = {}; | 
					
						
							|  |  |  | 					let currentSourceMappingURLComment = sourceMappingURLComment; | 
					
						
							|  |  |  | 					if(currentSourceMappingURLComment !== false && /\.css($|\?)/i.test(file)) { | 
					
						
							|  |  |  | 						currentSourceMappingURLComment = currentSourceMappingURLComment.replace(/^\n\/\/(.*)$/, "\n/*$1*/"); | 
					
						
							| 
									
										
										
										
											2014-07-26 23:54:00 +08:00
										 |  |  | 					} | 
					
						
							| 
									
										
										
										
											2017-06-05 14:49:09 +08:00
										 |  |  | 					const sourceMapString = JSON.stringify(sourceMap); | 
					
						
							| 
									
										
										
										
											2017-04-06 20:46:40 +08:00
										 |  |  | 					if(sourceMapFilename) { | 
					
						
							|  |  |  | 						let filename = file; | 
					
						
							|  |  |  | 						let query = ""; | 
					
						
							|  |  |  | 						const idx = filename.indexOf("?"); | 
					
						
							|  |  |  | 						if(idx >= 0) { | 
					
						
							|  |  |  | 							query = filename.substr(idx); | 
					
						
							|  |  |  | 							filename = filename.substr(0, idx); | 
					
						
							|  |  |  | 						} | 
					
						
							| 
									
										
										
										
											2017-06-05 14:49:09 +08:00
										 |  |  | 						let sourceMapFile = compilation.getPath(sourceMapFilename, { | 
					
						
							| 
									
										
										
										
											2017-04-06 20:46:40 +08:00
										 |  |  | 							chunk, | 
					
						
							| 
									
										
										
										
											2017-11-25 22:38:30 +08:00
										 |  |  | 							filename: options.fileContext ? path.relative(options.fileContext, filename) : filename, | 
					
						
							| 
									
										
										
										
											2017-04-06 20:46:40 +08:00
										 |  |  | 							query, | 
					
						
							|  |  |  | 							basename: basename(filename) | 
					
						
							|  |  |  | 						}); | 
					
						
							| 
									
										
										
										
											2018-01-12 00:58:39 +08:00
										 |  |  | 						if(sourceMapFile.includes("[contenthash]")) { | 
					
						
							| 
									
										
										
										
											2017-11-23 17:59:29 +08:00
										 |  |  | 							sourceMapFile = sourceMapFile.replace(/\[contenthash\]/g, createHash("md5").update(sourceMapString).digest("hex")); | 
					
						
							| 
									
										
										
										
											2017-06-03 00:05:25 +08:00
										 |  |  | 						} | 
					
						
							| 
									
										
										
										
											2017-11-27 14:53:38 +08:00
										 |  |  | 						const sourceMapUrl = options.publicPath ? options.publicPath + sourceMapFile.replace(/\\/g, "/") : path.relative(path.dirname(file), sourceMapFile).replace(/\\/g, "/"); | 
					
						
							| 
									
										
										
										
											2017-04-06 20:46:40 +08:00
										 |  |  | 						if(currentSourceMappingURLComment !== false) { | 
					
						
							|  |  |  | 							asset.__SourceMapDevToolData[file] = compilation.assets[file] = new ConcatSource(new RawSource(source), currentSourceMappingURLComment.replace(/\[url\]/g, sourceMapUrl)); | 
					
						
							|  |  |  | 						} | 
					
						
							| 
									
										
										
										
											2017-06-05 14:49:09 +08:00
										 |  |  | 						asset.__SourceMapDevToolData[sourceMapFile] = compilation.assets[sourceMapFile] = new RawSource(sourceMapString); | 
					
						
							| 
									
										
										
										
											2017-04-06 20:46:40 +08:00
										 |  |  | 						chunk.files.push(sourceMapFile); | 
					
						
							|  |  |  | 					} else { | 
					
						
							|  |  |  | 						asset.__SourceMapDevToolData[file] = compilation.assets[file] = new ConcatSource(new RawSource(source), currentSourceMappingURLComment | 
					
						
							| 
									
										
										
										
											2017-06-05 14:49:09 +08:00
										 |  |  | 							.replace(/\[map\]/g, () => sourceMapString) | 
					
						
							| 
									
										
										
										
											2018-01-22 22:00:12 +08:00
										 |  |  | 							.replace(/\[url\]/g, () => `data:application/json;charset=utf-8;base64,${Buffer.from(sourceMapString, "utf-8").toString("base64")}`) | 
					
						
							| 
									
										
										
										
											2017-04-06 20:46:40 +08:00
										 |  |  | 						); | 
					
						
							| 
									
										
										
										
											2014-08-28 21:13:05 +08:00
										 |  |  | 					} | 
					
						
							| 
									
										
										
										
											2017-04-06 20:46:40 +08:00
										 |  |  | 				}); | 
					
						
							| 
									
										
										
										
											2018-01-04 22:41:26 +08:00
										 |  |  | 				reportProgress(1.0); | 
					
						
							| 
									
										
										
										
											2017-04-06 20:46:40 +08:00
										 |  |  | 			}); | 
					
						
							| 
									
										
										
										
											2013-03-26 23:54:41 +08:00
										 |  |  | 		}); | 
					
						
							| 
									
										
										
										
											2017-04-06 20:46:40 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-06-17 22:35:31 +08:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2017-04-06 20:46:40 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | module.exports = SourceMapDevToolPlugin; |