UNPKG

webpack

Version:

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.

218 lines (203 loc) 7.24 kB
/* 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 = /** @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;