diff options
author | Florian Dold <florian.dold@gmail.com> | 2018-09-20 02:56:13 +0200 |
---|---|---|
committer | Florian Dold <florian.dold@gmail.com> | 2018-09-20 02:56:13 +0200 |
commit | bbff7403fbf46f9ad92240ac213df8d30ef31b64 (patch) | |
tree | c58400ec5124da1c7d56b01aea83309f80a56c3b /node_modules/webpack/lib/SourceMapDevToolPlugin.js | |
parent | 003fb34971cf63466184351b4db5f7c67df4f444 (diff) |
update packages
Diffstat (limited to 'node_modules/webpack/lib/SourceMapDevToolPlugin.js')
-rw-r--r-- | node_modules/webpack/lib/SourceMapDevToolPlugin.js | 510 |
1 files changed, 301 insertions, 209 deletions
diff --git a/node_modules/webpack/lib/SourceMapDevToolPlugin.js b/node_modules/webpack/lib/SourceMapDevToolPlugin.js index e63f34afb..315a9c22c 100644 --- a/node_modules/webpack/lib/SourceMapDevToolPlugin.js +++ b/node_modules/webpack/lib/SourceMapDevToolPlugin.js @@ -1,209 +1,301 @@ -/*
- MIT License http://www.opensource.org/licenses/mit-license.php
- Author Tobias Koppers @sokra
-*/
-"use strict";
-
-const path = require("path");
-const crypto = require("crypto");
-const RequestShortener = require("./RequestShortener");
-const ConcatSource = require("webpack-sources").ConcatSource;
-const RawSource = require("webpack-sources").RawSource;
-const ModuleFilenameHelpers = require("./ModuleFilenameHelpers");
-const SourceMapDevToolModuleOptionsPlugin = require("./SourceMapDevToolModuleOptionsPlugin");
-
-const basename = (name) => {
- if(name.indexOf("/") < 0) return name;
- return name.substr(name.lastIndexOf("/") + 1);
-};
-
-function getTaskForFile(file, chunk, options, compilation) {
- 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,
- sourceMap,
- modules: undefined
- };
- }
-}
-
-class SourceMapDevToolPlugin {
- constructor(options) {
- if(arguments.length > 1)
- throw new Error("SourceMapDevToolPlugin only takes one argument (pass an options object)");
- // TODO: remove in webpack 3
- if(typeof options === "string") {
- options = {
- sourceMapFilename: options
- };
- }
- if(!options) options = {};
- this.sourceMapFilename = options.filename;
- this.sourceMappingURLComment = options.append === false ? false : options.append || "\n//# sourceMappingURL=[url]";
- this.moduleFilenameTemplate = options.moduleFilenameTemplate || "webpack:///[resourcePath]";
- this.fallbackModuleFilenameTemplate = options.fallbackModuleFilenameTemplate || "webpack:///[resourcePath]?[hash]";
- this.options = options;
- }
-
- apply(compiler) {
- const sourceMapFilename = this.sourceMapFilename;
- const sourceMappingURLComment = this.sourceMappingURLComment;
- const moduleFilenameTemplate = this.moduleFilenameTemplate;
- const fallbackModuleFilenameTemplate = this.fallbackModuleFilenameTemplate;
- const requestShortener = new RequestShortener(compiler.context);
- const options = this.options;
- options.test = options.test || /\.(js|css)($|\?)/i;
-
- const matchObject = ModuleFilenameHelpers.matchObject.bind(undefined, options);
-
- compiler.plugin("compilation", compilation => {
- new SourceMapDevToolModuleOptionsPlugin(options).apply(compilation);
-
- compilation.plugin("after-optimize-chunk-assets", function(chunks) {
- const moduleToSourceNameMapping = new Map();
- const tasks = [];
-
- chunks.forEach(function(chunk) {
- chunk.files.forEach(file => {
- if(matchObject(file)) {
- 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, requestShortener));
- }
- }
-
- task.modules = modules;
-
- tasks.push(task);
- }
- }
- });
- });
-
- 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;
- });
-
- // find modules with conflicting source names
- for(let idx = 0; idx < allModules.length; idx++) {
- const module = allModules[idx];
- let sourceName = moduleToSourceNameMapping.get(module);
- let hasName = conflictDetectionSet.has(sourceName);
- if(!hasName) {
- conflictDetectionSet.add(sourceName);
- continue;
- }
-
- // try the fallback name first
- sourceName = ModuleFilenameHelpers.createFilename(module, fallbackModuleFilenameTemplate, requestShortener);
- hasName = usedNamesSet.has(sourceName);
- if(!hasName) {
- moduleToSourceNameMapping.set(module, sourceName);
- usedNamesSet.add(sourceName);
- continue;
- }
-
- // elsewise just append stars until we have a valid name
- while(hasName) {
- sourceName += "*";
- hasName = usedNamesSet.has(sourceName);
- }
- moduleToSourceNameMapping.set(module, sourceName);
- usedNamesSet.add(sourceName);
- }
- tasks.forEach(function(task) {
- const chunk = task.chunk;
- const file = task.file;
- const asset = task.asset;
- const sourceMap = task.sourceMap;
- const source = task.source;
- const modules = task.modules;
- const moduleFilenames = modules.map(m => moduleToSourceNameMapping.get(m));
- sourceMap.sources = moduleFilenames;
- if(sourceMap.sourcesContent && !options.noSources) {
- sourceMap.sourcesContent = sourceMap.sourcesContent.map((content, i) => typeof content === "string" ? `${content}\n\n\n${ModuleFilenameHelpers.createFooter(modules[i], requestShortener)}` : null);
- } else {
- sourceMap.sourcesContent = undefined;
- }
- 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*/");
- }
- const sourceMapString = JSON.stringify(sourceMap);
- if(sourceMapFilename) {
- let filename = file;
- let query = "";
- const idx = filename.indexOf("?");
- if(idx >= 0) {
- query = filename.substr(idx);
- filename = filename.substr(0, idx);
- }
- let sourceMapFile = compilation.getPath(sourceMapFilename, {
- chunk,
- filename: options.fileContext ? path.relative(options.fileContext, filename) : filename,
- query,
- basename: basename(filename)
- });
- if(sourceMapFile.indexOf("[contenthash]") !== -1) {
- sourceMapFile = sourceMapFile.replace(/\[contenthash\]/g, crypto.createHash("md5").update(sourceMapString).digest("hex"));
- }
- const sourceMapUrl = options.publicPath ? options.publicPath + sourceMapFile.replace(/\\/g, "/") : path.relative(path.dirname(file), sourceMapFile).replace(/\\/g, "/");
- if(currentSourceMappingURLComment !== false) {
- asset.__SourceMapDevToolData[file] = compilation.assets[file] = new ConcatSource(new RawSource(source), currentSourceMappingURLComment.replace(/\[url\]/g, sourceMapUrl));
- }
- asset.__SourceMapDevToolData[sourceMapFile] = compilation.assets[sourceMapFile] = new RawSource(sourceMapString);
- chunk.files.push(sourceMapFile);
- } else {
- asset.__SourceMapDevToolData[file] = compilation.assets[file] = new ConcatSource(new RawSource(source), currentSourceMappingURLComment
- .replace(/\[map\]/g, () => sourceMapString)
- .replace(/\[url\]/g, () => `data:application/json;charset=utf-8;base64,${new Buffer(sourceMapString, "utf-8").toString("base64")}`) // eslint-disable-line
- );
- }
- });
- });
- });
- }
-}
-
-module.exports = SourceMapDevToolPlugin;
+/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ +"use strict"; + +const path = require("path"); +const { ConcatSource, RawSource } = require("webpack-sources"); +const ModuleFilenameHelpers = require("./ModuleFilenameHelpers"); +const SourceMapDevToolModuleOptionsPlugin = require("./SourceMapDevToolModuleOptionsPlugin"); +const createHash = require("./util/createHash"); + +const validateOptions = require("schema-utils"); +const schema = require("../schemas/plugins/SourceMapDevToolPlugin.json"); + +const basename = name => { + if (!name.includes("/")) return name; + return name.substr(name.lastIndexOf("/") + 1); +}; + +const assetsCache = new WeakMap(); + +const getTaskForFile = (file, chunk, options, compilation) => { + const asset = compilation.assets[file]; + const cache = assetsCache.get(asset); + if (cache && cache.file === file) { + for (const cachedFile in cache.assets) { + compilation.assets[cachedFile] = cache.assets[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, + sourceMap, + modules: undefined + }; + } +}; + +class SourceMapDevToolPlugin { + constructor(options) { + if (arguments.length > 1) { + throw new Error( + "SourceMapDevToolPlugin only takes one argument (pass an options object)" + ); + } + + validateOptions(schema, options || {}, "SourceMap DevTool Plugin"); + + if (!options) options = {}; + this.sourceMapFilename = options.filename; + this.sourceMappingURLComment = + options.append === false + ? false + : options.append || "\n//# sourceMappingURL=[url]"; + this.moduleFilenameTemplate = + options.moduleFilenameTemplate || "webpack://[namespace]/[resourcePath]"; + this.fallbackModuleFilenameTemplate = + options.fallbackModuleFilenameTemplate || + "webpack://[namespace]/[resourcePath]?[hash]"; + this.namespace = options.namespace || ""; + this.options = options; + } + + apply(compiler) { + const sourceMapFilename = this.sourceMapFilename; + const sourceMappingURLComment = this.sourceMappingURLComment; + const moduleFilenameTemplate = this.moduleFilenameTemplate; + const namespace = this.namespace; + const fallbackModuleFilenameTemplate = this.fallbackModuleFilenameTemplate; + const requestShortener = compiler.requestShortener; + const options = this.options; + options.test = options.test || /\.(m?js|css)($|\?)/i; + + const matchObject = ModuleFilenameHelpers.matchObject.bind( + undefined, + options + ); + + compiler.hooks.compilation.tap("SourceMapDevToolPlugin", compilation => { + new SourceMapDevToolModuleOptionsPlugin(options).apply(compilation); + + compilation.hooks.afterOptimizeChunkAssets.tap( + { + name: "SourceMapDevToolPlugin", + context: true + }, + (context, chunks) => { + const moduleToSourceNameMapping = new Map(); + const reportProgress = + context && context.reportProgress + ? context.reportProgress + : () => {}; + + const files = []; + for (const chunk of chunks) { + for (const file of chunk.files) { + if (matchObject(file)) { + files.push({ + file, + chunk + }); + } + } + } + + reportProgress(0.0); + const tasks = []; + files.forEach(({ file, chunk }, idx) => { + 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"); + 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; + } + ); + + // find modules with conflicting source names + for (let idx = 0; idx < allModules.length; idx++) { + const module = allModules[idx]; + let sourceName = moduleToSourceNameMapping.get(module); + let hasName = conflictDetectionSet.has(sourceName); + if (!hasName) { + conflictDetectionSet.add(sourceName); + continue; + } + + // try the fallback name first + sourceName = ModuleFilenameHelpers.createFilename( + module, + { + moduleFilenameTemplate: fallbackModuleFilenameTemplate, + namespace: namespace + }, + requestShortener + ); + hasName = usedNamesSet.has(sourceName); + if (!hasName) { + moduleToSourceNameMapping.set(module, sourceName); + usedNamesSet.add(sourceName); + continue; + } + + // elsewise just append stars until we have a valid name + while (hasName) { + sourceName += "*"; + hasName = usedNamesSet.has(sourceName); + } + moduleToSourceNameMapping.set(module, sourceName); + usedNamesSet.add(sourceName); + } + tasks.forEach((task, index) => { + reportProgress( + 0.5 + (0.5 * index) / tasks.length, + task.file, + "attach SourceMap" + ); + const assets = Object.create(null); + const chunk = task.chunk; + const file = task.file; + const asset = task.asset; + const sourceMap = task.sourceMap; + const source = task.source; + const modules = task.modules; + const moduleFilenames = modules.map(m => + moduleToSourceNameMapping.get(m) + ); + sourceMap.sources = moduleFilenames; + if (options.noSources) { + sourceMap.sourcesContent = undefined; + } + sourceMap.sourceRoot = options.sourceRoot || ""; + sourceMap.file = file; + assetsCache.set(asset, { file, assets }); + let currentSourceMappingURLComment = sourceMappingURLComment; + if ( + currentSourceMappingURLComment !== false && + /\.css($|\?)/i.test(file) + ) { + currentSourceMappingURLComment = currentSourceMappingURLComment.replace( + /^\n\/\/(.*)$/, + "\n/*$1*/" + ); + } + const sourceMapString = JSON.stringify(sourceMap); + if (sourceMapFilename) { + let filename = file; + let query = ""; + const idx = filename.indexOf("?"); + if (idx >= 0) { + query = filename.substr(idx); + filename = filename.substr(0, idx); + } + let sourceMapFile = compilation.getPath(sourceMapFilename, { + chunk, + filename: options.fileContext + ? path.relative(options.fileContext, filename) + : filename, + query, + basename: basename(filename), + contentHash: createHash("md4") + .update(sourceMapString) + .digest("hex") + }); + const sourceMapUrl = options.publicPath + ? options.publicPath + sourceMapFile.replace(/\\/g, "/") + : path + .relative(path.dirname(file), sourceMapFile) + .replace(/\\/g, "/"); + if (currentSourceMappingURLComment !== false) { + assets[file] = compilation.assets[file] = new ConcatSource( + new RawSource(source), + currentSourceMappingURLComment.replace( + /\[url\]/g, + sourceMapUrl + ) + ); + } + assets[sourceMapFile] = compilation.assets[ + sourceMapFile + ] = new RawSource(sourceMapString); + chunk.files.push(sourceMapFile); + } else { + assets[file] = compilation.assets[file] = new ConcatSource( + new RawSource(source), + currentSourceMappingURLComment + .replace(/\[map\]/g, () => sourceMapString) + .replace( + /\[url\]/g, + () => + `data:application/json;charset=utf-8;base64,${Buffer.from( + sourceMapString, + "utf-8" + ).toString("base64")}` + ) + ); + } + }); + reportProgress(1.0); + } + ); + }); + } +} + +module.exports = SourceMapDevToolPlugin; |