All Downloads are FREE. Search and download functionalities are using the official Maven repository.

package.lib.EvalSourceMapDevToolPlugin.js Maven / Gradle / Ivy

Go to download

Packs ECMAScript/CommonJs/AMD modules for the browser. Allows you to split your codebase into multiple bundles, which can be loaded on demand. Supports loaders to preprocess files, i.e. json, jsx, es7, css, less, ... and your custom stuff.

The newest version!
/*
	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} */
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 = /** @type {string} */ (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;




© 2015 - 2024 Weber Informatics LLC | Privacy Policy