allow to configure default RegExps for automatically created contexts

allow to configure when an automatically created context is critical
better warning message in critical dependencies warning

fixes #196
fixes #198
This commit is contained in:
Tobias Koppers 2014-03-11 16:08:22 +01:00
parent bf40067cba
commit 61f1c4d37d
10 changed files with 117 additions and 68 deletions

View File

@ -6,7 +6,16 @@ function CriticalDependenciesWarning(module, dependencies) {
Error.call(this);
Error.captureStackTrace(this, CriticalDependenciesWarning);
this.name = "CriticalDependenciesWarning";
this.message = "Critical dependencies.";
this.message = "Critical dependencies:";
this.message += dependencies.filter(function(d) {
return typeof d.critical === "string" || d.loc;
}).map(function(dep) {
var line = [];
if(dep.loc) line.push(dep.loc.start.line + ":" + dep.loc.start.column + "-" +
(dep.loc.start.line != dep.loc.end.line ? dep.loc.end.line + ":" : "") + dep.loc.end.column);
if(typeof dep.critical === "string") line.push(dep.critical);
return "\n" + line.join(" ");
}).join("");
this.dependencies = dependencies;
this.origin = this.module = module;
}

View File

@ -190,8 +190,8 @@ WebpackOptionsApply.prototype.process = function(options, compiler) {
new RequireIncludePlugin(),
new RequireEnsurePlugin(),
new RequireContextPlugin(options.resolve.modulesDirectories, options.resolve.extensions),
new AMDPlugin(options.amd || {}),
new CommonJsPlugin()
new AMDPlugin(options.module, options.amd || {}),
new CommonJsPlugin(options.module)
);
compiler.apply(

View File

@ -16,6 +16,18 @@ function WebpackOptionsDefaulter() {
this.set("resolve", {});
this.set("resolveLoader", {});
this.set("module.unknownContextRequest", ".");
this.set("module.unknownContextRecursive", true);
this.set("module.unknownContextRegExp", /^\.\/.*$/);
this.set("module.unknownContextCritical", true);
this.set("module.exprContextRequest", ".");
this.set("module.exprContextRegExp", /^\.\/.*$/);
this.set("module.exprContextRecursive", true);
this.set("module.exprContextCritical", true);
this.set("module.wrappedContextRegExp", /.*/);
this.set("module.wrappedContextRecursive", true);
this.set("module.wrappedContextCritical", false);
this.set("output.libraryTarget", "var");
this.set("output.path", "");
this.set("output.sourceMapFilename", "[file].map");

View File

@ -2,7 +2,6 @@
MIT License http://www.opensource.org/licenses/mit-license.php
Author Tobias Koppers @sokra
*/
var AbstractPlugin = require("../AbstractPlugin");
var AMDRequireItemDependency = require("./AMDRequireItemDependency");
var AMDRequireContextDependency = require("./AMDRequireContextDependency");
var ConstDependency = require("./ConstDependency");
@ -22,8 +21,14 @@ function isBoundFunctionExpression(expr) {
return true;
}
module.exports = AbstractPlugin.create({
"call define": function(expr) {
function AMDDefineDependencyParserPlugin(options) {
this.options = options;
}
module.exports = AMDDefineDependencyParserPlugin;
AMDDefineDependencyParserPlugin.prototype.apply = function(parser) {
var options = this.options;
parser.plugin("call define", function(expr) {
var array, fn, obj, namedModule;
switch(expr.arguments.length) {
case 1:
@ -135,8 +140,8 @@ module.exports = AbstractPlugin.create({
}
this.state.current.addDependency(dep);
return true;
},
"call define:amd:array": function(expr, param, identifiers) {
});
parser.plugin("call define:amd:array", function(expr, param, identifiers) {
if(param.isArray()) {
param.items.forEach(function(param, idx) {
if(param.isString() && ["require", "module", "exports"].indexOf(param.string) >= 0)
@ -175,8 +180,8 @@ module.exports = AbstractPlugin.create({
this.state.current.addDependency(dep);
return true;
}
},
"call define:amd:item": function(expr, param) {
});
parser.plugin("call define:amd:item", function(expr, param) {
if(param.isConditional()) {
param.options.forEach(function(param) {
var result = this.applyPluginsBailResult("call define:amd:item", expr, param);
@ -201,14 +206,14 @@ module.exports = AbstractPlugin.create({
this.state.current.addDependency(dep);
return true;
}
},
"call define:amd:context": function(expr, param) {
var dep = ContextDependencyHelpers.create(AMDRequireContextDependency, param.range, param, expr);
});
parser.plugin("call define:amd:context", function(expr, param) {
var dep = ContextDependencyHelpers.create(AMDRequireContextDependency, param.range, param, expr, options);
if(!dep) return;
dep.loc = expr.loc;
dep.optional = !!this.scope.inTry;
this.state.current.addDependency(dep);
return true;
}
});
});
};

View File

@ -20,13 +20,14 @@ var ModuleAliasPlugin = require("enhanced-resolve/lib/ModuleAliasPlugin");
var BasicEvaluatedExpression = require("../BasicEvaluatedExpression");
function AMDPlugin(options) {
function AMDPlugin(options, amdOptions) {
this.amdOptions = amdOptions;
this.options = options;
}
module.exports = AMDPlugin;
AMDPlugin.prototype.apply = function(compiler) {
var options = this.options;
var amdOptions = this.amdOptions;
compiler.plugin("compilation", function(compilation, params) {
var normalModuleFactory = params.normalModuleFactory;
var contextModuleFactory = params.contextModuleFactory;
@ -49,8 +50,10 @@ AMDPlugin.prototype.apply = function(compiler) {
compilation.dependencyFactories.set(LocalModuleDependency, new NullFactory());
compilation.dependencyTemplates.set(LocalModuleDependency, new LocalModuleDependency.Template());
});
new AMDRequireDependenciesBlockParserPlugin().apply(compiler.parser);
new AMDDefineDependencyParserPlugin().apply(compiler.parser);
compiler.parser.apply(
new AMDRequireDependenciesBlockParserPlugin(this.options),
new AMDDefineDependencyParserPlugin(this.options)
);
compiler.parser.plugin("expression require.amd", function(expr) {
var dep = new AMDRequireItemDependency("!!webpack amd options", expr.range);
dep.userRequest = "require.amd";
@ -70,13 +73,13 @@ AMDPlugin.prototype.apply = function(compiler) {
return true;
});
compiler.parser.plugin("expression __webpack_amd_options__", function(expr) {
return this.state.current.addVariable("__webpack_amd_options__", JSON.stringify(options));
return this.state.current.addVariable("__webpack_amd_options__", JSON.stringify(amdOptions));
});
compiler.parser.plugin("evaluate typeof define.amd", function(expr) {
return new BasicEvaluatedExpression().setString(typeof options).setRange(expr.range);
return new BasicEvaluatedExpression().setString(typeof amdOptions).setRange(expr.range);
});
compiler.parser.plugin("evaluate typeof require.amd", function(expr) {
return new BasicEvaluatedExpression().setString(typeof options).setRange(expr.range);
return new BasicEvaluatedExpression().setString(typeof amdOptions).setRange(expr.range);
});
compiler.parser.plugin("evaluate Identifier define.amd", function(expr) {
return new BasicEvaluatedExpression().setBoolean(true).setRange(expr.range);

View File

@ -2,7 +2,6 @@
MIT License http://www.opensource.org/licenses/mit-license.php
Author Tobias Koppers @sokra
*/
var AbstractPlugin = require("../AbstractPlugin");
var AMDRequireItemDependency = require("./AMDRequireItemDependency");
var AMDRequireArrayDependency = require("./AMDRequireArrayDependency");
var AMDRequireContextDependency = require("./AMDRequireContextDependency");
@ -11,8 +10,15 @@ var LocalModuleDependency = require("./LocalModuleDependency");
var ContextDependencyHelpers = require("./ContextDependencyHelpers");
var LocalModulesHelpers = require("./LocalModulesHelpers");
module.exports = AbstractPlugin.create({
"call require": function(expr) {
function AMDRequireDependenciesBlockParserPlugin(options) {
this.options = options;
}
module.exports = AMDRequireDependenciesBlockParserPlugin;
AMDRequireDependenciesBlockParserPlugin.prototype.apply = function(parser) {
var options = this.options;
parser.plugin("call require", function(expr) {
switch(expr.arguments.length) {
case 1:
var param = this.evaluateExpression(expr.arguments[0]);
@ -55,8 +61,8 @@ module.exports = AbstractPlugin.create({
}
return true;
}
},
"call require:amd:array": function(expr, param) {
});
parser.plugin("call require:amd:array", function(expr, param) {
if(param.isArray()) {
param.items.forEach(function(param) {
var result = this.applyPluginsBailResult("call require:amd:item", expr, param);
@ -91,8 +97,8 @@ module.exports = AbstractPlugin.create({
this.state.current.addDependency(dep);
return true;
}
},
"call require:amd:item": function(expr, param) {
});
parser.plugin("call require:amd:item", function(expr, param) {
if(param.isConditional()) {
param.options.forEach(function(param) {
var result = this.applyPluginsBailResult("call require:amd:item", expr, param);
@ -117,14 +123,14 @@ module.exports = AbstractPlugin.create({
this.state.current.addDependency(dep);
return true;
}
},
"call require:amd:context": function(expr, param) {
var dep = ContextDependencyHelpers.create(AMDRequireContextDependency, param.range, param, expr);
});
parser.plugin("call require:amd:context", function(expr, param) {
var dep = ContextDependencyHelpers.create(AMDRequireContextDependency, param.range, param, expr, options);
if(!dep) return;
dep.loc = expr.loc;
dep.optional = !!this.scope.inTry;
this.state.current.addDependency(dep);
return true;
}
});
});
};

View File

@ -17,7 +17,8 @@ var CommonJsRequireDependencyParserPlugin = require("./CommonJsRequireDependency
var BasicEvaluatedExpression = require("../BasicEvaluatedExpression");
function CommonJsPlugin() {
function CommonJsPlugin(options) {
this.options = options;
}
module.exports = CommonJsPlugin;
@ -72,7 +73,7 @@ CommonJsPlugin.prototype.apply = function(compiler) {
return new BasicEvaluatedExpression().setString("object").setRange(expr.range);
});
compiler.parser.apply(
new CommonJsRequireDependencyParserPlugin(),
new RequireResolveDependencyParserPlugin()
new CommonJsRequireDependencyParserPlugin(this.options),
new RequireResolveDependencyParserPlugin(this.options)
);
};

View File

@ -2,7 +2,6 @@
MIT License http://www.opensource.org/licenses/mit-license.php
Author Tobias Koppers @sokra
*/
var AbstractPlugin = require("../AbstractPlugin");
var ConstDependency = require("./ConstDependency");
var CommonJsRequireDependency = require("./CommonJsRequireDependency");
var CommonJsRequireContextDependency = require("./CommonJsRequireContextDependency");
@ -11,22 +10,29 @@ var LocalModuleDependency = require("./LocalModuleDependency");
var ContextDependencyHelpers = require("./ContextDependencyHelpers");
var LocalModulesHelpers = require("./LocalModulesHelpers");
module.exports = AbstractPlugin.create({
"expression require.cache": function(expr) {
function CommonJsRequireDependencyParserPlugin(options) {
this.options = options;
}
module.exports = CommonJsRequireDependencyParserPlugin;
CommonJsRequireDependencyParserPlugin.prototype.apply = function(parser) {
var options = this.options;
parser.plugin("expression require.cache", function(expr) {
var dep = new ConstDependency("__webpack_require__.c", expr.range);
dep.loc = expr.loc;
this.state.current.addDependency(dep);
return true;
},
"expression require": function(expr) {
var dep = new CommonJsRequireContextDependency(".", true, /^\.\/.*$/, expr.range);
dep.critical = true;
});
parser.plugin("expression require", function(expr) {
var dep = new CommonJsRequireContextDependency(options.unknownContextRequest, options.unknownContextRecursive, options.unknownContextRegExp, expr.range);
dep.critical = options.unknownContextCritical && "require function is used in a way, in which dependencies cannot be statically extracted";
dep.loc = expr.loc;
dep.optional = !!this.scope.inTry;
this.state.current.addDependency(dep);
return true;
},
"call require": function(expr) {
});
parser.plugin("call require", function(expr) {
if(expr.arguments.length !== 1) return;
var localModule;
var param = this.evaluateExpression(expr.arguments[0]);
@ -53,8 +59,8 @@ module.exports = AbstractPlugin.create({
}
return true;
}
},
"call require:commonjs:item": function(expr, param) {
});
parser.plugin("call require:commonjs:item", function(expr, param) {
if(param.isString()) {
var dep = new CommonJsRequireDependency(param.string, param.range);
dep.loc = expr.loc;
@ -62,14 +68,14 @@ module.exports = AbstractPlugin.create({
this.state.current.addDependency(dep);
return true;
}
},
"call require:commonjs:context": function(expr, param) {
var dep = ContextDependencyHelpers.create(CommonJsRequireContextDependency, expr.range, param, expr);
});
parser.plugin("call require:commonjs:context", function(expr, param) {
var dep = ContextDependencyHelpers.create(CommonJsRequireContextDependency, expr.range, param, expr, options);
if(!dep) return;
dep.loc = expr.loc;
dep.optional = !!this.scope.inTry;
this.state.current.addDependency(dep);
return true;
}
});
});
};

View File

@ -4,7 +4,7 @@
*/
var ContextDependencyHelpers = exports;
ContextDependencyHelpers.create = function(Dep, range, param, expr) {
ContextDependencyHelpers.create = function(Dep, range, param, expr, options) {
if(param.isWrapped() && param.prefix.isString()) {
var prefix = param.prefix.string;
var postfix = param.postfix.isString() ? param.postfix.string : "";
@ -18,16 +18,17 @@ ContextDependencyHelpers.create = function(Dep, range, param, expr) {
}
var regExp = new RegExp("^" +
prefix.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&") +
".*" +
options.wrappedContextRegExp.source +
postfix.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&") + "$");
var dep = new Dep(context, true, regExp, range, valueRange);
var dep = new Dep(context, options.wrappedContextRecursive, regExp, range, valueRange);
dep.loc = expr.loc;
dep.prepend = prefix;
dep.critical = options.wrappedContextCritical && "a part of the request of a dependency is an expression";
return dep;
} else {
var dep = new Dep(".", true, /^\.\/.*$/, range, param.range);
var dep = new Dep(options.exprContextRequest, options.exprContextRecursive, options.exprContextRegExp, range, param.range);
dep.loc = expr.loc;
dep.critical = true;
dep.critical = options.exprContextCritical && "the request of a dependency is an expression";
return dep;
}
};

View File

@ -2,14 +2,20 @@
MIT License http://www.opensource.org/licenses/mit-license.php
Author Tobias Koppers @sokra
*/
var AbstractPlugin = require("../AbstractPlugin");
var RequireResolveDependency = require("./RequireResolveDependency");
var RequireResolveContextDependency = require("./RequireResolveContextDependency");
var RequireResolveHeaderDependency = require("./RequireResolveHeaderDependency");
var ContextDependencyHelpers = require("./ContextDependencyHelpers");
module.exports = AbstractPlugin.create({
"call require.resolve": function(expr) {
function RequireResolveDependencyParserPlugin(options) {
this.options = options;
}
module.exports = RequireResolveDependencyParserPlugin;
RequireResolveDependencyParserPlugin.prototype.apply = function(parser) {
var options = this.options;
parser.plugin("call require.resolve", function(expr) {
if(expr.arguments.length !== 1) return;
var param = this.evaluateExpression(expr.arguments[0]);
if(param.isConditional()) {
@ -29,8 +35,8 @@ module.exports = AbstractPlugin.create({
this.state.current.addDependency(new RequireResolveHeaderDependency(expr.callee.range));
return true;
}
},
"call require.resolve:item": function(expr, param) {
});
parser.plugin("call require.resolve:item", function(expr, param) {
if(param.isString()) {
var dep = new RequireResolveDependency(param.string, param.range);
dep.loc = expr.loc;
@ -38,14 +44,14 @@ module.exports = AbstractPlugin.create({
this.state.current.addDependency(dep);
return true;
}
},
"call require.resolve:context": function(expr, param) {
var dep = ContextDependencyHelpers.create(RequireResolveContextDependency, param.range, param, expr);
});
parser.plugin("call require.resolve:context", function(expr, param) {
var dep = ContextDependencyHelpers.create(RequireResolveContextDependency, param.range, param, expr, options);
if(!dep) return;
dep.loc = expr.loc;
dep.optional = !!this.scope.inTry;
this.state.current.addDependency(dep);
return true;
}
});
});
};