track chunk origin

This commit is contained in:
Tobias Koppers 2014-01-23 15:31:40 +01:00
parent 07f2a23130
commit 30f954067c
10 changed files with 68 additions and 19 deletions

View File

@ -36,6 +36,8 @@ optimist
.boolean("display-error-details").describe("display-error-details")
.boolean("display-origins").describe("display-origins")
.boolean("display-reasons").alias("display-reasons", "verbose").alias("display-reasons", "v").describe("display-reasons");
@ -93,6 +95,10 @@ if(!outputOptions.json) {
ifArg("display-error-details", function(bool) {
outputOptions.errorDetails = bool;
});
ifArg("display-origins", function(bool) {
outputOptions.chunkOrigins = bool;
});
} else {
outputOptions.chunks = true;
outputOptions.modules = true;

View File

@ -4,17 +4,19 @@
*/
var DependenciesBlock = require("./DependenciesBlock");
function AsyncDependenciesBlock(name) {
function AsyncDependenciesBlock(name, module, loc) {
DependenciesBlock.call(this);
this.name = name;
this.chunkName = name;
this.chunk = null;
this.module = module;
this.loc = loc;
}
module.exports = AsyncDependenciesBlock;
AsyncDependenciesBlock.prototype = Object.create(DependenciesBlock.prototype);
AsyncDependenciesBlock.prototype.updateHash = function updateHash(hash) {
hash.update(this.name || "");
hash.update(this.chunkName || "");
DependenciesBlock.prototype.updateHash.call(this, hash);
};

View File

@ -2,7 +2,7 @@
MIT License http://www.opensource.org/licenses/mit-license.php
Author Tobias Koppers @sokra
*/
function Chunk(name) {
function Chunk(name, module, loc) {
this.id = null;
this.ids = null;
this.name = name;
@ -10,9 +10,11 @@ function Chunk(name) {
this.chunks = [];
this.parents = [];
this.blocks = [];
this.origins = [];
this.rendered = false;
this.entry = false;
this.initial = false;
if(module) this.origins.push({module: module, loc: loc, name: name});
}
module.exports = Chunk;
@ -124,6 +126,11 @@ Chunk.prototype.integrate = function(other, reason) {
this.addBlock(b);
}, this);
other.blocks.length = 0;
other.origins.forEach(function(origin) {
if(!origin.reasons) origin.reasons = [reason];
else if(origin.reasons[0] !== reason) origin.reasons.unshift(reason);
this.origins.push(origin);
}, this);
};
Chunk.prototype.isEmpty = function() {

View File

@ -358,7 +358,7 @@ Compilation.prototype.seal = function seal(callback) {
this.applyPlugins("seal");
this.preparedChunks.forEach(function(preparedChunk) {
var module = preparedChunk.module;
var chunk = this.addChunk(preparedChunk.name);
var chunk = this.addChunk(preparedChunk.name, module);
chunk.id = 0;
chunk.initial = chunk.entry = true;
chunk.addModule(module);
@ -408,12 +408,12 @@ Compilation.prototype.seal = function seal(callback) {
}.bind(this));
};
Compilation.prototype.addChunk = function addChunk(name) {
Compilation.prototype.addChunk = function addChunk(name, module, loc) {
if(name) {
if(Object.prototype.hasOwnProperty.call(this.namedChunks, name))
return this.namedChunks[name];
}
var chunk = new Chunk(name);
var chunk = new Chunk(name, module, loc);
this.chunks.push(chunk);
if(name) {
this.namedChunks[name] = chunk;
@ -425,7 +425,7 @@ Compilation.prototype.processDependenciesBlockForChunk = function processDepende
block.blocks.forEach(function(b) {
var c;
if(!b.chunk) {
c = this.addChunk(b.chunkName);
c = this.addChunk(b.chunkName, b.module, b.loc);
b.chunk = c;
c.addBlock(b);
} else {

View File

@ -225,7 +225,7 @@ NormalModule.prototype.createTemplate = function(keepModules) {
});
newBlock.dependencies = doDeps(block.dependencies);
block.blocks.forEach(function(childBlock) {
var newChildBlock = new AsyncDependenciesBlock(childBlock.name);
var newChildBlock = new AsyncDependenciesBlock(childBlock.name, childBlock.module, childBlock.loc);
newBlock.addBlock(newChildBlock);
doBlock(childBlock, newChildBlock);
});

View File

@ -27,6 +27,7 @@ Stats.prototype.toJson = function toJson(options, forToString) {
var showAssets = d(options.assets, true);
var showChunks = d(options.chunks, true);
var showChunkModules = d(options.chunkModules, !!forToString);
var showChunkOrigins = d(options.chunkOrigins, !forToString);
var showModules = d(options.modules, !forToString);
var showCachedModules = d(options.cached, true);
var showReasons = d(options.reasons, !forToString);
@ -171,6 +172,17 @@ Stats.prototype.toJson = function toJson(options, forToString) {
}
obj.modules.sort(sortByField(sortModules));
}
if(showChunkOrigins) {
obj.origins = chunk.origins.map(function(origin) {
return {
module: origin.module ? origin.module.identifier() : "",
loc: origin.loc ? obj.loc = origin.loc.start.line + ":" + origin.loc.start.column + "-" +
(origin.loc.start.line != origin.loc.end.line ? origin.loc.end.line + ":" : "") + origin.loc.end.column : "",
name: origin.name,
reasons: origin.reasons || []
}
});
}
return obj;
});
obj.chunks.sort(sortByField(sortChunks));
@ -424,6 +436,31 @@ Stats.jsonToString = function jsonToString(obj, useColors) {
green(" [rendered]");
}
newline();
if(chunk.origins) {
chunk.origins.forEach(function(origin) {
normal(" > ");
if(origin.reasons && origin.reasons.length) {
yellow(origin.reasons.join(" "));
normal(" ");
}
if(origin.name) {
normal(origin.name)
normal(" ");
}
if(origin.module) {
var module = modulesByIdentifier["$"+origin.module];
normal("[");
normal(module.id);
normal("] ");
bold(module.name);
if(origin.loc) {
normal(" ");
normal(origin.loc);
}
}
newline();
});
}
if(chunk.modules) {
chunk.modules.forEach(function(module) {
normal(" ");

View File

@ -5,8 +5,8 @@
var AsyncDependenciesBlock = require("../AsyncDependenciesBlock");
var AMDRequireDependency = require("./AMDRequireDependency");
function AMDRequireDependenciesBlock(expr, arrayRange, functionRange) {
AsyncDependenciesBlock.call(this, null);
function AMDRequireDependenciesBlock(expr, arrayRange, functionRange, module, loc) {
AsyncDependenciesBlock.call(this, null, module, loc);
this.expr = expr;
this.range = expr.range;
this.arrayRange = arrayRange;

View File

@ -15,8 +15,7 @@ module.exports = AbstractPlugin.create({
case 1:
var param = this.evaluateExpression(expr.arguments[0]);
var result;
var dep = new AMDRequireDependenciesBlock(expr, param.range);
dep.loc = expr.loc;
var dep = new AMDRequireDependenciesBlock(expr, param.range, null, this.state.module, expr.loc);
var old = this.state.current;
this.state.current = dep;
this.inScope([], function() {
@ -28,7 +27,7 @@ module.exports = AbstractPlugin.create({
return true;
case 2:
var param = this.evaluateExpression(expr.arguments[0]);
var dep = new AMDRequireDependenciesBlock(expr, param.range, expr.arguments[1].range);
var dep = new AMDRequireDependenciesBlock(expr, param.range, expr.arguments[1].range, this.state.module, expr.loc);
dep.loc = expr.loc;
var old = this.state.current;
this.state.current = dep;

View File

@ -5,12 +5,11 @@
var AsyncDependenciesBlock = require("../AsyncDependenciesBlock");
var RequireEnsureDependency = require("./RequireEnsureDependency");
function RequireEnsureDependenciesBlock(expr, fnExpression, chunkName, chunkNameRange) {
AsyncDependenciesBlock.call(this);
function RequireEnsureDependenciesBlock(expr, fnExpression, chunkName, chunkNameRange, module, loc) {
AsyncDependenciesBlock.call(this, chunkName, module, loc);
this.expr = expr;
var bodyRange = fnExpression && fnExpression.body && fnExpression.body.range;
this.range = bodyRange && [bodyRange[0] + 1, bodyRange[1] - 1] || null;
this.chunkName = chunkName;
this.chunkNameRange = chunkNameRange;
this.addDependency(new RequireEnsureDependency(this));
}

View File

@ -33,8 +33,7 @@ module.exports = AbstractPlugin.create({
this.walkExpression(fnExpression.arguments[0]);
fnExpression = fnExpression.callee.object;
}
var dep = new RequireEnsureDependenciesBlock(expr, fnExpression, chunkName, chunkNameRange);
dep.loc = expr.loc;
var dep = new RequireEnsureDependenciesBlock(expr, fnExpression, chunkName, chunkNameRange, this.state.module, expr.loc);
var old = this.state.current;
this.state.current = dep;
try {