Skip to content

Commit 2eeb492

Browse files
committed
API: loaderContext.depencency is more relaxed and don't need to be called before reading
API: loader.seperable cannot combined with loaderContext.emitFile and loaderContext.emitSubStats loaderContext.options.resolve loaderContext.options.events loaderContext.resolve and .sync API: added profile option (and --profile) API: added workers option (and --workers) API: added closeWorkers option API: if option workers is used: options must be JSON.stringify-able. Except options.resolve and options.events. Any error thrown in loader must be an object (i. e. an Error object). Only message, stack and value of toString is passed to main process. API: The expected Cache object for options.cache has changed. API: event module is emited after the module is finished. API: event context is now named context-enum API: added event context which is emited after the context is finished. API: event dependency is removed. Use stats.dependencies for this. API: event loader is removed. Use stats.loaders for this. API: added stats.contexts as a list of contexts. API: added stats...modules[..].dependencies for as list of files which affect the module's content. API: added stats...modules[..].loaders for as list of loaders which affect the module's content. API: removed stats.modulesPerChunk, it is useless and was deprecated. API: added stats.chunkNameFiles which export the files for named chunks API: added stats.startTime, timestamp as number cmd: more colorful output to indicate caching and timing API: webpack in watch mode emits the event watch-end if watch mode have to end (i. e. loader changed). You may restart it after clearing require.cache. API: added loaderContext.loaderType as one of loader, preLoader or postLoader. API: added loaderContext.currentLoaders as list of all loader of the current type. API: added loaderContext.loaderIndex as index of current loader in loaderContext.currentLoaders. API: added loaderContext.loaders, loaderContext.preLoaders and loaderContext.postLoaders.
1 parent ab35703 commit 2eeb492

13 files changed

Lines changed: 590 additions & 289 deletions

File tree

README.md

Lines changed: 52 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -325,21 +325,23 @@ if invoked without arguments it prints a usage:
325325
Usage: webpack <options> <input> <output>
326326
327327
Options:
328-
--min Minimize it with uglifyjs [boolean] [default: false]
329-
--filenames Output Filenames Into File [boolean] [default: false]
330-
--options Options JSON File [string]
331-
--public-prefix Path Prefix For JavaScript Loading [string]
332-
--libary Stores the exports into this variable [string]
333-
--colors Output Stats with colors [boolean] [default: false]
334-
--single Disable lazy loading [boolean] [default: false]
335-
--json Output Stats as JSON [boolean] [default: false]
336-
--by-size Sort modules by size in Stats [boolean] [default: false]
337-
--verbose Output dependencies in Stats [boolean] [default: false]
338-
--alias Set a alias name for a module. ex. http=http-browserify [string]
339-
--debug Prints debug info to output files [boolean] [default: false]
340-
--watch Recompiles on changes (except loaders) [boolean] [default: false]
341-
--watch-delay Timeout to wait for the last change [string]
342-
--progress Displays a progress while compiling [boolean] [default: false]
328+
--min Minimize it with uglifyjs [boolean] [default: false]
329+
--filenames Output Filenames Into File [boolean] [default: false]
330+
--options Options JSON File [string]
331+
--public-prefix Path Prefix For JavaScript Loading [string]
332+
--libary Stores the exports into this variable [string]
333+
--colors Output Stats with colors [boolean] [default: false]
334+
--single Disable lazy loading [boolean] [default: false]
335+
--json Output Stats as JSON [boolean] [default: false]
336+
--by-size Sort modules by size in Stats [boolean] [default: false]
337+
--verbose Output dependencies in Stats [boolean] [default: false]
338+
--profile Capture timings for modules [boolean] [default: false]
339+
--alias Set a alias name for a module. ex. http=http-browserify [string]
340+
--debug Prints debug info to output files [boolean] [default: false]
341+
--watch Recompiles on changes (except loaders) [boolean] [default: false]
342+
--watch-delay Timeout to wait for the last change
343+
--workers Use worker processes to be faster (BETA) [boolean] [default: false]
344+
--progress Displays a progress while compiling [boolean] [default: false]
343345
```
344346

345347
### Programmatically Usage
@@ -407,12 +409,11 @@ You can also save this options object in a JSON file and use it with the shell c
407409
// "bundle-invalid" () fired when the bundle gets invalid
408410
// [bundle-invalid is only fired in watch mode]
409411
// "start-writing" (hash) fired when webpack starts writing
410-
// -- events for dependencies --
411-
// "module" (module, filename) before a module is loaded
412-
// "context" (module, dirname) before a context is loaded
413-
// "dependency" (filename) before a dependency is loaded
414-
// "static-dependency"(filename) after a dependency is flagged as not recompile-able
415-
// "loader" (filename) before a loader is required
412+
// "watch-end" () watch ended because of loader change
413+
// -- events for modules --
414+
// "module" (module, filename) after a module is loaded
415+
// "context-enum" (module, dirname) before a context is enumerated
416+
// "context" (module, dirname) after a context is loaded
416417
// -- events for progress --
417418
// "task" (name?) start of a task
418419
// "task-end" (name?) end of a task
@@ -513,6 +514,26 @@ You can also save this options object in a JSON file and use it with the shell c
513514
// syntax like resolve.loaders
514515
// all loaders which matches the file are applied before the
515516
// normal loaders. This cannot be overridden in the require call.
517+
518+
workers: true,
519+
// default: false
520+
// options: true, false, number > 0, object of type webpack/lib/Workers
521+
// Use worker processes to do some work.
522+
// This *can* boost performance, but starting these processes has some
523+
// overhead (~100-200ms). If loaders are used they need to have the
524+
// seperable flag to work in worker process. If they havn't they work in
525+
// the main process.
526+
// In watch mode, worker processes only start once. So workers = true
527+
// is recommended for watch mode.
528+
529+
closeWorkers: false,
530+
// default: true
531+
// close the worker processes on webpack exit.
532+
533+
profile: true,
534+
// default: false
535+
// capture timings for the build.
536+
// they are stored in the stats
516537
}
517538
```
518539

