aboutsummaryrefslogtreecommitdiff
path: root/node_modules/webpack/lib/SourceMapDevToolPlugin.js
diff options
context:
space:
mode:
authorFlorian Dold <florian.dold@gmail.com>2017-08-14 05:01:11 +0200
committerFlorian Dold <florian.dold@gmail.com>2017-08-14 05:02:09 +0200
commit363723fc84f7b8477592e0105aeb331ec9a017af (patch)
tree29f92724f34131bac64d6a318dd7e30612e631c7 /node_modules/webpack/lib/SourceMapDevToolPlugin.js
parent5634e77ad96bfe1818f6b6ee70b7379652e5487f (diff)
node_modules
Diffstat (limited to 'node_modules/webpack/lib/SourceMapDevToolPlugin.js')
-rw-r--r--node_modules/webpack/lib/SourceMapDevToolPlugin.js165
1 files changed, 103 insertions, 62 deletions
diff --git a/node_modules/webpack/lib/SourceMapDevToolPlugin.js b/node_modules/webpack/lib/SourceMapDevToolPlugin.js
index 53645fb4e..abd8d5ee3 100644
--- a/node_modules/webpack/lib/SourceMapDevToolPlugin.js
+++ b/node_modules/webpack/lib/SourceMapDevToolPlugin.js
@@ -5,6 +5,7 @@
"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;
@@ -16,6 +17,38 @@ const basename = (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)
@@ -42,81 +75,85 @@ class SourceMapDevToolPlugin {
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) {
- let allModules = [];
- let allModuleFilenames = [];
+ const moduleToSourceNameMapping = new Map();
const tasks = [];
+
chunks.forEach(function(chunk) {
- chunk.files.filter(ModuleFilenameHelpers.matchObject.bind(undefined, options)).map(function(file) {
- 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);
+ 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(const module of modules) {
+ if(!moduleToSourceNameMapping.get(module)) {
+ moduleToSourceNameMapping.set(module, ModuleFilenameHelpers.createFilename(module, moduleFilenameTemplate, requestShortener));
+ }
+ }
+
+ task.modules = modules;
+
+ tasks.push(task);
}
- 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
- };
- }
- }).filter(Boolean).map(task => {
- const modules = task.sourceMap.sources.map(source => {
- const module = compilation.findModule(source);
- return module || source;
- });
- const moduleFilenames = modules.map(module => ModuleFilenameHelpers.createFilename(module, moduleFilenameTemplate, requestShortener));
- task.modules = modules;
- task.moduleFilenames = moduleFilenames;
- return task;
- }).forEach(task => {
- allModules = allModules.concat(task.modules);
- allModuleFilenames = allModuleFilenames.concat(task.moduleFilenames);
- tasks.push(task);
});
});
- allModuleFilenames = ModuleFilenameHelpers.replaceDuplicates(allModuleFilenames, (filename, i) => ModuleFilenameHelpers.createFilename(allModules[i], fallbackModuleFilenameTemplate, requestShortener), (ai, bi) => {
- let a = allModules[ai];
- let b = allModules[bi];
- a = !a ? "" : typeof a === "string" ? a : a.identifier();
- b = !b ? "" : typeof b === "string" ? b : b.identifier();
- return a.length - b.length;
- });
- allModuleFilenames = ModuleFilenameHelpers.replaceDuplicates(allModuleFilenames, (filename, i, n) => {
- for(let j = 0; j < n; j++)
- filename += "*";
- return filename;
- });
- tasks.forEach(task => {
- task.moduleFilenames = allModuleFilenames.slice(0, task.moduleFilenames.length);
- allModuleFilenames = allModuleFilenames.slice(task.moduleFilenames.length);
+
+ 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(const module of allModules) {
+ 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 moduleFilenames = task.moduleFilenames;
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) => `${content}\n\n\n${ModuleFilenameHelpers.createFooter(modules[i], requestShortener)}`);
@@ -131,6 +168,7 @@ class SourceMapDevToolPlugin {
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 = "";
@@ -139,22 +177,25 @@ class SourceMapDevToolPlugin {
query = filename.substr(idx);
filename = filename.substr(0, idx);
}
- const sourceMapFile = compilation.getPath(sourceMapFilename, {
+ let sourceMapFile = compilation.getPath(sourceMapFilename, {
chunk,
filename,
query,
basename: basename(filename)
});
+ if(sourceMapFile.indexOf("[contenthash]") !== -1) {
+ sourceMapFile = sourceMapFile.replace(/\[contenthash\]/g, crypto.createHash("md5").update(sourceMapString).digest("hex"));
+ }
const sourceMapUrl = 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(JSON.stringify(sourceMap));
+ 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, () => JSON.stringify(sourceMap))
- .replace(/\[url\]/g, () => `data:application/json;charset=utf-8;base64,${new Buffer(JSON.stringify(sourceMap), "utf-8").toString("base64")}`) // eslint-disable-line
+ .replace(/\[map\]/g, () => sourceMapString)
+ .replace(/\[url\]/g, () => `data:application/json;charset=utf-8;base64,${new Buffer(sourceMapString, "utf-8").toString("base64")}`) // eslint-disable-line
);
}
});