webpack
Version:
Packs CommonJs/AMD modules for the browser. Allows to split your codebase into multiple bundles, which can be loaded on demand. Support loaders to preprocess files, i.e. json, jade, coffee, css, less, ... and your custom stuff.
141 lines (137 loc) • 5.96 kB
JavaScript
/*
MIT License http://www.opensource.org/licenses/mit-license.php
Author Tobias Koppers @sokra
*/
var path = require("path");
var RequestShortener = require("./RequestShortener");
var Template = require("./Template");
var ConcatSource = require("webpack-core/lib/ConcatSource");
var RawSource = require("webpack-core/lib/RawSource");
var ModuleFilenameHelpers = require("./ModuleFilenameHelpers");
function SourceMapDevToolPlugin(sourceMapFilename, sourceMappingURLComment, moduleFilenameTemplate, fallbackModuleFilenameTemplate) {
this.sourceMapFilename = sourceMapFilename;
this.sourceMappingURLComment = sourceMappingURLComment === false ? false : sourceMappingURLComment || "\n//# sourceMappingURL=[url]";
this.moduleFilenameTemplate = moduleFilenameTemplate || "webpack:///[resourcePath]";
this.fallbackModuleFilenameTemplate = fallbackModuleFilenameTemplate || "webpack:///[resourcePath]?[hash]";
}
module.exports = SourceMapDevToolPlugin;
SourceMapDevToolPlugin.prototype.apply = function(compiler) {
var sourceMapFilename = this.sourceMapFilename;
var sourceMappingURLComment = this.sourceMappingURLComment;
var moduleFilenameTemplate = this.moduleFilenameTemplate;
var fallbackModuleFilenameTemplate = this.fallbackModuleFilenameTemplate;
var requestShortener = new RequestShortener(compiler.context);
compiler.plugin("compilation", function(compilation) {
compilation.plugin("build-module", function(module) {
module.useSourceMap = true;
});
compilation.plugin("after-optimize-chunk-assets", function(chunks) {
var allModules = [];
var allModuleFilenames = [];
var tasks = [];
chunks.forEach(function(chunk) {
chunk.files.slice().map(function(file) {
var asset = this.assets[file];
if(asset.__SourceMapDevTool_Data) {
var data = asset.__SourceMapDevTool_Data;
for(var cachedFile in data) {
this.assets[cachedFile] = data[cachedFile];
if(cachedFile !== file)
chunk.files.push(cachedFile);
}
return;
}
var sourceMap = asset.map();
if(sourceMap) {
return {
chunk: chunk,
file: file,
asset: asset,
sourceMap: sourceMap
}
}
}, this).filter(Boolean).map(function(task) {
var modules = task.sourceMap.sources.map(function(source) {
var module = compilation.findModule(source);
return module || source;
});
var moduleFilenames = modules.map(function(module) {
return ModuleFilenameHelpers.createFilename(module, moduleFilenameTemplate, requestShortener);
});
task.modules = modules;
task.moduleFilenames = moduleFilenames;
return task;
}, this).forEach(function(task) {
allModules = allModules.concat(task.modules);
allModuleFilenames = allModuleFilenames.concat(task.moduleFilenames);
tasks.push(task);
}, this);
}, this);
allModuleFilenames = ModuleFilenameHelpers.replaceDuplicates(allModuleFilenames, function(filename, i) {
return ModuleFilenameHelpers.createFilename(allModules[i], fallbackModuleFilenameTemplate, requestShortener);
}, function(ai, bi) {
var a = allModules[ai];
var b = allModules[bi];
a = typeof a === "string" ? a : a.identifier();
b = typeof b === "string" ? b : b.identifier();
return a.length - b.length;
});
allModuleFilenames = ModuleFilenameHelpers.replaceDuplicates(allModuleFilenames, function(filename, i, n) {
for(var j = 0; j < n; j++)
filename += "*";
return filename;
});
tasks.forEach(function(task) {
task.moduleFilenames = allModuleFilenames.slice(0, task.moduleFilenames.length);
allModuleFilenames = allModuleFilenames.slice(task.moduleFilenames.length);
}, this);
tasks.forEach(function(task) {
var chunk = task.chunk;
var file = task.file;
var asset = task.asset;
var sourceMap = task.sourceMap;
var moduleFilenames = task.moduleFilenames;
var modules = task.modules;
sourceMap.sources = moduleFilenames;
if(sourceMap.sourcesContent) {
sourceMap.sourcesContent = sourceMap.sourcesContent.map(function(content, i) {
return content + "\n\n\n" + ModuleFilenameHelpers.createFooter(modules[i], requestShortener);
});
}
sourceMap.sourceRoot = "";
sourceMap.file = file;
asset.__SourceMapDevTool_Data = {};
var currentSourceMappingURLComment = sourceMappingURLComment;
if(currentSourceMappingURLComment !== false && /\.css($|\?)/i.test(file)) {
currentSourceMappingURLComment = currentSourceMappingURLComment.replace(/^\n\/\/(.*)$/, "\n/*$1*/");
}
if(sourceMapFilename) {
var filename = file, query = "";
var idx = filename.indexOf("?");
if(idx >= 0) {
query = filename.substr(idx);
filename = filename.substr(0, idx);
}
var sourceMapFile = this.getPath(sourceMapFilename, {
chunk: chunk,
filename: filename,
query: query,
basename: basename(filename)
});
var sourceMapUrl = path.relative(path.dirname(file), sourceMapFile).replace(/\\/g, "/");
if(currentSourceMappingURLComment !== false) {
asset.__SourceMapDevTool_Data[file] = this.assets[file] = new ConcatSource(asset, currentSourceMappingURLComment.replace(/\[url\]/g, sourceMapUrl));
}
asset.__SourceMapDevTool_Data[sourceMapFile] = this.assets[sourceMapFile] = new RawSource(JSON.stringify(sourceMap));
chunk.files.push(sourceMapFile);
} else {
asset.__SourceMapDevTool_Data[file] = this.assets[file] = new ConcatSource(asset, currentSourceMappingURLComment.replace(/\[url\]/g, "data:application/json;base64," + new Buffer(JSON.stringify(sourceMap)).toString("base64")));
}
}, this);
});
});
};
function basename(name) {
if(name.indexOf("/") < 0) return name;
return name.substr(name.lastIndexOf("/")+1);
}