Skip to content

Commit cf30eee

Browse files
committed
Merge branch 'master' into webpack-2
Conflicts: lib/ChunkTemplate.js lib/Compilation.js lib/HotModuleReplacement.runtime.js test/TestCases.test.js test/statsCases/chunks/expected.txt test/statsCases/simple-more-info/expected.txt test/statsCases/simple/expected.txt
2 parents d98df52 + df4e2e4 commit cf30eee

40 files changed

Lines changed: 352 additions & 118 deletions

README.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
# Introduction
88

9-
webpack is a bundler for modules. The main purpose is to bundle javascript
9+
webpack is a bundler for modules. The main purpose is to bundle JavaScript
1010
files for usage in a browser, yet it is also capable of transforming, bundling,
1111
or packaging just about any resource or asset.
1212

@@ -16,7 +16,7 @@ or packaging just about any resource or asset.
1616
* Bundles both [CommonJs](http://www.commonjs.org/specs/modules/1.0/) and [AMD](https://github.com/amdjs/amdjs-api/wiki/AMD) modules (even combined).
1717
* Can create a single bundle or multiple chunks that are asynchronously loaded at runtime (to reduce initial loading time).
1818
* Dependencies are resolved during compilation reducing the runtime size.
19-
* Loaders can preprocess files while compiling, e.g. coffeescript to javascript, handlebars strings to compiled functions, images to Base64, etc.
19+
* Loaders can preprocess files while compiling, e.g. coffeescript to JavaScript, handlebars strings to compiled functions, images to Base64, etc.
2020
* Highly modular plugin system to do whatever else your application requires.
2121

2222
# Getting Started
@@ -56,7 +56,7 @@ and incredibly **fast** on incremental compilations.
5656
## Loaders
5757

5858
webpack enables use of loaders to preprocess files. This allows you to bundle
59-
**any static resource** way beyond javascript. You can easily [write your own
59+
**any static resource** way beyond JavaScript. You can easily [write your own
6060
loaders](http://webpack.github.io/docs/loaders.html) using node.js.
6161

6262
Loaders are activated by using `loadername!` prefixes in `require()` statements,
@@ -128,7 +128,7 @@ loaded asynchronously at runtime. This reduces the initial loading time.
128128
## Optimizations
129129

130130
webpack can do many optimizations to **reduce the output size of your
131-
javascript** by deduplicating frequently used modules, minifying, and giving
131+
JavaScript** by deduplicating frequently used modules, minifying, and giving
132132
you full control of what is loaded initially and what is loaded at runtime
133133
through code splitting. It can also can make your code chunks **cache
134134
friendly** by using hashes.
@@ -240,7 +240,7 @@ MIT (http://www.opensource.org/licenses/mit-license.php)
240240

241241
(In chronological order)
242242

243-
* @google for [Google Web Toolkit (GWT)](https://code.google.com/p/google-web-toolkit), which aims to compile Java to Javascript. It features a similar [Code Splitting](https://code.google.com/p/google-web-toolkit/wiki/CodeSplitting) as webpack.
243+
* @google for [Google Web Toolkit (GWT)](https://code.google.com/p/google-web-toolkit), which aims to compile Java to JavaScript. It features a similar [Code Splitting](https://code.google.com/p/google-web-toolkit/wiki/CodeSplitting) as webpack.
244244
* @medikoo for [modules-webmake](https://github.com/medikoo/modules-webmake), which is a simlar project. webpack was born because I wanted Code Splitting for modules-webpack. Interestingly the [Code Splitting issue is still open](https://github.com/medikoo/modules-webmake/issues/7) (thanks also to @Phoscur for the discussion).
245245
* @substack for [browserify](http://browserify.org/), which is a similar project and source for many ideas.
246246
* @jrburke for [require.js](http://requirejs.org/), which is a similar project and source for many ideas.

bin/convert-argv.js

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,23 @@ module.exports = function(optimist, argv, convertOptions) {
2828

2929
var configFileLoaded = false;
3030
var configPath, ext;
31+
var extensions = Object.keys(interpret.extensions).sort(function(a, b){
32+
return a.length - b.length;
33+
});
34+
3135
if (argv.config) {
3236
configPath = path.resolve(argv.config);
33-
ext = path.extname(configPath);
37+
for (var i = extensions.length - 1; i >= 0; i--) {
38+
var tmpExt = extensions[i];
39+
if (configPath.indexOf(tmpExt, configPath.length - tmpExt.length) > -1){
40+
ext = tmpExt;
41+
break;
42+
}
43+
};
44+
if (!ext) {
45+
ext = path.extname(configPath);
46+
}
3447
} else {
35-
var extensions = Object.keys(interpret.extensions);
3648
for(var i = 0; i < extensions.length; i++) {
3749
var webpackConfig = path.resolve('webpack.config' + extensions[i]);
3850
if(fs.existsSync(webpackConfig)) {
@@ -396,8 +408,10 @@ module.exports = function(optimist, argv, convertOptions) {
396408

397409
ifArg("optimize-min-chunk-size", function(value) {
398410
ensureArray(options, "plugins");
399-
var LimitChunkSizePlugin = require("../lib/optimize/LimitChunkSizePlugin");
400-
options.plugins.push(new LimitChunkSizePlugin(parseInt(value, 10)));
411+
var MinChunkSizePlugin = require("../lib/optimize/MinChunkSizePlugin");
412+
options.plugins.push(new MinChunkSizePlugin({
413+
minChunkSize: parseInt(value, 10)
414+
}));
401415
});
402416

403417
ifBooleanArg("optimize-minimize", function() {

lib/ChunkRenderError.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
/*
2+
MIT License http://www.opensource.org/licenses/mit-license.php
3+
Author Tobias Koppers @sokra
4+
*/
5+
function ChunkRenderError(chunk, file, error) {
6+
Error.call(this);
7+
Error.captureStackTrace(this, ChunkRenderError);
8+
this.name = "ChunkRenderError";
9+
this.error = error;
10+
this.message = error.message;
11+
this.details = error.stack;
12+
this.file = file;
13+
this.chunk = chunk;
14+
}
15+
module.exports = ChunkRenderError;
16+
17+
ChunkRenderError.prototype = Object.create(Error.prototype);

lib/ChunkTemplate.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,3 +30,8 @@ ChunkTemplate.prototype.updateHash = function(hash) {
3030
hash.update("2");
3131
this.applyPlugins("hash", hash);
3232
};
33+
34+
ChunkTemplate.prototype.updateHashForChunk = function(hash, chunk) {
35+
this.updateHash(hash);
36+
this.applyPlugins("hash-for-chunk", hash, chunk);
37+
};

lib/Compilation.js

Lines changed: 35 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ var ChunkTemplate = require("./ChunkTemplate");
1717
var HotUpdateChunkTemplate = require("./HotUpdateChunkTemplate");
1818
var ModuleTemplate = require("./ModuleTemplate");
1919
var Dependency = require("./Dependency");
20+
var ChunkRenderError = require("./ChunkRenderError");
2021
var CachedSource = require("webpack-core/lib/CachedSource");
2122

2223
function Compilation(compiler) {
@@ -516,6 +517,7 @@ Compilation.prototype.seal = function seal(callback) {
516517

517518
this.applyPlugins("revive-modules", this.modules, this.records);
518519
this.applyPlugins("optimize-module-order", this.modules);
520+
this.applyPlugins("before-module-ids", this.modules);
519521
this.applyModuleIds();
520522
this.applyPlugins("optimize-module-ids", this.modules);
521523
this.applyPlugins("after-optimize-module-ids", this.modules);
@@ -524,6 +526,7 @@ Compilation.prototype.seal = function seal(callback) {
524526

525527
this.applyPlugins("revive-chunks", this.chunks, this.records);
526528
this.applyPlugins("optimize-chunk-order", this.chunks);
529+
this.applyPlugins("before-chunk-ids", this.chunks);
527530
this.applyChunkIds();
528531
this.applyPlugins("optimize-chunk-ids", this.chunks);
529532
this.applyPlugins("after-optimize-chunk-ids", this.chunks);
@@ -760,7 +763,11 @@ Compilation.prototype.createHash = function createHash() {
760763
chunk = this.chunks[i];
761764
var chunkHash = require("crypto").createHash(hashFunction);
762765
chunk.updateHash(chunkHash);
763-
this.chunkTemplate.updateHash(chunkHash);
766+
if(chunk.entry) {
767+
this.mainTemplate.updateHashForChunk(chunkHash, chunk);
768+
} else {
769+
this.chunkTemplate.updateHashForChunk(chunkHash);
770+
}
764771
this.applyPlugins("chunk-hash", chunk, chunkHash);
765772
chunk.hash = chunkHash.digest(hashDigest);
766773
hash.update(chunk.hash);
@@ -809,30 +816,36 @@ Compilation.prototype.createChunkAssets = function createChunkAssets() {
809816
var filenameTemplate = chunk.filenameTemplate ? chunk.filenameTemplate :
810817
chunk.initial ? filename :
811818
chunkFilename;
812-
var usedHash = !chunk.entry || (this.mainTemplate.useChunkHash && this.mainTemplate.useChunkHash(chunk)) ? chunkHash : this.fullHash;
813-
if(this.cache && this.cache["c" + chunk.id] && this.cache["c" + chunk.id].hash === usedHash) {
814-
source = this.cache["c" + chunk.id].source;
815-
} else {
816-
if(chunk.entry) {
817-
source = this.mainTemplate.render(this.hash, chunk, this.moduleTemplate, this.dependencyTemplates);
819+
try {
820+
var useChunkHash = !chunk.entry || (this.mainTemplate.useChunkHash && this.mainTemplate.useChunkHash(chunk));
821+
var usedHash = useChunkHash ? chunkHash : this.fullHash;
822+
if(this.cache && this.cache["c" + chunk.id] && this.cache["c" + chunk.id].hash === usedHash) {
823+
source = this.cache["c" + chunk.id].source;
818824
} else {
819-
source = this.chunkTemplate.render(chunk, this.moduleTemplate, this.dependencyTemplates);
820-
}
821-
if(this.cache) {
822-
this.cache["c" + chunk.id] = {
823-
hash: usedHash,
824-
source: source = (source instanceof CachedSource ? source : new CachedSource(source))
825-
};
825+
if(chunk.entry) {
826+
source = this.mainTemplate.render(this.hash, chunk, this.moduleTemplate, this.dependencyTemplates);
827+
} else {
828+
source = this.chunkTemplate.render(chunk, this.moduleTemplate, this.dependencyTemplates);
829+
}
830+
if(this.cache) {
831+
this.cache["c" + chunk.id] = {
832+
hash: usedHash,
833+
source: source = (source instanceof CachedSource ? source : new CachedSource(source))
834+
};
835+
}
826836
}
837+
file = this.getPath(filenameTemplate, {
838+
noChunkHash: !useChunkHash,
839+
chunk: chunk
840+
});
841+
if(this.assets[file])
842+
throw new Error("Conflict: Multiple assets emit to the same filename '" + file + "'");
843+
this.assets[file] = source;
844+
chunk.files.push(file);
845+
this.applyPlugins("chunk-asset", chunk, file);
846+
} catch(err) {
847+
this.errors.push(new ChunkRenderError(chunk, file || filenameTemplate, err));
827848
}
828-
file = this.getPath(filenameTemplate, {
829-
chunk: chunk
830-
});
831-
if(this.assets[file])
832-
throw new Error("Conflict: Multiple assets emit to the same filename '" + file + "'");
833-
this.assets[file] = source;
834-
chunk.files.push(file);
835-
this.applyPlugins("chunk-asset", chunk, file);
836849
}
837850
};
838851

lib/HotModuleReplacement.runtime.js

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -71,10 +71,11 @@ module.exports = function() {
7171
hot._selfAccepted = true;
7272
else if(typeof dep === "function")
7373
hot._selfAccepted = dep;
74-
else if(typeof dep === "number")
75-
hot._acceptedDependencies[dep] = callback;
76-
else for(var i = 0; i < dep.length; i++)
74+
else if(typeof dep === "object")
75+
for(var i = 0; i < dep.length; i++)
7776
hot._acceptedDependencies[dep[i]] = callback;
77+
else
78+
hot._acceptedDependencies[dep] = callback;
7879
},
7980
decline: function(dep) {
8081
if(typeof dep === "undefined")
@@ -136,6 +137,10 @@ module.exports = function() {
136137
// The update info
137138
var hotUpdate, hotUpdateNewHash;
138139

140+
function toModuleId(id) {
141+
return (+id) + "" === id ? +id : id;
142+
}
143+
139144
function hotCheck(apply) {
140145
if(hotStatus !== "idle") throw new Error("check() is only allowed in idle status");
141146
hotApplyOnUpdate = apply;
@@ -211,7 +216,7 @@ module.exports = function() {
211216
var outdatedModules = [];
212217
for(var id in hotUpdate) {
213218
if(Object.prototype.hasOwnProperty.call(hotUpdate, id)) {
214-
outdatedModules.push(+id);
219+
outdatedModules.push(toModuleId(id));
215220
}
216221
}
217222
deferred.resolve(outdatedModules);
@@ -235,9 +240,6 @@ module.exports = function() {
235240
if(module.hot._selfDeclined) {
236241
return new Error("Aborted because of self decline: " + moduleId);
237242
}
238-
if(moduleId === 0) {
239-
return;
240-
}
241243
for(var i = 0; i < module.parents.length; i++) {
242244
var parentId = module.parents[i];
243245
var parent = installedModules[parentId];
@@ -274,7 +276,7 @@ module.exports = function() {
274276
var appliedUpdate = {};
275277
for(var id in hotUpdate) {
276278
if(Object.prototype.hasOwnProperty.call(hotUpdate, id)) {
277-
var moduleId = +id;
279+
var moduleId = toModuleId(id);
278280
var result = getAffectedStuff(moduleId);
279281
if(!result) {
280282
if(options.ignoreUnaccepted)

lib/MainTemplate.js

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@ function MainTemplate(outputOptions) {
2121
var buf = [];
2222
if(chunk.entryModule) {
2323
buf.push("// Load entry module and return exports");
24-
buf.push("return " + this.renderRequireFunctionForModule(hash, chunk, this.requireFn + ".s = " + chunk.entryModule.id) +
25-
"(" + this.requireFn + ".s = " + chunk.entryModule.id + ");");
24+
buf.push("return " + this.renderRequireFunctionForModule(hash, chunk, JSON.stringify(chunk.entryModule.id)) +
25+
"(" + this.requireFn + ".s = " + JSON.stringify(chunk.entryModule.id) + ");");
2626
}
2727
return this.asString(buf);
2828
});
@@ -163,6 +163,11 @@ MainTemplate.prototype.updateHash = function(hash) {
163163
this.applyPlugins("hash", hash);
164164
};
165165

166+
MainTemplate.prototype.updateHashForChunk = function(hash, chunk) {
167+
this.updateHash(hash);
168+
this.applyPlugins("hash-for-chunk", hash, chunk);
169+
};
170+
166171
MainTemplate.prototype.useChunkHash = function(chunk) {
167172
var paths = this.applyPluginsWaterfall("global-hash-paths", []);
168173
return !this.applyPluginsBailResult("global-hash", chunk, paths);

lib/MultiModule.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ MultiModule.prototype.source = function(dependencyTemplates, outputOptions) {
4444
str.push("__webpack_require__(");
4545
if(outputOptions.pathinfo)
4646
str.push("/*! " + dep.request + " */");
47-
str.push("" + dep.module.id);
47+
str.push("" + JSON.stringify(dep.module.id));
4848
str.push(")");
4949
} else {
5050
str.push("(function webpackMissingModule() { throw new Error(");

lib/NamedModulesPlugin.js

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
/*
2+
MIT License http://www.opensource.org/licenses/mit-license.php
3+
Author Tobias Koppers @sokra
4+
*/
5+
function NamedModulesPlugin(options) {
6+
this.options = options || {};
7+
}
8+
module.exports = NamedModulesPlugin;
9+
NamedModulesPlugin.prototype.apply = function(compiler) {
10+
compiler.plugin("compilation", function(compilation) {
11+
compilation.plugin("before-module-ids", function(modules) {
12+
modules.forEach(function(module) {
13+
if(module.id === null && module.libIdent) {
14+
module.id = module.libIdent({
15+
context: this.options.context || compiler.options.context
16+
});
17+
}
18+
}, this);
19+
}.bind(this));
20+
}.bind(this));
21+
};

lib/Stats.js

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,10 +74,17 @@ Stats.prototype.toJson = function toJson(options, forToString) {
7474
}
7575
function formatError(e) {
7676
var text = "";
77+
if(typeof e === "string")
78+
e = {message: e};
79+
if(e.chunk) {
80+
text += "chunk " + (e.chunk.name || e.chunk.id) +
81+
(e.chunk.entry ? " [entry]" : e.chunk.initial ? " [initial]" : "") + "\n";
82+
}
83+
if(e.file) {
84+
text += e.file + "\n";
85+
}
7786
if(e.module && e.module.readableIdentifier && typeof e.module.readableIdentifier === "function") {
7887
text += e.module.readableIdentifier(requestShortener) + "\n";
79-
} else if(e.file) {
80-
text += e.file + "\n";
8188
}
8289
text += e.message;
8390
if(showErrorDetails && e.details) text += "\n" + e.details;

0 commit comments

Comments
 (0)