Skip to content

Commit 5104661

Browse files
committed
optional externals
track optional modules optional externals for UMD and root fixes webpack#339
1 parent ca46619 commit 5104661

File tree

11 files changed

+93
-10
lines changed

11 files changed

+93
-10
lines changed

lib/Compilation.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,10 @@ Compilation.prototype.addModuleDependencies = function(module, dependencies, bai
228228
if(!newModule) { // from cache
229229
dependantModule = this.getModule(dependantModule);
230230

231+
if(dependantModule.optional) {
232+
dependantModule.optional = isOptional();
233+
}
234+
231235
if(dependantModule.id === 0) {
232236
return errorOrWarningAndCallback(
233237
new ModuleNotFoundError(module, new Error("a dependency to an entry point is not allowed"))
@@ -257,6 +261,7 @@ Compilation.prototype.addModuleDependencies = function(module, dependencies, bai
257261
newModule.profile = dependantModule.profile;
258262
}
259263

264+
newModule.optional = isOptional();
260265
newModule.issuer = dependantModule.issuer;
261266
dependantModule = newModule;
262267

@@ -272,6 +277,8 @@ Compilation.prototype.addModuleDependencies = function(module, dependencies, bai
272277
}
273278
}
274279

280+
dependantModule.optional = isOptional();
281+
275282
dependencies.forEach(function(dep) {
276283
dep.module = dependantModule;
277284
dependantModule.addReason(module, dep);

lib/ExternalModule.js

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
var Module = require("./Module");
66
var OriginalSource = require("webpack-core/lib/OriginalSource");
77
var RawSource = require("webpack-core/lib/RawSource");
8+
var WebpackMissingModule = require("./dependencies/WebpackMissingModule");
89

910
function ExternalModule(request, type) {
1011
Module.call(this);
@@ -61,10 +62,18 @@ ExternalModule.prototype.source = function(dependencyTemplates, outputOptions, r
6162
break;
6263
case "amd":
6364
case "umd":
64-
str = "module.exports = __WEBPACK_EXTERNAL_MODULE_" + this.id + "__;";
65+
str = "";
66+
if(this.optional) {
67+
str += "if(typeof __WEBPACK_EXTERNAL_MODULE_" + this.id + "__ === 'undefined') {" + WebpackMissingModule.moduleCode(request) + "}\n";
68+
}
69+
str += "module.exports = __WEBPACK_EXTERNAL_MODULE_" + this.id + "__;";
6570
break;
6671
default:
67-
str = "module.exports = " + request + ";";
72+
str = "";
73+
if(this.optional) {
74+
str += "if(typeof " + request + " === 'undefined') {" + WebpackMissingModule.moduleCode(request) + "}\n";
75+
}
76+
str += "module.exports = " + request + ";";
6877
break;
6978
}
7079
if(this.useSourceMap) {

lib/Stats.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,7 @@ Stats.prototype.toJson = function toJson(options, forToString) {
121121
size: module.size(),
122122
cacheable: !!module.cacheable,
123123
built: !!module.built,
124+
optional: !!module.optional,
124125
prefetched: !!module.prefetched,
125126
chunks: module.chunks.map(function(chunk) {
126127
return chunk.id;
@@ -409,6 +410,9 @@ Stats.jsonToString = function jsonToString(obj, useColors) {
409410
if(!module.cacheable) {
410411
red(" [not cacheable]");
411412
}
413+
if(!module.optional) {
414+
yellow(" [optional]");
415+
}
412416
if(module.built) {
413417
green(" [built]");
414418
}

lib/UmdMainTemplatePlugin.js

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,9 +54,13 @@ UmdMainTemplatePlugin.prototype.apply = function(mainTemplate) {
5454
var request = m.request;
5555
if(typeof request === "object") request = request[type];
5656
if(Array.isArray(request)) {
57-
return "require(" + JSON.stringify(request[0]) + ")" + accessorToObjectAccess(request.slice(1));
57+
var expr = "require(" + JSON.stringify(request[0]) + ")" + accessorToObjectAccess(request.slice(1));
5858
} else
59-
return "require(" + JSON.stringify(request) + ")";
59+
var expr = "require(" + JSON.stringify(request) + ")";
60+
if(m.optional) {
61+
expr = "(function webpackLoadOptionalExternalModule() { try { return " + expr + "; } catch(e) {} }())";
62+
}
63+
return expr;
6064
}).join(", "));
6165
}
6266
var externalsArguments = externals.map(function(m) {

lib/dependencies/WebpackMissingModule.js

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,21 @@
33
Author Tobias Koppers @sokra
44
*/
55
exports.module = function(request) {
6-
return "!(function webpackMissingModule() { "+
7-
"var e = new Error(" + JSON.stringify("Cannot find module \"" + request + "\"") + "); "+
8-
"e.code = 'MODULE_NOT_FOUND'; "+
9-
"throw e; "+
10-
"}())";
6+
return "!(function webpackMissingModule() { " +
7+
exports.moduleCode(request) +
8+
" }())";
119
};
10+
11+
exports.moduleCode = function(request) {
12+
return "var e = new Error(" + JSON.stringify("Cannot find module \"" + request + "\"") + "); " +
13+
"e.code = 'MODULE_NOT_FOUND'; " +
14+
"throw e;";
15+
};
16+
1217
exports.moduleMetaInfo = function(request) {
1318
return "!(function webpackMissingModuleMetaInfo() { "+
1419
"var e = new Error(" + JSON.stringify("Module cannot be imported because no meta info about exports is available \"" + request + "\"") + "); "+
1520
"e.code = 'MODULE_NOT_FOUND'; "+
1621
"throw e; "+
1722
"}())";
18-
};
23+
};
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
it("should not fail on optional externals", function() {
2+
try {
3+
require("external");
4+
} catch(e) {
5+
e.should.be.instanceof(Error);
6+
e.code.should.be.eql("MODULE_NOT_FOUND");
7+
return;
8+
}
9+
throw new Error("It doesn't fail");
10+
});
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
module.exports = {
2+
output: {
3+
libraryTarget: "commonjs2"
4+
},
5+
externals: {
6+
external: "external"
7+
}
8+
};
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
it("should not fail on optional externals", function() {
2+
try {
3+
require("external");
4+
} catch(e) {
5+
e.should.be.instanceof(Error);
6+
e.code.should.be.eql("MODULE_NOT_FOUND");
7+
return;
8+
}
9+
throw new Error("It doesn't fail");
10+
});
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
module.exports = {
2+
output: {
3+
libraryTarget: "var"
4+
},
5+
externals: {
6+
external: "external"
7+
}
8+
};
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
it("should not fail on optional externals", function() {
2+
try {
3+
require("external");
4+
} catch(e) {
5+
e.should.be.instanceof(Error);
6+
e.code.should.be.eql("MODULE_NOT_FOUND");
7+
return;
8+
}
9+
throw new Error("It doesn't fail");
10+
});

0 commit comments

Comments
 (0)