added option to prefetch modules

This commit is contained in:
Tobias Koppers 2013-05-13 13:34:00 +02:00
parent 96275187cc
commit 209f96c543
10 changed files with 122 additions and 24 deletions

View File

@ -55,6 +55,8 @@ module.exports = function(optimist) {
.boolean("optimize-occurence-order").describe("optimize-occurence-order")
.string("prefetch").describe("prefetch")
.string("provide").describe("provide")
.string("plugin").describe("plugin")

View File

@ -255,6 +255,11 @@ module.exports = function(optimist, argv, convertOptions) {
options.optimize.occurenceOrder = true;
});
ifArg("prefetch", function(request) {
ensureArray(options, "prefetch");
options.prefetch.push(request);
});
ifArg("provide", function(value) {
ensureObject(options, "provide");
var idx = value.indexOf("=");

View File

@ -234,63 +234,106 @@ Compilation.prototype.processModuleDependencies = function(module, callback) {
});
};
Compilation.prototype.addEntry = function process(context, entry, name, callback) {
Compilation.prototype._addModuleChain = function process(context, dependency, onModule, callback) {
var errorAndCallback = this.bail ? function errorAndCallback(err) {
callback(err);
} : function errorAndCallback(err) {
err.dependencies = [entry];
err.dependencies = [dependency];
this.errors.push(err);
callback();
}.bind(this);
if(!(typeof entry == "object" && entry != null && entry.Class))
return callback(new Error("Parameter 'entry' must be a Dependency"));
if(!(typeof dependency == "object" && dependency != null && dependency.Class))
throw new Error("Parameter 'dependency' must be a Dependency");
var moduleFactory = this.dependencyFactories.get(entry.Class);
var moduleFactory = this.dependencyFactories.get(dependency.Class);
if(!moduleFactory)
return callback(new Error("No dependency factory availible for this entry dependency type: " + entry.Class.name));
throw new Error("No dependency factory availible for this dependency type: " + dependency.Class.name);
moduleFactory.create(context, entry, function(err, module) {
if(this.profile) var start = +new Date();
moduleFactory.create(context, dependency, function(err, module) {
if(err) return errorAndCallback(new EntryModuleNotFoundError(err));
if(this.profile) {
if(!module.profile) module.profile = {};
var afterFactory = +new Date();
module.profile.factory = afterFactory - start;
}
var result = this.addModule(module);
if(!result) {
return callback(new Error("Entry module is already added"));
module = this.getModule(module);
onModule(module);
return callback(null, module);
}
if(result instanceof Module) {
if(this.profile) {
result.profile = module.profile;
}
module = result;
}
this.entries.push(module);
module.id = 0;
onModule(module);
if(result instanceof Module) {
entryReady.call(this);
moduleReady.call(this);
} else {
this.buildModule(module, function(err) {
if(err) return errorAndCallback(err);
entryReady.call(this);
if(this.profile) {
var afterBuilding = +new Date();
module.profile.building = afterBuilding - afterFactory;
}
moduleReady.call(this);
}.bind(this));
}
function entryReady() {
function moduleReady() {
this.processModuleDependencies(module, function(err) {
if(err) return callback(err);
var chunk = this.addChunk(name);
chunk.id = 0;
chunk.entry = true;
chunk.addModule(module);
module.addChunk(chunk);
this.processDependenciesBlockForChunk(module, chunk);
return callback();
return callback(null, module);
}.bind(this));
}
}.bind(this));
};
Compilation.prototype.addEntry = function process(context, entry, name, callback) {
this._addModuleChain(context, entry, function(module) {
this.entries.push(module);
module.id = 0;
}.bind(this), function(err, module) {
if(err) return callback(err);
if(module) {
var chunk = this.addChunk(name);
chunk.id = 0;
chunk.entry = true;
chunk.addModule(module);
module.addChunk(chunk);
this.processDependenciesBlockForChunk(module, chunk);
}
return callback();
}.bind(this));
};
Compilation.prototype.prefetch = function process(context, dependency, callback) {
this._addModuleChain(context, dependency, function(module) {
module.prefetched = true;
}, callback);
};
Compilation.prototype.seal = function seal(callback) {
this.applyPlugins("seal");
this.applyPlugins("optimize");

View File

@ -278,7 +278,7 @@ Compiler.prototype.compile = function(callback) {
var compilation = this.newCompilation(params);
this.applyPluginsAsync("make", compilation, function(err) {
this.applyPluginsParallel("make", compilation, function(err) {
if(err) return callback(err);
compilation.seal(function(err) {

21
lib/PrefetchPlugin.js Normal file
View File

@ -0,0 +1,21 @@
/*
MIT License http://www.opensource.org/licenses/mit-license.php
Author Tobias Koppers @sokra
*/
var PrefetchDependency = require("./dependencies/PrefetchDependency");
function PrefetchPlugin(context, request) {
this.context = context;
this.request = request;
}
module.exports = PrefetchPlugin;
PrefetchPlugin.prototype.apply = function(compiler) {
compiler.plugin("compilation", function(compilation, params) {
var normalModuleFactory = params.normalModuleFactory;
compilation.dependencyFactories.set(PrefetchDependency, normalModuleFactory);
});
compiler.plugin("make", function(compilation, callback) {
compilation.prefetch(this.context, new PrefetchDependency(this.request), callback);
}.bind(this));
};

View File

@ -114,6 +114,7 @@ Stats.prototype.toJson = function toJson(options, forToString) {
size: module.size(),
cacheable: !!module.cacheable,
built: !!module.built,
prefetched: !!module.prefetched,
chunks: module.chunks.map(function(chunk) {
return chunk.id;
}),
@ -406,6 +407,9 @@ Stats.jsonToString = function jsonToString(obj, useColors) {
if(module.built) {
green(" [built]");
}
if(module.prefetched) {
magenta(" [prefetched]");
}
if(module.chunks) {
module.chunks.forEach(function(chunk) {
normal(" {");
@ -453,6 +457,9 @@ Stats.jsonToString = function jsonToString(obj, useColors) {
if(module.built) {
green(" [built]");
}
if(module.prefetched) {
magenta(" [prefetched]");
}
if(module.chunks) {
module.chunks.forEach(function(chunk) {
normal(" {");

View File

@ -12,6 +12,7 @@ var EvalDevToolModulePlugin = require("./EvalDevToolModulePlugin");
var SourceMapDevToolPlugin = require("./SourceMapDevToolPlugin");
var LibraryTemplatePlugin = require("./LibraryTemplatePlugin");
var PrefetchPlugin = require("./PrefetchPlugin");
var SingleEntryPlugin = require("./SingleEntryPlugin");
var MultiEntryPlugin = require("./MultiEntryPlugin");
var CachePlugin = require("./CachePlugin");
@ -111,6 +112,11 @@ WebpackOptionsApply.prototype.process = function(options, compiler) {
compiler.apply(itemToPlugin(options.entry[name], name));
});
}
if(options.prefetch) {
options.prefetch.map(function(request) {
compiler.apply(new PrefetchPlugin(options.context, request));
});
}
compiler.apply(
new CompatibilityPlugin(),
new NodeStuffPlugin(options.node),

View File

@ -0,0 +1,14 @@
/*
MIT License http://www.opensource.org/licenses/mit-license.php
Author Tobias Koppers @sokra
*/
var ModuleDependency = require("./ModuleDependency");
function PrefetchDependency(request) {
ModuleDependency.call(this, request);
this.Class = PrefetchDependency;
}
module.exports = PrefetchDependency;
PrefetchDependency.prototype = Object.create(ModuleDependency.prototype);
PrefetchDependency.prototype.type = "prefetch";

View File

@ -1,6 +1,6 @@
{
"name": "webpack",
"version": "0.10.0-beta10",
"version": "0.10.0-beta11",
"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

@ -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 ./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 ./less/stylesheet.less ./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", "./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", "./less/stylesheet.less", "./lib/index", "js/web.js", "--progress"], extraArgs));
bindOutput(main);
}
});