Skip to content

Commit a37948d

Browse files
committed
added options.define, evaluate conditionals, fixes webpack#99
1 parent d9f470d commit a37948d

File tree

7 files changed

+131
-19
lines changed

7 files changed

+131
-19
lines changed

lib/BasicEvaluatedExpression.js

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,25 @@ BasicEvaluatedExpression.prototype.isArray = function() {
2828
BasicEvaluatedExpression.prototype.isWrapped = function() {
2929
return Object.prototype.hasOwnProperty.call(this, "prefix");
3030
};
31+
BasicEvaluatedExpression.prototype.asBool = function() {
32+
if(this.isBoolean()) return this.bool;
33+
else if(this.isString()) return !!this.string;
34+
else if(this.isNumber()) return !!this.number;
35+
else if(this.isRegExp()) return true;
36+
else if(this.isArray()) return true;
37+
else if(this.isWrapped()) return this.prefix || this.postfix ? true : undefined;
38+
return undefined;
39+
};
40+
BasicEvaluatedExpression.prototype.set = function(value) {
41+
if(typeof value === "string") return this.setString(value);
42+
if(typeof value === "number") return this.setNumber(value);
43+
if(typeof value === "boolean") return this.setBoolean(value);
44+
if(value instanceof RegExp) return this.setRegExp(value);
45+
if(Array.isArray(value)) return this.setItems(value.map(function(item) {
46+
return new BasicEvaluatedExpression().set(item);
47+
}));
48+
return this;
49+
};
3150
BasicEvaluatedExpression.prototype.setString = function(str) {
3251
if(str === null)
3352
delete this.string;

lib/ConstPlugin.js

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,20 @@ ConstPlugin.prototype.apply = function(compiler) {
1818
});
1919
compiler.parser.plugin("statement if", function(statement) {
2020
var param = this.evaluateExpression(statement.test);
21-
if(param.isBoolean()) {
22-
this.state.current.addDependency(new ConstDependency(param.bool + "", param.range));
23-
return param.bool;
21+
var bool = param.asBool();
22+
if(typeof bool === "boolean") {
23+
if(statement.test.type !== "Literal")
24+
this.state.current.addDependency(new ConstDependency(bool + "", param.range));
25+
return bool;
26+
}
27+
});
28+
compiler.parser.plugin("expression ?:", function(expression) {
29+
var param = this.evaluateExpression(expression.test);
30+
var bool = param.asBool();
31+
if(typeof bool === "boolean") {
32+
if(expression.test.type !== "Literal")
33+
this.state.current.addDependency(new ConstDependency(bool + "", param.range));
34+
return bool;
2435
}
2536
});
2637
compiler.parser.plugin("evaluate Identifier __resourceQuery", function(expr) {

lib/DefinePlugin.js

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
/*
2+
MIT License http://www.opensource.org/licenses/mit-license.php
3+
Author Tobias Koppers @sokra
4+
*/
5+
var ConstDependency = require("./dependencies/ConstDependency");
6+
var BasicEvaluatedExpression = require("./BasicEvaluatedExpression");
7+
8+
function DefinePlugin(definitions) {
9+
this.definitions = definitions;
10+
}
11+
module.exports = DefinePlugin;
12+
DefinePlugin.prototype.apply = function(compiler) {
13+
var definitions = this.definitions;
14+
Object.keys(definitions).forEach(function(key) {
15+
var value = definitions[key];
16+
var code = "(" + JSON.stringify(value, function(key, value) {
17+
if(typeof value === "function") return value.toString();
18+
if(value instanceof RegExp) return value.toString();
19+
if(value instanceof Date) return "new Date(" + value.getTime() + ")";
20+
return value;
21+
}) + ")";
22+
compiler.parser.plugin("evaluate Identifier " + key, function(expr) {
23+
var res = new BasicEvaluatedExpression();
24+
res.set(value);
25+
res.setRange(expr.range);
26+
return res;
27+
});
28+
compiler.parser.plugin("evaluate typeof " + key, function(expr) {
29+
var res = new BasicEvaluatedExpression();
30+
res.setString(typeof value);
31+
res.setRange(expr.range);
32+
return res;
33+
});
34+
compiler.parser.plugin("expression " + key, function(expr) {
35+
var dep = new ConstDependency(code, expr.range);
36+
dep.loc = expr.loc;
37+
this.state.current.addDependency(dep);
38+
return true;
39+
});
40+
compiler.parser.plugin("typeof " + key, function(expr) {
41+
var dep = new ConstDependency(JSON.stringify(typeof value), expr.range);
42+
dep.loc = expr.loc;
43+
this.state.current.addDependency(dep);
44+
return true;
45+
});
46+
});
47+
};

lib/Parser.js

Lines changed: 30 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -192,18 +192,24 @@ Parser.prototype.initializeEvaluating = function() {
192192
return new BasicEvaluatedExpression().setString(result).setRange(expr.range);
193193
});
194194
this.plugin("evaluate ConditionalExpression", function(expr) {
195-
var consequent = this.evaluateExpression(expr.consequent);
196-
var alternate = this.evaluateExpression(expr.alternate);
197-
if(!consequent || !alternate) return;
198-
var res = new BasicEvaluatedExpression();
199-
if(consequent.isConditional())
200-
res.setOptions(consequent.options);
201-
else
202-
res.setOptions([consequent]);
203-
if(alternate.isConditional())
204-
res.addOptions(alternate.options);
205-
else
206-
res.addOptions([alternate]);
195+
var condition = this.evaluateExpression(expr.test);
196+
var conditionValue = condition.asBool();
197+
if(conditionValue === undefined) {
198+
var consequent = this.evaluateExpression(expr.consequent);
199+
var alternate = this.evaluateExpression(expr.alternate);
200+
if(!consequent || !alternate) return;
201+
var res = new BasicEvaluatedExpression();
202+
if(consequent.isConditional())
203+
res.setOptions(consequent.options);
204+
else
205+
res.setOptions([consequent]);
206+
if(alternate.isConditional())
207+
res.addOptions(alternate.options);
208+
else
209+
res.addOptions([alternate]);
210+
} else {
211+
var res = this.evaluateExpression(conditionValue ? expr.consequent : expr.alternate);
212+
}
207213
res.setRange(expr.range);
208214
return res;
209215
});
@@ -414,9 +420,18 @@ Parser.prototype.walkExpression = function walkExpression(expression) {
414420
this.walkExpression(expression.right);
415421
break;
416422
case "ConditionalExpression":
417-
this.walkExpression(expression.test);
418-
this.walkExpression(expression.alternate);
419-
this.walkExpression(expression.consequent);
423+
var result = this.applyPluginsBailResult("expression ?:", expression);
424+
if(result === undefined) {
425+
this.walkExpression(expression.test);
426+
this.walkExpression(expression.consequent);
427+
if(expression.alternate)
428+
this.walkExpression(expression.alternate);
429+
} else {
430+
if(result)
431+
this.walkExpression(expression.consequent);
432+
else if(expression.alternate)
433+
this.walkExpression(expression.alternate);
434+
}
420435
break;
421436
case "NewExpression":
422437
this.walkExpression(expression.callee);

lib/WebpackOptionsApply.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ var ConstPlugin = require("./ConstPlugin");
1717
var RequireJsStuffPlugin = require("./RequireJsStuffPlugin");
1818
var NodeStuffPlugin = require("./NodeStuffPlugin");
1919
var CompatibilityPlugin = require("./CompatibilityPlugin");
20+
var DefinePlugin = require("./DefinePlugin");
2021

2122
var CommonJsPlugin = require("./dependencies/CommonJsPlugin");
2223
var AMDPlugin = require("./dependencies/AMDPlugin");
@@ -214,6 +215,18 @@ WebpackOptionsApply.prototype.process = function(options, compiler) {
214215
}
215216
}
216217

218+
if(options.define !== false) {
219+
var defineObject = {};
220+
if(typeof options.define === "object") {
221+
Object.keys(options.define).forEach(function(key) {
222+
defineObject[key] = options.define[key];
223+
});
224+
}
225+
if(defineObject.DEBUG === undefined)
226+
defineObject.DEBUG = !!options.debug;
227+
compiler.apply(new DefinePlugin(defineObject));
228+
}
229+
217230
compiler.applyPlugins("after-plugins", compiler);
218231
compiler.resolvers.normal.apply(
219232
new UnsafeCachePlugin(options.resolve.unsafeCache),

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "webpack",
3-
"version": "0.11.0-beta16",
3+
"version": "0.11.0-beta17",
44
"author": "Tobias Koppers @sokra",
55
"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.",
66
"dependencies": {

test/browsertest/lib/index.web.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,13 @@ describe("main", function() {
196196
if(typeof module != "object") module = require("fail");
197197
if(typeof exports == "undefined") exports = require("fail");
198198
});
199+
200+
it("should define DEBUG", function() {
201+
DEBUG.should.be.eql(false);
202+
(typeof DEBUG).should.be.eql("boolean");
203+
var x = require(DEBUG ? "fail" : "./a");
204+
var y = DEBUG ? require("fail") : require("./a");
205+
});
199206
});
200207

201208
describe("polyfilling", function() {

0 commit comments

Comments
 (0)