@@ -525,6 +546,7 @@ else `stats` as json:
525546
``` javascript
526547
{
527548
hash: "52bd9213...38d",
549+
startTime: 237467691, // in ms since 1.1.1990
528550
time: 1234, // in ms
529551
chunkCount: 2,
530552
modulesCount: 10,
@@ -534,13 +556,20 @@ else `stats` as json:
534556
"output.js": 1234,
535557
"1.output.js": 2345
536558
},
559+
chunkNameFiles: {
560+
"main": "output.js",
561+
"namedChunk": "1.output.js"
562+
}
537563
warnings: [ "Some warning" ],
538564
errors: [ "Some error" ],
539565
fileModules: {
540566
"output.js": [
541567
{ id: 0, size: 123, filename: "/home/.../main.js", reasons: [
542568
{ type: "main" }
543-
]},
569+
],
570+
dependencies: [ "filename", ... ],
571+
loaders: [ "filename of loader", ... ]
572+
},
544573
{ id: 1, size: 234, filename: "...", reasons: [
545574
{ type: "require", // or "context", "async require", "async context"
546575
count: 2,
@@ -919,9 +948,7 @@ You are also welcome to correct any spelling mistakes or any language issues, be
919948

920949
## Future plans
921950

922-
* more and better polyfills for node.js buildin modules
923-
* cache in folder and allow reuseing it
924-
* write it into the wiki if you have more ideas...
951+
see [/webpack/webpack/wiki/Ideas](wiki Ideas)
925952

926953
## License
927954

bin/webpack.js

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,10 @@ var argv = require("optimist")
5656
.describe("verbose", "Output dependencies in Stats")
5757
.default("verbose", false)
5858

59+
.boolean("profile")
60+
.describe("profile", "Capture timings for modules")
61+
.default("profile", false)
62+
5963
.string("alias")
6064
.describe("alias", "Set a alias name for a module. ex. http=http-browserify")
6165

@@ -67,10 +71,13 @@ var argv = require("optimist")
6771
.describe("watch", "Recompiles on changes (except loaders)")
6872
.default("watch", false)
6973

70-
.string("watch-delay")
7174
.describe("watch-delay", "Timeout to wait for the last change")
7275
.default("watch", false)
7376

77+
.boolean("workers")
78+
.describe("workers", "Use worker processes to be faster (BETA)")
79+
.default("workers", false)
80+
7481
.boolean("progress")
7582
.describe("progress", "Displays a progress while compiling")
7683
.default("progress", false)
@@ -122,8 +129,16 @@ if(argv.watch) {
122129
options.watch = true;
123130
}
124131

132+
if(argv.workers) {
133+
options.workers = true;
134+
}
135+
136+
if(argv.profile) {
137+
options.profile = true;
138+
}
139+
125140
if(argv["watch-delay"]) {
126-
options.watchDelay = parseInt(argv["watch-delay"], 10);
141+
options.watchDelay = argv["watch-delay"];
127142
}
128143

129144
if(argv.filenames) {
@@ -164,17 +179,25 @@ if(argv.progress) {
164179
if(!options.events) options.events = new (require("events").EventEmitter)();
165180
var events = options.events;
166181

182+
var nextUpdate = 0;
167183
var sum = 0;
168184
var finished = 0;
169185
var chars = 0;
170-
function print() {
186+
function print(force) {
187+
if(!force && nextUpdate > new Date().getTime()) return;
188+
nextUpdate = new Date().getTime() + 100;
171189
var msg = "";
172190
if(sum > 0) {
191+
var precentage = Math.floor(finished*100/sum);
173192
msg += "compiling... (" + c("\033[1m\033[33m");
174193
msg += sprintf("%4s", finished+"") + "/" + sprintf("%4s", sum+"");
175-
msg += " " + sprintf("%4s", Math.floor(finished*100/sum)+"%");
194+
msg += " " + sprintf("%4s", precentage+"%");
176195
msg += c("\033[39m\033[22m") + ")";
196+
for(var i = 0; i < Math.floor(precentage/2); i++)
197+
msg += "#";
177198
}
199+
for(var i = msg.length; i < chars; i++)
200+
msg += " ";
178201
for(var i = 0; i < chars; i++)
179202
process.stderr.write("\b");
180203
process.stderr.write(msg);
@@ -191,6 +214,7 @@ if(argv.progress) {
191214
process.stderr.write("\b \b");
192215
process.stderr.write(name + " " + c("\033[1m\033[32m") + "done" + c("\033[39m\033[22m") + "\n");
193216
chars = 0;
217+
return print(true);
194218
}
195219
print();
196220
});
@@ -210,7 +234,7 @@ webpack(input, options, function(err, stats) {
210234
return;
211235
}
212236
if(argv.json)
213-
console.log(JSON.stringify(stats));
237+
console.log(JSON.stringify(stats, null, 2));
214238
else {
215239
console.log(formatOutput(stats, {
216240
colors: argv.colors,

bm.js

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
var webpack = require("./lib/webpack");
66
var path = require("path");
77

8-
var TIMES = 5;
8+
var TIMES = 2;
99

1010
/* TESTS */
1111

@@ -27,22 +27,29 @@ var testCases = {
2727
var TESTS = {}
2828

2929
Object.keys(testCases).forEach(function(name) {
30-
TESTS[name + " "] = runWebpack.bind(null, name, testCases[name], false, false, false);
31-
TESTS[name + " single "] = runWebpack.bind(null, name, testCases[name], true, false, false);
32-
TESTS[name + " debug "] = runWebpack.bind(null, name, testCases[name], false, true, false);
33-
TESTS[name + " single debug "] = runWebpack.bind(null, name, testCases[name], true, true, false);
34-
TESTS[name + " min"] = runWebpack.bind(null, name, testCases[name], false, false, true );
35-
TESTS[name + " single min"] = runWebpack.bind(null, name, testCases[name], true, false, true );
36-
TESTS[name + " debug min"] = runWebpack.bind(null, name, testCases[name], false, true, true );
37-
TESTS[name + " single debug min"] = runWebpack.bind(null, name, testCases[name], true, true, true );
30+
TESTS[name + " "] = runWebpack.bind(null, name, testCases[name], false, false, false, false);
31+
TESTS[name + " workers"] = runWebpack.bind(null, name, testCases[name], false, false, false, true);
32+
TESTS[name + " single "] = runWebpack.bind(null, name, testCases[name], true, false, false, false);
33+
TESTS[name + " single workers"] = runWebpack.bind(null, name, testCases[name], true, false, false, true);
34+
TESTS[name + " debug "] = runWebpack.bind(null, name, testCases[name], false, true, false, false);
35+
TESTS[name + " debug workers"] = runWebpack.bind(null, name, testCases[name], false, true, false, true);
36+
TESTS[name + " single debug "] = runWebpack.bind(null, name, testCases[name], true, true, false, false);
37+
TESTS[name + " single debug workers"] = runWebpack.bind(null, name, testCases[name], true, true, false, true);
38+
TESTS[name + " min "] = runWebpack.bind(null, name, testCases[name], false, false, true , false);
39+
TESTS[name + " min workers"] = runWebpack.bind(null, name, testCases[name], false, false, true , true);
40+
TESTS[name + " single min "] = runWebpack.bind(null, name, testCases[name], true, false, true , false);
41+
TESTS[name + " single min workers"] = runWebpack.bind(null, name, testCases[name], true, false, true , true);
3842
});
3943

40-
function runWebpack(name, file, single, debug, min, cb) {
44+
var workers = new (require("./lib/Workers"))(path.join(__dirname, "lib", "buildModuleFork.js"), require("os").cpus().length)
45+
function runWebpack(name, file, single, debug, min, withWorkers, cb) {
4146
webpack(file, {
4247
output: path.join(root, "js", "bm", name.trim() + ".js"),
4348
single: single,
4449
debug: debug,
45-
minimize: min
50+
minimize: min,
51+
workers: withWorkers && workers,
52+
closeWorkers: false
4653
}, cb);
4754
}
4855

@@ -60,7 +67,9 @@ asyncForEach(Object.keys(TESTS), function(name, done) {
6067
done();
6168
});
6269
});
63-
}, function() {});
70+
}, function() {
71+
workers.close();
72+
});
6473

6574
/* HELPERS */
6675

lib/Cache.js

Lines changed: 26 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ var fs = require("fs");
66

77
function Cache(options) {
88
this.options = options = options || {};
9+
if(!this.options.stat) this.options.stat = fs.stat;
910
this.map = {};
1011
}
1112
var $ = Cache.prototype;
@@ -18,14 +19,14 @@ $.get = function(request, callback) {
1819
var count = item.files.length;
1920
var invalid = false;
2021
item.files.forEach(function(file) {
21-
fs.stat(file.path, function(err, stat) {
22+
this.options.stat(file.path, function(err, stat) {
2223
if(err) return invalidate(err.toString());
2324
if(!stat) return invalidate("Cannot read stat");
2425
if(stat.mtime.getTime() !== file.time)
2526
return invalidate("File " + file.path + " has changed");
2627
valid();
2728
});
28-
});
29+
}, this);
2930
if(item.files.length === 0) valid();
3031
function invalidate(msg) {
3132
if(invalid) return;
@@ -40,27 +41,27 @@ $.get = function(request, callback) {
4041
}
4142
}
4243

43-
$.create = function(request) {
44-
var self = this;
45-
var item = {
46-
files: []
47-
};
48-
var cacheEntry = {
49-
add: function(path) {
50-
item.files.push({
51-
path: path,
52-
// TODO do it asynchronly
53-
time: fs.statSync(path).mtime.getTime()
54-
});
55-
},
56-
clear: function() {
57-
item.files.length = 0;
58-
},
59-
save: function(value) {
60-
item.value = value;
61-
self.map[request] = item;
62-
cacheEntry.saved = true;
44+
$.store = function(request, dependencies, startTime, value) {
45+
var count = dependencies.length + 1;
46+
var files = [];
47+
var endOne = function() {
48+
if(--count == 0) {
49+
this.map[request] = {
50+
files: files,
51+
value: value
52+
}
6353
}
64-
}
65-
return cacheEntry;
66-
}
54+
}.bind(this);
55+
dependencies.forEach(function(file) {
56+
this.options.stat(file, function(err, stat) {
57+
if(err) return; // do not cache it.
58+
if(stat.mtime.getTime() > startTime.getTime()) return; // do not cache it.
59+
files.unshift({
60+
path: file,
61+
time: stat.mtime.getTime()
62+
});
63+
endOne();
64+
});
65+
}, this);
66+
endOne();
67+
}

0 commit comments

Comments
 (0)