webpack 1.0 beta

moved many options to plugins
#113
This commit is contained in:
Tobias Koppers 2013-12-17 23:21:49 +01:00
parent 6d7ac9e5e7
commit 3170b76b22
28 changed files with 341 additions and 230 deletions

View File

@ -73,6 +73,8 @@ module.exports = function(optimist) {
.string("provide").describe("provide")
.boolean("labeled-modules").describe("labeled-modules")
.string("plugin").describe("plugin")
.boolean("bail").describe("bail")

View File

@ -18,22 +18,24 @@ module.exports = function(optimist, argv, convertOptions) {
argv["optimize-occurence-order"] = true;
}
function ifArg(name, fn, init) {
function ifArg(name, fn, init, finalize) {
if(Array.isArray(argv[name])) {
if(init) init();
argv[name].forEach(fn);
if(finalize) finalize();
} else if(typeof argv[name] != "undefined") {
if(init) init();
fn(argv[name], -1);
if(finalize) finalize();
}
}
function ifArgPair(name, fn, init) {
function ifArgPair(name, fn, init, finalize) {
ifArg(name, function(content, idx) {
var i = content.indexOf("=");
if(i < 0) return fn(null, content, idx);
else return fn(content.substr(0, i), content.substr(i+1), idx);
}, init);
}, init, finalize);
}
function ifBooleanArg(name, fn) {
@ -139,14 +141,19 @@ module.exports = function(optimist, argv, convertOptions) {
ensureArray(options.module, "postLoaders");
});
var defineObject;
ifArgPair("define", function(name, value) {
if(name === null) {
name = value;
value = true;
}
options.define[name] = value;
defineObject[name] = value;
}, function() {
ensureObject(options, "define");
defineObject = {}
}, function() {
ensureArray(options, "plugins");
var DefinePlugin = require("../lib/DefinePlugin");
options.plugins.push(new DefinePlugin(defineObject));
});
ifArg("output-path", function(value) {
@ -222,7 +229,12 @@ module.exports = function(optimist, argv, convertOptions) {
options.watchDelay = value;
});
mapArgToBoolean("hot", "hot");
ifBooleanArg("hot", function() {
ensureArray(options, "plugins");
var HotModuleReplacementPlugin = require("../lib/HotModuleReplacementPlugin");
options.plugins.push(new HotModuleReplacementPlugin());
});
mapArgToBoolean("debug", "debug");
ifBooleanArg("progress", function() {
@ -279,37 +291,45 @@ module.exports = function(optimist, argv, convertOptions) {
});
ifArg("optimize-max-chunks", function(value) {
ensureObject(options, "optimize");
options.optimize.maxChunks = parseInt(value, 10);
ensureArray(options, "plugins");
var LimitChunkCountPlugin = require("../lib/optimize/LimitChunkCountPlugin");
options.plugins.push(new LimitChunkCountPlugin({
maxChunks: parseInt(value, 10)
}));
});
ifArg("optimize-min-chunk-size", function(value) {
ensureObject(options, "optimize");
options.optimize.minChunkSize = parseInt(value, 10);
ensureArray(options, "plugins");
var LimitChunkSizePlugin = require("../lib/optimize/LimitChunkSizePlugin");
options.plugins.push(new LimitChunkSizePlugin(parseInt(value, 10)));
});
ifBooleanArg("optimize-minimize", function() {
ensureObject(options, "optimize");
options.optimize.minimize = true;
ensureArray(options, "plugins");
var UglifyJsPlugin = require("../lib/optimize/UglifyJsPlugin");
options.plugins.push(new UglifyJsPlugin());
});
ifBooleanArg("optimize-occurence-order", function() {
ensureObject(options, "optimize");
options.optimize.occurenceOrder = true;
ensureArray(options, "plugins");
var OccurenceOrderPlugin = require("../lib/optimize/OccurenceOrderPlugin");
options.plugins.push(new OccurenceOrderPlugin());
});
ifBooleanArg("optimize-dedupe", function() {
ensureObject(options, "optimize");
options.optimize.dedupe = true;
ensureArray(options, "plugins");
var DedupePlugin = require("../lib/optimize/DedupePlugin");
options.plugins.push(new DedupePlugin());
});
ifArg("prefetch", function(request) {
ensureArray(options, "prefetch");
options.prefetch.push(request);
ensureArray(options, "plugins");
var PrefetchPlugin = require("../lib/PrefetchPlugin");
options.plugins.push(new PrefetchPlugin(request));
});
ifArg("provide", function(value) {
ensureObject(options, "provide");
ensureArray(options, "plugins");
var idx = value.indexOf("=");
if(idx >= 0) {
var name = value.substr(0, idx);
@ -317,7 +337,14 @@ module.exports = function(optimist, argv, convertOptions) {
} else {
var name = value;
}
options.provide[name] = value;
var ProvidePlugin = require("../lib/ProvidePlugin");
options.plugins.push(new ProvidePlugin(name, value));
});
ifBooleanArg("labeled-modules", function() {
ensureArray(options, "plugins");
var LabeledModulesPlugin = require("../lib/dependencies/LabeledModulesPlugin");
options.plugins.push(new LabeledModulesPlugin());
});
ifArg("plugin", function(value) {

View File

@ -1,5 +1,6 @@
var webpack = require("../../");
module.exports = {
optimize: {
dedupe: true
}
plugins: [
new webpack.optimize.DedupePlugin()
]
}

View File

@ -1,5 +1,6 @@
var webpack = require("../../");
module.exports = {
optimize: {
dedupe: true
}
plugins: [
new webpack.optimize.DedupePlugin()
]
}

View File

@ -0,0 +1,6 @@
var webpack = require("../../");
module.exports = {
plugins: [
new webpack.dependencies.LabeledModulesPlugin()
]
}

View File

@ -0,0 +1,6 @@
var webpack = require("../../");
module.exports = {
plugins: [
new webpack.dependencies.LabeledModulesPlugin()
]
}

View File

@ -5,11 +5,11 @@
var FunctionModuleTemplate = require("./FunctionModuleTemplate");
var RequestShortener = require("./RequestShortener");
function FunctionModulePlugin(context, options) {
this.context = context;
function FunctionModulePlugin(options, requestShortener) {
this.options = options;
this.requestShortener = requestShortener;
}
module.exports = FunctionModulePlugin;
FunctionModulePlugin.prototype.apply = function(compiler) {
compiler.moduleTemplate = new FunctionModuleTemplate(this.options, new RequestShortener(this.context));
compiler.moduleTemplate = new FunctionModuleTemplate(this.options, this.requestShortener || new RequestShortener(compiler.context));
};

View File

@ -8,14 +8,13 @@ var ModuleHotAcceptDependency = require("./dependencies/ModuleHotAcceptDependenc
var ModuleHotDeclineDependency = require("./dependencies/ModuleHotDeclineDependency");
var RawSource = require("webpack-core/lib/RawSource");
function HotModuleReplacementPlugin(outputOptions) {
this.outputOptions = outputOptions;
function HotModuleReplacementPlugin() {
}
module.exports = HotModuleReplacementPlugin;
HotModuleReplacementPlugin.prototype.apply = function(compiler) {
var hotUpdateChunkFilename = this.outputOptions.hotUpdateChunkFilename;
var hotUpdateMainFilename = this.outputOptions.hotUpdateMainFilename;
var hotUpdateChunkFilename = compiler.options.output.hotUpdateChunkFilename;
var hotUpdateMainFilename = compiler.options.output.hotUpdateMainFilename;
compiler.plugin("compilation", function(compilation, params) {
var hotUpdateChunkTemplate = compilation.compiler.hotUpdateChunkTemplate;
if(!hotUpdateChunkTemplate && !compilation.mainTemplate.renderHotModuleReplacementInit) return;

View File

@ -0,0 +1,17 @@
/*
MIT License http://www.opensource.org/licenses/mit-license.php
Author Tobias Koppers @sokra
*/
function MovedToPluginWarningPlugin(optionName, pluginName) {
this.optionName = optionName;
this.pluginName = pluginName
}
module.exports = MovedToPluginWarningPlugin;
MovedToPluginWarningPlugin.prototype.apply = function(compiler) {
var optionName = this.optionName;
var pluginName = this.pluginName
compiler.plugin("compilation", function(compilation) {
compilation.warnings.push(new Error("webpack options:\nDEPRECATED option '" + optionName + "' will be moved to the " + pluginName + ". Use this by now.\nFor more info about the usage of the " + pluginName + " see https://github.com/webpack/docs/wiki/webpack-plugins"));
});
};

View File

@ -1,15 +0,0 @@
/*
MIT License http://www.opensource.org/licenses/mit-license.php
Author Tobias Koppers @sokra
*/
var BasicEvaluatedExpression = require("./BasicEvaluatedExpression");
function NoHotModuleReplacementPlugin() {
}
module.exports = NoHotModuleReplacementPlugin;
NoHotModuleReplacementPlugin.prototype.apply = function(compiler) {
compiler.parser.plugin("evaluate Identifier module.hot", function(expr) {
return new BasicEvaluatedExpression().setBoolean(false).setRange(expr.range);
});
};

View File

@ -9,14 +9,13 @@ var ConstDependency = require("./dependencies/ConstDependency");
var BasicEvaluatedExpression = require("./BasicEvaluatedExpression");
var UnsupportedFeatureWarning = require("./UnsupportedFeatureWarning");
function NodeStuffPlugin(options, context) {
function NodeStuffPlugin(options) {
this.options = options;
this.context = context;
}
module.exports = NodeStuffPlugin;
NodeStuffPlugin.prototype.apply = function(compiler) {
function ignore() { return true; }
var context = this.context;
var context = compiler.context;
if(this.options.__filename == "mock") {
compiler.parser.plugin("expression __filename", function(expr) {
this.state.current.addVariable("__filename", JSON.stringify("/index.js"));
@ -71,6 +70,9 @@ NodeStuffPlugin.prototype.apply = function(compiler) {
compiler.parser.plugin("expression module.exports", ignore);
compiler.parser.plugin("expression module.loaded", ignore);
compiler.parser.plugin("expression module.id", ignore);
compiler.parser.plugin("evaluate Identifier module.hot", function(expr) {
return new BasicEvaluatedExpression().setBoolean(false).setRange(expr.range);
});
compiler.parser.plugin("expression module", function(expr) {
return ModuleParserHelpers.addParsedVariable(this, "module", "require(" + JSON.stringify(path.join(__dirname, "..", "buildin", "module.js")) + ")(module)");
});

View File

@ -5,8 +5,12 @@
var PrefetchDependency = require("./dependencies/PrefetchDependency");
function PrefetchPlugin(context, request) {
this.context = context;
this.request = request;
if(!request) {
this.request = context;
} else {
this.context = context;
this.request = request;
}
}
module.exports = PrefetchPlugin;
PrefetchPlugin.prototype.apply = function(compiler) {
@ -16,6 +20,6 @@ PrefetchPlugin.prototype.apply = function(compiler) {
compilation.dependencyFactories.set(PrefetchDependency, normalModuleFactory);
});
compiler.plugin("make", function(compilation, callback) {
compilation.prefetch(this.context, new PrefetchDependency(this.request), callback);
compilation.prefetch(this.context || compiler.context, new PrefetchDependency(this.request), callback);
}.bind(this));
};

View File

@ -4,15 +4,15 @@
*/
var ModuleParserHelpers = require("./ModuleParserHelpers");
function ProvidePlugin(name, request) {
this.name = name;
this.request = request;
function ProvidePlugin(definitions) {
this.definitions = definitions;
}
module.exports = ProvidePlugin;
ProvidePlugin.prototype.apply = function(compiler) {
var name = this.name;
var request = this.request;
compiler.parser.plugin("expression " + name, function(expr) {
return ModuleParserHelpers.addParsedVariable(this, name, "require(" + JSON.stringify(request) + ")");
});
Object.keys(this.definitions).forEach(function(name) {
var request = this.definitions[name];
compiler.parser.plugin("expression " + name, function(expr) {
return ModuleParserHelpers.addParsedVariable(this, name, "require(" + JSON.stringify(request) + ")");
});
}, this);
};

View File

@ -8,8 +8,7 @@ var ConcatSource = require("webpack-core/lib/ConcatSource");
var RawSource = require("webpack-core/lib/RawSource");
var base64Encode = require("base64-encode");
function SourceMapDevToolPlugin(context, sourceMapFilename, sourceMappingURLComment) {
this.context = context;
function SourceMapDevToolPlugin(sourceMapFilename, sourceMappingURLComment) {
this.sourceMapFilename = sourceMapFilename;
this.sourceMappingURLComment = sourceMappingURLComment || "\n/*\n//@ sourceMappingURL=[url]\n*/";
}
@ -17,7 +16,7 @@ module.exports = SourceMapDevToolPlugin;
SourceMapDevToolPlugin.prototype.apply = function(compiler) {
var sourceMapFilename = this.sourceMapFilename;
var sourceMappingURLComment = this.sourceMappingURLComment;
var requestShortener = new RequestShortener(this.context);
var requestShortener = new RequestShortener(compiler.context);
compiler.plugin("compilation", function(compilation) {
compilation.plugin("build-module", function(module) {
module.useSourceMap = true;

View File

@ -19,6 +19,8 @@ var NodeStuffPlugin = require("./NodeStuffPlugin");
var CompatibilityPlugin = require("./CompatibilityPlugin");
var DefinePlugin = require("./DefinePlugin");
var MovedToPluginWarningPlugin = require("./MovedToPluginWarningPlugin");
var LoaderPlugin = require("./dependencies/LoaderPlugin");
var CommonJsPlugin = require("./dependencies/CommonJsPlugin");
var AMDPlugin = require("./dependencies/AMDPlugin");
@ -52,6 +54,7 @@ module.exports = WebpackOptionsApply;
WebpackOptionsApply.prototype = Object.create(OptionsApply.prototype);
WebpackOptionsApply.prototype.process = function(options, compiler) {
compiler.context = options.context;
if(options.plugins && Array.isArray(options.plugins)) {
compiler.apply.apply(compiler, options.plugins);
}
@ -64,7 +67,7 @@ WebpackOptionsApply.prototype.process = function(options, compiler) {
var NodeSourcePlugin = require("./node/NodeSourcePlugin");
compiler.apply(
new JsonpTemplatePlugin(options.output),
new FunctionModulePlugin(options.context, options.output),
new FunctionModulePlugin(options.output),
new NodeSourcePlugin(options.node)
);
break;
@ -73,7 +76,7 @@ WebpackOptionsApply.prototype.process = function(options, compiler) {
var NodeSourcePlugin = require("./node/NodeSourcePlugin");
compiler.apply(
new WebWorkerTemplatePlugin(options.output),
new FunctionModulePlugin(options.context, options.output),
new FunctionModulePlugin(options.output),
new NodeSourcePlugin(options.node)
);
break;
@ -83,7 +86,7 @@ WebpackOptionsApply.prototype.process = function(options, compiler) {
var NodeTargetPlugin = require("./node/NodeTargetPlugin");
compiler.apply(
new NodeTemplatePlugin(options.output, options.target === "async-node"),
new FunctionModulePlugin(options.context, options.output),
new FunctionModulePlugin(options.output),
new NodeTargetPlugin()
);
break;
@ -94,11 +97,9 @@ WebpackOptionsApply.prototype.process = function(options, compiler) {
}
if(options.hot) {
compiler.apply(new MovedToPluginWarningPlugin("hot", "HotModuleReplacementPlugin"));
var HotModuleReplacementPlugin = require("./HotModuleReplacementPlugin");
compiler.apply(new HotModuleReplacementPlugin(options.output));
} else {
var NoHotModuleReplacementPlugin = require("./NoHotModuleReplacementPlugin");
compiler.apply(new NoHotModuleReplacementPlugin());
}
if(options.devtool == "eval")
@ -110,29 +111,29 @@ WebpackOptionsApply.prototype.process = function(options, compiler) {
else if(options.devtool == "#@eval")
compiler.apply(new EvalDevToolModulePlugin("//@ sourceURL=[url]\n//# sourceURL=[url]"));
else if(options.devtool == "sourcemap" || options.devtool == "source-map")
compiler.apply(new SourceMapDevToolPlugin(options.context, options.output.sourceMapFilename));
compiler.apply(new SourceMapDevToolPlugin(options.output.sourceMapFilename));
else if(options.devtool == "@sourcemap" || options.devtool == "@source-map")
compiler.apply(new SourceMapDevToolPlugin(options.context, options.output.sourceMapFilename, "\n/*\n//@ sourceMappingURL=[url]\n*/"));
compiler.apply(new SourceMapDevToolPlugin(options.output.sourceMapFilename, "\n/*\n//@ sourceMappingURL=[url]\n*/"));
else if(options.devtool == "#sourcemap" || options.devtool == "#source-map")
compiler.apply(new SourceMapDevToolPlugin(options.context, options.output.sourceMapFilename, "\n//# sourceMappingURL=[url]"));
compiler.apply(new SourceMapDevToolPlugin(options.output.sourceMapFilename, "\n//# sourceMappingURL=[url]"));
else if(options.devtool == "#@sourcemap" || options.devtool == "#@source-map")
compiler.apply(new SourceMapDevToolPlugin(options.context, options.output.sourceMapFilename, "\n/*\n//@ sourceMappingURL=[url]\n//# sourceMappingURL=[url]\n*/"));
compiler.apply(new SourceMapDevToolPlugin(options.output.sourceMapFilename, "\n/*\n//@ sourceMappingURL=[url]\n//# sourceMappingURL=[url]\n*/"));
else if(options.devtool == "inlinesourcemap" ||
options.devtool == "inline-sourcemap" ||
options.devtool == "inline-source-map")
compiler.apply(new SourceMapDevToolPlugin(options.context));
compiler.apply(new SourceMapDevToolPlugin());
else if(options.devtool == "@inlinesourcemap" ||
options.devtool == "@inline-sourcemap" ||
options.devtool == "@inline-source-map")
compiler.apply(new SourceMapDevToolPlugin(options.context, null, "\n/*\n//@ sourceMappingURL=[url]\n*/"));
compiler.apply(new SourceMapDevToolPlugin(null, "\n/*\n//@ sourceMappingURL=[url]\n*/"));
else if(options.devtool == "#inlinesourcemap" ||
options.devtool == "#inline-sourcemap" ||
options.devtool == "#inline-source-map")
compiler.apply(new SourceMapDevToolPlugin(options.context, null, "\n//# sourceMappingURL=[url]"));
compiler.apply(new SourceMapDevToolPlugin(null, "\n//# sourceMappingURL=[url]"));
else if(options.devtool == "#@inlinesourcemap" ||
options.devtool == "#@inline-sourcemap" ||
options.devtool == "#@inline-source-map")
compiler.apply(new SourceMapDevToolPlugin(options.context, null, "\n/*\n//@ sourceMappingURL=[url]\n//# sourceMappingURL=[url]\n*/"));
compiler.apply(new SourceMapDevToolPlugin(null, "\n/*\n//@ sourceMappingURL=[url]\n//# sourceMappingURL=[url]\n*/"));
function itemToPlugin(item, name) {
if(Array.isArray(item))
@ -149,6 +150,7 @@ WebpackOptionsApply.prototype.process = function(options, compiler) {
}
if(options.prefetch) {
compiler.apply(new MovedToPluginWarningPlugin("prefetch", "PrefetchPlugin"));
var PrefetchPlugin = require("./PrefetchPlugin");
options.prefetch.map(function(request) {
compiler.apply(new PrefetchPlugin(options.context, request));
@ -157,7 +159,7 @@ WebpackOptionsApply.prototype.process = function(options, compiler) {
compiler.apply(
new CompatibilityPlugin(),
new LoaderPlugin(),
new NodeStuffPlugin(options.node, options.context),
new NodeStuffPlugin(options.node),
new RequireJsStuffPlugin(),
new APIPlugin(),
new ConstPlugin(),
@ -165,8 +167,7 @@ WebpackOptionsApply.prototype.process = function(options, compiler) {
new RequireEnsurePlugin(),
new RequireContextPlugin(options.resolve.modulesDirectories, options.resolve.extensions),
new AMDPlugin(options.amd || {}),
new CommonJsPlugin(),
new LabeledModulesPlugin()
new CommonJsPlugin()
);
compiler.apply(
@ -179,29 +180,34 @@ WebpackOptionsApply.prototype.process = function(options, compiler) {
compiler.apply(new RecordIdsPlugin());
if(options.optimize && options.optimize.occurenceOrder) {
compiler.apply(new MovedToPluginWarningPlugin("optimize.occurenceOrder", "optimize.OccurenceOrderPlugin"));
var OccurenceOrderPlugin = require("./optimize/OccurenceOrderPlugin");
compiler.apply(new OccurenceOrderPlugin(options.optimize.occurenceOrderPreferEntry));
}
if(options.optimize && options.optimize.minChunkSize) {
compiler.apply(new MovedToPluginWarningPlugin("optimize.minChunkSize", "optimize.MinChunkSizePlugin"));
var MinChunkSizePlugin = require("./optimize/MinChunkSizePlugin");
compiler.apply(new MinChunkSizePlugin(options.optimize));
}
if(options.optimize && options.optimize.maxChunks) {
compiler.apply(new MovedToPluginWarningPlugin("optimize.maxChunks", "optimize.LimitChunkCountPlugin"));
var LimitChunkCountPlugin = require("./optimize/LimitChunkCountPlugin");
compiler.apply(new LimitChunkCountPlugin(options.optimize));
}
if(options.optimize.minimize) {
compiler.apply(new MovedToPluginWarningPlugin("optimize.minimize", "optimize.UglifyJsPlugin"));
var UglifyJsPlugin = require("./optimize/UglifyJsPlugin");
if(options.optimize.minimize === true)
compiler.apply(new UglifyJsPlugin(options.context));
compiler.apply(new UglifyJsPlugin());
else
compiler.apply(new UglifyJsPlugin(options.context, options.optimize.minimize));
compiler.apply(new UglifyJsPlugin(options.optimize.minimize));
}
if(options.optimize.dedupe === true) {
compiler.apply(new MovedToPluginWarningPlugin("optimize.dedupe", "optimize.DedupePlugin"));
var DedupePlugin = require("./optimize/DedupePlugin");
compiler.apply(new DedupePlugin());
}
@ -212,23 +218,23 @@ WebpackOptionsApply.prototype.process = function(options, compiler) {
}
if(typeof options.provide === "object") {
compiler.apply(new MovedToPluginWarningPlugin("provide", "ProvidePlugin"));
var ProvidePlugin = require("./ProvidePlugin");
for(var name in options.provide) {
compiler.apply(new ProvidePlugin(name, options.provide[name]));
}
compiler.apply(new ProvidePlugin(name, options.provide));
}
if(options.define !== false) {
if(options.define) {
compiler.apply(new MovedToPluginWarningPlugin("define", "DefinePlugin"));
var defineObject = {};
if(typeof options.define === "object") {
Object.keys(options.define).forEach(function(key) {
defineObject[key] = options.define[key];
});
}
if(defineObject.DEBUG === undefined)
defineObject.DEBUG = !!options.debug;
compiler.apply(new DefinePlugin(defineObject));
}
if(options.defineDebug !== false)
compiler.apply(new DefinePlugin({ DEBUG: !!options.debug }));
compiler.applyPlugins("after-plugins", compiler);
compiler.resolvers.normal.apply(

View File

@ -13,7 +13,6 @@ function WebpackOptionsDefaulter() {
this.set("target", "web");
this.set("output", {});
this.set("node", {});
this.set("optimize", {});
this.set("resolve", {});
this.set("resolveLoader", {});

View File

@ -100,89 +100,91 @@ DedupePlugin.prototype.apply = function(compiler) {
});
}
});
compiler.moduleTemplate = new DedupModuleTemplateDecorator(compiler.moduleTemplate);
compiler.mainTemplate = Object.create(compiler.mainTemplate);
var oldRenderAddModule = compiler.mainTemplate.renderAddModule;
compiler.mainTemplate.renderAddModule = function(hash, chunk, varModuleId, varModule) {
if(!chunk._DedupePlugin_hasDeduplicatedModules) {
return oldRenderAddModule.call(this, hash, chunk, varModuleId, varModule);
}
return [
"var _m = " + varModule + ";",
"",
"// Check if module is deduplicated",
"switch(typeof _m) {",
"case \"number\":",
this.indent([
"// Module is a copy of another module",
"modules[" + varModuleId + "] = modules[_m];",
"break;"
]),
"case \"object\":",
this.indent([
"// Module can be created from a template",
"modules[" + varModuleId + "] = (function(_m) {",
this.indent([
"var args = _m.slice(1), fn = modules[_m[0]];",
"return function (a,b,c) {",
this.indent([
"fn.apply(this, [a,b,c].concat(args));"
]),
"};"
]),
"}(_m));",
"break;"
]),
"default:",
this.indent([
"// Normal module",
"modules[" + varModuleId + "] = _m;"
]),
"}"
]
};
var oldRenderModules = compiler.mainTemplate.renderModules;
compiler.mainTemplate.renderModules = function renderModules(hash, chunk, moduleTemplate, dependencyTemplates) {
if(!chunk._DedupePlugin_hasDeduplicatedModules) {
return oldRenderModules.call(this, hash, chunk, moduleTemplate, dependencyTemplates);
}
var source = new ConcatSource();
source.add("(function(modules) {\n");
source.add(this.indent([
"// Check all modules for deduplicated modules",
"for(var i in modules) {",
this.indent([
"switch(typeof modules[i]) {",
compiler.plugin("after-plugins", function(compiler) {
compiler.moduleTemplate = new DedupModuleTemplateDecorator(compiler.moduleTemplate);
compiler.mainTemplate = Object.create(compiler.mainTemplate);
var oldRenderAddModule = compiler.mainTemplate.renderAddModule;
compiler.mainTemplate.renderAddModule = function(hash, chunk, varModuleId, varModule) {
if(!chunk._DedupePlugin_hasDeduplicatedModules) {
return oldRenderAddModule.call(this, hash, chunk, varModuleId, varModule);
}
return [
"var _m = " + varModule + ";",
"",
"// Check if module is deduplicated",
"switch(typeof _m) {",
"case \"number\":",
this.indent([
"// Module is a copy of another module",
"modules[i] = modules[modules[i]];",
"modules[" + varModuleId + "] = modules[_m];",
"break;"
]),
"case \"object\":",
this.indent([
"// Module can be created from a template",
"modules[i] = (function(_m) {",
"modules[" + varModuleId + "] = (function(_m) {",
this.indent([
"var args = _m.slice(1), fn = modules[_m[0]];",
"return function (a,b,c) {",
this.indent([
"fn.apply(null, [a,b,c].concat(args));"
"fn.apply(this, [a,b,c].concat(args));"
]),
"};"
]),
"}(modules[i]));"
"}(_m));",
"break;"
]),
"default:",
this.indent([
"// Normal module",
"modules[" + varModuleId + "] = _m;"
]),
"}"
]),
"}",
"return modules;"
]));
source.add("\n}(");
source.add(oldRenderModules.call(this, hash, chunk, moduleTemplate, dependencyTemplates));
source.add("))");
return source;
};
]
};
var oldRenderModules = compiler.mainTemplate.renderModules;
compiler.mainTemplate.renderModules = function renderModules(hash, chunk, moduleTemplate, dependencyTemplates) {
if(!chunk._DedupePlugin_hasDeduplicatedModules) {
return oldRenderModules.call(this, hash, chunk, moduleTemplate, dependencyTemplates);
}
var source = new ConcatSource();
source.add("(function(modules) {\n");
source.add(this.indent([
"// Check all modules for deduplicated modules",
"for(var i in modules) {",
this.indent([
"switch(typeof modules[i]) {",
"case \"number\":",
this.indent([
"// Module is a copy of another module",
"modules[i] = modules[modules[i]];",
"break;"
]),
"case \"object\":",
this.indent([
"// Module can be created from a template",
"modules[i] = (function(_m) {",
this.indent([
"var args = _m.slice(1), fn = modules[_m[0]];",
"return function (a,b,c) {",
this.indent([
"fn.apply(null, [a,b,c].concat(args));"
]),
"};"
]),
"}(modules[i]));"
]),
"}"
]),
"}",
"return modules;"
]));
source.add("\n}(");
source.add(oldRenderModules.call(this, hash, chunk, moduleTemplate, dependencyTemplates));
source.add("))");
return source;
};
});
};
function DedupModuleTemplateDecorator(template) {

View File

@ -7,18 +7,17 @@ var SourceMapSource = require("webpack-core/lib/SourceMapSource");
var RequestShortener = require("../RequestShortener");
var uglify = require("uglify-js");
function UglifyJsPlugin(context, options) {
function UglifyJsPlugin(options) {
if(typeof options !== "object") options = {};
if(typeof options.compressor !== "undefined") {
options.compress = options.compressor;
}
this.options = options;
this.requestShortener = new RequestShortener(context);
}
module.exports = UglifyJsPlugin;
UglifyJsPlugin.prototype.apply = function(compiler) {
var options = this.options;
var requestShortener = this.requestShortener;
var requestShortener = new RequestShortener(compiler.context);
compiler.plugin("compilation", function(compilation) {
compilation.plugin("build-module", function(module) {
// to get detailed location info about errors

View File

@ -23,9 +23,43 @@ function webpack(options, callback) {
}
return compiler;
}
module.exports = webpack;
exports = module.exports = webpack;
webpack.WebpackOptionsDefaulter = WebpackOptionsDefaulter;
webpack.WebpackOptionsApply = WebpackOptionsApply;
webpack.Compiler = Compiler;
webpack.NodeEnvironmentPlugin = NodeEnvironmentPlugin;
function exportPlugins(exports, path, plugins) {
plugins.forEach(function(name) {
Object.defineProperty(exports, name, {
configurable: false,
enumerable: true,
get: function() {
return require(path + "/" + name);
}
});
});
}
exportPlugins(exports, ".", [
"DefinePlugin",
"NormalModuleReplacementPlugin",
"ContextReplacementPlugin",
"IgnorePlugin",
"BannerPlugin",
"PrefetchPlugin",
"ProvidePlugin",
"HotModuleReplacementPlugin",
]);
exportPlugins(exports.optimize = {}, "./optimize", [
"CommonsChunkPlugin",
"DedupePlugin",
"LimitChunkCountPlugin",
"MinChunkSizePlugin",
"OccurenceOrderPlugin",
"UglifyJsPlugin"
]);
exportPlugins(exports.dependencies = {}, "./dependencies", [
"LabeledModulesPlugin"
]);

View File

@ -1,6 +1,6 @@
{
"name": "webpack",
"version": "0.11.15",
"version": "1.0.0-beta1",
"author": "Tobias Koppers @sokra",
"description": "Packs CommonJs/AMD/Labeled 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.",
"dependencies": {

View File

@ -16,7 +16,9 @@ describe("HotModuleReplacementPlugin", function() {
output: {
path: path.join(__dirname, "js")
},
hot: true
plugins: [
new webpack.HotModuleReplacementPlugin()
]
});
fs.writeFileSync(entryFile, "1", "utf-8");
compiler.run(function(err, stats) {

View File

@ -40,21 +40,6 @@ describe("Integration", function() {
}
]
},
optimize: {
maxChunks: 2,
},
define: {
CONST_TRUE: true,
CONST_FALSE: false,
CONST_FUNCTION: function() { return "ok"; },
CONST_NUMBER: 123,
CONST_NUMBER_EXPR: "1*100+23",
CONST_OBJECT: {
A: 1,
B: JSON.stringify("B"),
C: function() { return "C"; }
}
},
amd: {
fromOptions: true
},
@ -63,13 +48,28 @@ describe("Integration", function() {
// so it is injected here
alias: { should: require.resolve("should") }
},
plugins: {
"after-environment": function() {
this.resolver.plugin("module-resolved", function(request, callback) {
callback(null, request.replace(/extra\.js/, "extra2.js"));
plugins: [
new webpack.optimize.LimitChunkCountPlugin(1),
new webpack.DefinePlugin({
CONST_TRUE: true,
CONST_FALSE: false,
CONST_FUNCTION: function() { return "ok"; },
CONST_NUMBER: 123,
CONST_NUMBER_EXPR: "1*100+23",
CONST_OBJECT: {
A: 1,
B: JSON.stringify("B"),
C: function() { return "C"; }
}
}),
function() {
this.plugin("after-environment", function() {
this.resolver.plugin("module-resolved", function(request, callback) {
callback(null, request.replace(/extra\.js/, "extra2.js"));
});
});
}
}
]
}, function(err, stats) {
if(err) throw err;
stats.hasErrors().should.be.not.ok;

View File

@ -16,11 +16,10 @@ describe("NodeTemplatePlugin", function() {
library: "abc",
libraryTarget: "commonjs",
},
optimize: {
minimize: true
},
entry: "./entry",
plugins: [
new webpack.optimize.UglifyJsPlugin()
]
}, function(err, stats) {
if(err) return err;
stats.hasErrors().should.be.not.ok;
@ -49,12 +48,11 @@ describe("NodeTemplatePlugin", function() {
library: "def",
libraryTarget: "umd",
},
optimize: {
minimize: true,
maxChunks: 1
},
entry: "./entry",
plugins: [
new webpack.optimize.LimitChunkCountPlugin(1),
new webpack.optimize.UglifyJsPlugin()
]
}, function(err, stats) {
if(err) return err;
stats.hasErrors().should.be.not.ok;

View File

@ -19,14 +19,32 @@ describe("TestCases", function() {
});
[
{ name: "normal" },
{ name: "hot", hot: true },
{ name: "hot", plugins: [
new webpack.HotModuleReplacementPlugin()
]},
{ name: "devtool-eval", devtool: "eval" },
{ name: "devtool-source-map", devtool: "#@source-map" },
{ name: "minimized", optimize: { minimize: true } },
{ name: "deduped", optimize: { dedupe: true } },
{ name: "minimized-deduped", optimize: { minimize: true, dedupe: true } },
{ name: "optimized", optimize: { minimize: true, dedupe: true, occurenceOrder: true } },
{ name: "all-combined", hot: true, devtool: "#@source-map", optimize: { minimize: true, dedupe: true, occurenceOrder: true } }
{ name: "minimized", plugins: [
new webpack.optimize.UglifyJsPlugin()
]},
{ name: "deduped", plugins: [
new webpack.optimize.DedupePlugin()
]},
{ name: "minimized-deduped", plugins: [
new webpack.optimize.DedupePlugin(),
new webpack.optimize.UglifyJsPlugin()
]},
{ name: "optimized", plugins: [
new webpack.optimize.DedupePlugin(),
new webpack.optimize.OccurenceOrderPlugin(),
new webpack.optimize.UglifyJsPlugin()
]},
{ name: "all-combined", devtool: "#@source-map", plugins: [
new webpack.HotModuleReplacementPlugin(),
new webpack.optimize.DedupePlugin(),
new webpack.optimize.OccurenceOrderPlugin(),
new webpack.optimize.UglifyJsPlugin()
]}
].forEach(function(config) {
describe(config.name, function() {
categories.forEach(function(category) {
@ -46,15 +64,16 @@ describe("TestCases", function() {
path: outputDirectory,
filename: "bundle.js"
},
optimize: config.optimize,
hot: config.hot,
module: {
loaders: [
{ test: /\.json$/, loader: "json" },
{ test: /\.coffee$/, loader: "coffee" },
{ test: /\.jade$/, loader: "jade" }
]
}
},
plugins: (config.plugins || []).concat(
new webpack.dependencies.LabeledModulesPlugin()
)
};
webpack(options, function(err, stats) {
if(err) return done(err);

View File

@ -34,9 +34,9 @@ var library1 = cp.spawn("node", join(["../../bin/webpack.js", "--output-pathinfo
bindOutput(library1);
library1.on("exit", function(code) {
if(code === 0) {
// node ../../bin/webpack --output-pathinfo --colors --resolve-alias vm=vm-browserify --output-public-path js/ --module-bind json --module-bind css=style!css --module-bind less=style!css!less --module-bind coffee --module-bind jade --prefetch ./lib/stylesheet.less --optimize-dedupe ./lib/index js/web.js
// node ../../bin/webpack --output-pathinfo --colors --resolve-alias vm=vm-browserify --output-public-path js/ --module-bind json --module-bind css=style!css --module-bind less=style!css!less --module-bind coffee --module-bind jade --prefetch ./lib/stylesheet.less --optimize-dedupe --labeled-modules ./lib/index js/web.js
var main = cp.spawn("node", join(["../../bin/webpack.js", "--output-pathinfo", "--colors", "--resolve-alias", "vm=vm-browserify", "--workers",
"--output-public-path", "js/", "--module-bind", "json", "--module-bind", "css=style!css", "--module-bind", "less=style/url!file?postfix=.css&string!less", "--module-bind", "coffee", "--module-bind", "jade", "--prefetch", "./lib/stylesheet.less", "--optimize-dedupe", "./lib/index", "js/web.js", "--progress"], extraArgs));
"--output-public-path", "js/", "--module-bind", "json", "--module-bind", "css=style!css", "--module-bind", "less=style/url!file?postfix=.css&string!less", "--module-bind", "coffee", "--module-bind", "jade", "--prefetch", "./lib/stylesheet.less", "--optimize-dedupe", "--labeled-modules", "./lib/index", "js/web.js", "--progress"], extraArgs));
bindOutput(main);
}
});

View File

@ -1,3 +1,4 @@
var webpack = require("../../");
module.exports = {
output: {
hashDigestLength: 5
@ -7,35 +8,33 @@ module.exports = {
{ test: /extra2?\.js/, loader: "raw!extra!val?cacheable" }
]
},
optimize: {
maxChunks: 2
},
define: {
CONST_UNDEFINED: undefined,
CONST_NULL: null,
CONST_TRUE: true,
CONST_FALSE: false,
CONST_FUNCTION: function() { return "ok"; },
CONST_NUMBER: 123,
CONST_NUMBER_EXPR: "1*100+23",
CONST_OBJECT: {
A: 1,
B: JSON.stringify("B"),
C: function() { return "C"; }
}
},
amd: {
fromOptions: true
},
provide: {
s3: "submodule3"
},
resolve: {
// cannot resolve should outside the outermost node_modules
// so it is injected here
alias: { should: require.resolve("should") }
},
plugins: [
new webpack.optimize.LimitChunkCountPlugin(2),
new webpack.DefinePlugin({
CONST_UNDEFINED: undefined,
CONST_NULL: null,
CONST_TRUE: true,
CONST_FALSE: false,
CONST_FUNCTION: function() { return "ok"; },
CONST_NUMBER: 123,
CONST_NUMBER_EXPR: "1*100+23",
CONST_OBJECT: {
A: 1,
B: JSON.stringify("B"),
C: function() { return "C"; }
}
}),
new webpack.ProvidePlugin({
s3: "submodule3"
}),
function() {
this.plugin("normal-module-factory", function(nmf) {
nmf.plugin("after-resolve", function(data, callback) {

View File

@ -25,14 +25,9 @@ app.configure(function() {
vm: "vm-browserify"
}
},
optimize: {
minimize: true,
dedupe: true
},
resolve: {
unsafeCache: true
},
hot: true,
cache: true,
recordsPath: path.join(__dirname, "webpack.records.json"),
output: {
@ -40,7 +35,13 @@ app.configure(function() {
path: "/",
filename: "web.js",
chunkFilename: "[chunkhash].chunk.js"
}
},
plugins: [
new webpack.dependencies.LabeledModulesPlugin(),
new webpack.optimize.UglifyJsPlugin(),
new webpack.optimize.DedupePlugin(),
new webpack.HotModuleReplacementPlugin()
]
}), {
lazy: false,
watchDelay: 5000,

View File

@ -1,3 +1,4 @@
var webpack = require("../../");
module.exports = {
entry: ["../../hot/dev-server", "./index.js"],
output: {
@ -5,6 +6,8 @@ module.exports = {
hotUpdateChunkFilename: "[id].[hash].bundle-update.js",
hashDigestLength: 4
},
hot: true, // enable hot module replacement
plugins: [
new webpack.HotModuleReplacementPlugin()
],
recordsPath: __dirname + "/records.json" // this is not required for the webpack-dev-server, but when compiled.
};