Skip to content

Commit 0de7c73

Browse files
committed
SourceMap support
1 parent 6c3f51e commit 0de7c73

32 files changed

Lines changed: 610 additions & 363 deletions

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,15 @@ Check the [documentation](https://github.com/webpack/docs/wiki) if you want to k
1717

1818
# Examples
1919

20-
Take a look at the `examples` folder.
20+
Take a look at the [`examples`](https://github.com/webpack/webpack/tree/master/examples) folder.
2121

2222
# Features
2323

2424
* loaders are chainable
2525
* loaders run in node.js and can do a bunch of stuff
2626
* option to name your file with a hash of the content
2727
* watch mode
28+
* SourceUrl and SourceMap support
2829
* plugin system, extend webpack or build a complete different compiler
2930
* interfaces
3031
* CLI with arguments

bin/config-optimist.js

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@ module.exports = function(optimist) {
1919

2020
.string("output-chunk-file").describe("output-chunk-file")
2121

22+
.string("output-named-chunk-file").describe("output-named-chunk-file")
23+
24+
.string("output-source-map-file").describe("output-source-map-file")
25+
2226
.string("output-public-path").describe("output-public-path")
2327

2428
.boolean("output-pathinfo").describe("output-pathinfo")
@@ -53,5 +57,9 @@ module.exports = function(optimist) {
5357

5458
.string("plugin").describe("plugin")
5559

56-
.boolean("bail").describe("bail");
60+
.boolean("bail").describe("bail")
61+
62+
.boolean("d").describe("d", "shortcut for --debug --devtool sourcemap --output-pathinfo")
63+
64+
.boolean("p").describe("p", "shortcut for --optimize-minimize");
5765
};

bin/convert-argv.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,16 @@ module.exports = function(optimist, argv, convertOptions) {
77

88
var options = {};
99

10+
// Shortcuts
11+
if(argv.d) {
12+
argv.debug = true;
13+
argv["output-pathinfo"] = true;
14+
if(!argv.devtool) argv.devtool = "sourcemap";
15+
}
16+
if(argv.p) {
17+
argv["optimize-minimize"] = true;
18+
}
19+
1020
function ifArg(name, fn, init) {
1121
if(Array.isArray(argv[name])) {
1222
if(init) init();
@@ -148,6 +158,11 @@ module.exports = function(optimist, argv, convertOptions) {
148158
options.output.namedChunkFilename = value;
149159
});
150160

161+
ifArg("output-source-map-file", function(value) {
162+
ensureObject(options, "output");
163+
options.output.sourceMapFilename = value;
164+
});
165+
151166
ifArg("output-public-path", function(value) {
152167
ensureObject(options, "output");
153168
options.output.publicPath = value;

lib/ChunkTemplate.js

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/*
2+
MIT License http://www.opensource.org/licenses/mit-license.php
3+
Author Tobias Koppers @sokra
4+
*/
5+
var ConcatSource = require("webpack-core/lib/ConcatSource");
6+
var Template = require("./Template");
7+
8+
function ChunkTemplate(outputOptions) {
9+
Template.call(this, outputOptions);
10+
}
11+
12+
module.exports = ChunkTemplate;
13+
14+
ChunkTemplate.prototype = Object.create(Template.prototype);
15+
ChunkTemplate.prototype.render = function(chunk, moduleTemplate, dependencyTemplates) {
16+
var source = new ConcatSource();
17+
source.add(this.asString(this.renderHeader(chunk)));
18+
chunk.modules.forEach(function(module, idx) {
19+
if(idx != 0) source.add(",\n");
20+
source.add("\n/***/ " + module.id + ":\n");
21+
source.add(moduleTemplate.render(module, dependencyTemplates));
22+
});
23+
source.add("\n\n");
24+
source.add(this.asString(this.renderFooter(chunk)));
25+
return source;
26+
};
27+
28+
ChunkTemplate.prototype.renderHeader = function(chunk) {
29+
return ["{\n"];
30+
};
31+
32+
ChunkTemplate.prototype.renderFooter = function(chunk) {
33+
return ["}"];
34+
};
35+
36+
ChunkTemplate.prototype.updateHash = function(hash) {
37+
hash.update("template");
38+
hash.update("jsonp");
39+
hash.update("2");
40+
hash.update(this.outputOptions.jsonpFunction + "");
41+
hash.update(this.outputOptions.library + "");
42+
};

lib/Compilation.js

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ var Module = require("./Module");
1414
var ArrayMap = require("./ArrayMap");
1515
var Chunk = require("./Chunk");
1616
var Stats = require("./Stats");
17+
var Template = require("./Template");
1718

1819
function Compilation(compiler) {
1920
Tapable.call(this);
@@ -77,6 +78,10 @@ Compilation.prototype.getModule = function(module) {
7778
return this._modules[identifier];
7879
};
7980

81+
Compilation.prototype.findModule = function(identifier) {
82+
return this._modules[identifier];
83+
};
84+
8085
Compilation.prototype.buildModule = function(module, callback) {
8186
this.applyPlugins("build-module", module);
8287
module.build(this.options, this, this.resolvers.normal, this.inputFileSystem, function(err) {
@@ -278,6 +283,7 @@ Compilation.prototype.seal = function seal(callback) {
278283
this.summarizeDependencies();
279284
this.applyPluginsAsync("optimize-chunk-assets", this.chunks, function(err) {
280285
if(err) return callback(err);
286+
this.applyPlugins("after-optimize-chunk-assets", this.chunks);
281287
this.applyPluginsAsync("optimize-assets", this.assets, function(err) {
282288
if(err) return callback(err);
283289
this.applyPlugins("after-optimize-assets", this.assets);
@@ -457,13 +463,10 @@ Compilation.prototype.summarizeDependencies = function summarizeDependencies() {
457463
this.contextDependencies = filterDups(this.contextDependencies);
458464
};
459465

460-
var REGEXP_ID = /\[id\]/g;
461-
var REGEXP_NAME = /\[name\]/g;
462-
var REGEXP_HASH = /\[hash\]/g;
463466
Compilation.prototype.createChunkAssets = function createChunkAssets() {
464467
var outputOptions = this.outputOptions || {};
465468
var filename = outputOptions.filename || "bundle.js";
466-
var chunkFilename = outputOptions.chunkFilename || "[id]." + filename.replace(REGEXP_NAME, "");
469+
var chunkFilename = outputOptions.chunkFilename || "[id]." + filename.replace(Template.REGEXP_NAME, "");
467470
var namedChunkFilename = outputOptions.namedChunkFilename || null;
468471
var hash = new (require("crypto").Hash)("md5");
469472
this.mainTemplate.updateHash(hash);
@@ -479,7 +482,9 @@ Compilation.prototype.createChunkAssets = function createChunkAssets() {
479482
var module = this.modules[i];
480483
if(module.assets) {
481484
Object.keys(module.assets).forEach(function(name) {
482-
this.assets[name.replace(REGEXP_HASH, hash)] = module.assets[name];
485+
var file = name.replace(Template.REGEXP_HASH, hash);
486+
this.assets[file] = module.assets[name];
487+
this.applyPlugins("module-asset", module, file);
483488
}, this);
484489
}
485490
}
@@ -490,15 +495,32 @@ Compilation.prototype.createChunkAssets = function createChunkAssets() {
490495
var file;
491496
if(chunk.entry) {
492497
source = this.mainTemplate.render(hash, chunk, this.moduleTemplate, this.dependencyTemplates);
493-
this.assets[file = filename.replace(REGEXP_HASH, hash).replace(REGEXP_ID, chunk.id).replace(REGEXP_NAME, chunk.name || "")] = source;
498+
this.assets[
499+
file = filename
500+
.replace(Template.REGEXP_HASH, hash)
501+
.replace(Template.REGEXP_ID, chunk.id)
502+
.replace(Template.REGEXP_NAME, chunk.name || "")
503+
] = source;
494504
chunk.files.push(file);
505+
this.applyPlugins("chunk-asset", chunk, file);
495506
} else {
496507
source = this.chunkTemplate.render(chunk, this.moduleTemplate, this.dependencyTemplates);
497-
this.assets[file = chunkFilename.replace(REGEXP_HASH, hash).replace(REGEXP_ID, chunk.id)] = source;
508+
this.assets[
509+
file = chunkFilename
510+
.replace(Template.REGEXP_HASH, hash)
511+
.replace(Template.REGEXP_ID, chunk.id)
512+
] = source;
498513
chunk.files.push(file);
514+
this.applyPlugins("chunk-asset", chunk, file);
499515
if(namedChunkFilename && chunk.name) {
500-
this.assets[file = namedChunkFilename.replace(REGEXP_HASH, hash).replace(REGEXP_ID, chunk.id).replace(REGEXP_NAME, chunk.name || "")] = source;
516+
this.assets[
517+
file = namedChunkFilename
518+
.replace(Template.REGEXP_HASH, hash)
519+
.replace(Template.REGEXP_ID, chunk.id)
520+
.replace(Template.REGEXP_NAME, chunk.name || "")
521+
] = source;
501522
chunk.files.push(file);
523+
this.applyPlugins("chunk-asset", chunk, file);
502524
}
503525
}
504526
}

lib/Compiler.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,7 @@ Compiler.prototype.emitAssets = function(compilation, callback) {
172172

173173
require("async").forEach(Object.keys(compilation.assets), function(file, callback) {
174174

175-
if(file.indexOf("/")) {
175+
if(file.indexOf("/") >= 0) {
176176
var idx = file.lastIndexOf("/");
177177
var dir = file.substr(0, idx);
178178
this.outputFileSystem.mkdirp(this.outputFileSystem.join(this.outputPath, dir), writeOut.bind(this));

lib/ContextModule.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
Author Tobias Koppers @sokra
44
*/
55
var Module = require("./Module");
6-
var RawSource = require("webpack-core/lib/RawSource");
6+
var OriginalSource = require("webpack-core/lib/OriginalSource");
77

88
function ContextModule(resolveDependencies, context, recursive, regExp, addon) {
99
Module.call(this);
@@ -97,7 +97,7 @@ ContextModule.prototype.source = function(dependencyTemplates, outputOptions, re
9797
"webpackContext.resolve = webpackContextResolve;\n",
9898
"module.exports = webpackContext;\n",
9999
];
100-
return new RawSource(str.join(""));
100+
return new OriginalSource(str.join(""), this.identifier());
101101
};
102102

103103
ContextModule.prototype.size = function() {

lib/DependenciesBlockVariable.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22
MIT License http://www.opensource.org/licenses/mit-license.php
33
Author Tobias Koppers @sokra
44
*/
5-
var ReplaceSource = require("./ReplaceSource");
6-
var StringSource = require("webpack-core/lib/RawSource");
5+
var ReplaceSource = require("webpack-core/lib/ReplaceSource");
6+
var RawSource = require("webpack-core/lib/RawSource");
77

88
function DependenciesBlockVariable(name, expression, dependencies) {
99
this.name = name;
@@ -21,7 +21,7 @@ DependenciesBlockVariable.prototype.updateHash = function(hash) {
2121
};
2222

2323
DependenciesBlockVariable.prototype.expressionSource = function(dependencyTemplates, outputOptions, requestShortener) {
24-
var source = new ReplaceSource(new StringSource(this.expression));
24+
var source = new ReplaceSource(new RawSource(this.expression));
2525
this.dependencies.forEach(function(dep) {
2626
var template = dependencyTemplates.get(dep.Class);
2727
if(!template) throw new Error("No template for dependency: " + dep.Class.name);

lib/EvalDevToolModuleTemplateDecorator.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ EvalDevToolModuleTemplateDecorator.prototype.render = function(module, dependenc
1818
"// WEBPACK FOOTER",
1919
"// module.id = " + module.id,
2020
"// module.readableIdentifier = " + module.readableIdentifier(requestShortener),
21-
"//@ sourceURL=webpack-module:///" + encodeURI(module.readableIdentifier(requestShortener) + "(" + module.id + ")").replace(/%2F/g, "/").replace(/%20/g, "_").replace(/%5E/g, "^").replace(/%5C/g, "\\").replace(/\?/, "%3F").replace(/^\//, "")
21+
"//@ sourceURL=webpack-module:///" + encodeURI(module.readableIdentifier(requestShortener)).replace(/%2F/g, "/").replace(/%20/g, "_").replace(/%5E/g, "^").replace(/%5C/g, "\\").replace(/\?/, "%3F").replace(/^\//, "")
2222
].join("\n");
2323
return new RawSource("eval(" + JSON.stringify(content + footer) + ");" );
2424
},

lib/FunctionModuleTemplate.js

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
MIT License http://www.opensource.org/licenses/mit-license.php
33
Author Tobias Koppers @sokra
44
*/
5-
var RawSource = require("webpack-core/lib/RawSource");
5+
var ConcatSource = require("webpack-core/lib/ConcatSource");
66

77
function FunctionModuleTemplate(outputOptions, requestShortener) {
88
this.outputOptions = outputOptions || {};
@@ -11,18 +11,17 @@ function FunctionModuleTemplate(outputOptions, requestShortener) {
1111
module.exports = FunctionModuleTemplate;
1212

1313
FunctionModuleTemplate.prototype.render = function(module, dependencyTemplates) {
14-
var buf = [];
14+
var source = new ConcatSource();
1515
if(this.outputOptions.pathinfo) {
1616
var req = module.readableIdentifier(this.requestShortener);
17-
buf.push("/*!****" + req.replace(/./g, "*") + "****!*\\\n");
18-
buf.push(" !*** " + req.replace(/\*\//g, "*_/") + " ***!\n");
19-
buf.push(" \\****" + req.replace(/./g, "*") + "****/\n");
17+
source.add("/*!****" + req.replace(/./g, "*") + "****!*\\\n");
18+
source.add(" !*** " + req.replace(/\*\//g, "*_/") + " ***!\n");
19+
source.add(" \\****" + req.replace(/./g, "*") + "****/\n");
2020
}
21-
buf.push("/***/ function(module, exports, require) {\n\n");
22-
var source = module.source(dependencyTemplates, this.outputOptions, this.requestShortener);
23-
buf.push("\t" + source.source().replace(/\r?\n/g, "\n\t"));
24-
buf.push("\n\n/***/ }");
25-
return new RawSource(buf.join(""));
21+
source.add("/***/ function(module, exports, require) {\n\n");
22+
source.add(module.source(dependencyTemplates, this.outputOptions, this.requestShortener));
23+
source.add("\n\n/***/ }");
24+
return source;
2625
};
2726

2827
FunctionModuleTemplate.prototype.updateHash = function(hash) {

0 commit comments

Comments
 (0)