```javascript
const DEBUG = false;
const PRODUCTION = true;
-// Alternative for environments that don't support `const`
-/** @const */ var STAGING = false;
// etc.
```
UglifyJS will notice the constants and, since they cannot be altered, it
will evaluate references to them to the value itself and drop unreachable
code as usual. The build will contain the `const` declarations if you use
-them. If you are targeting < ES6 environments, use `/** @const */ var`.
+them. If you are targeting < ES6 environments which does not support `const`,
+using `var` with `reduce_vars` (enabled by default) should suffice.
<a name="codegen-options"></a>
hoist_vars : false,
if_return : !false_by_default,
join_vars : !false_by_default,
- collapse_vars : false,
- reduce_vars : false,
+ collapse_vars : !false_by_default,
+ reduce_vars : !false_by_default,
cascade : !false_by_default,
side_effects : !false_by_default,
pure_getters : false,
this._evaluating = true;
try {
var d = this.definition();
- if ((d.constant || compressor.option("reduce_vars") && !d.modified) && d.init) {
+ if (compressor.option("reduce_vars") && !d.modified && d.init) {
if (compressor.option("unsafe")) {
if (!HOP(d.init, '_evaluated')) {
d.init._evaluated = ev(d.init, compressor);
return make_node(AST_Infinity, self).transform(compressor);
}
}
- if (compressor.option("evaluate") && !isLHS(self, compressor.parent())) {
+ if (compressor.option("evaluate")
+ && compressor.option("reduce_vars")
+ && !isLHS(self, compressor.parent())) {
var d = self.definition();
- if (d && d.constant && d.init && d.init.is_constant(compressor)) {
+ if (d.constant && !d.modified && d.init && d.init.is_constant(compressor)) {
var original_as_string = self.print_to_string();
var const_node = make_node_from_constant(compressor, d.init.constant_value(compressor), self);
var const_node_as_string = const_node.print_to_string();
var scope = self.parent_scope = null;
var labels = new Dictionary();
var defun = null;
- var last_var_had_const_pragma = false;
var tw = new TreeWalker(function(node, descend){
if (options.screw_ie8 && node instanceof AST_Catch) {
var save_scope = scope;
// later.
(node.scope = defun.parent_scope).def_function(node);
}
- else if (node instanceof AST_Var) {
- last_var_had_const_pragma = node.has_const_pragma();
- }
else if (node instanceof AST_SymbolVar
|| node instanceof AST_SymbolConst) {
var def = defun.def_variable(node);
- def.constant = node instanceof AST_SymbolConst || last_var_had_const_pragma;
+ def.constant = node instanceof AST_SymbolConst;
def.init = tw.parent().value;
}
else if (node instanceof AST_SymbolCatch) {
return this.definition().global;
});
-AST_Var.DEFMETHOD("has_const_pragma", function() {
- var comments_before = this.start && this.start.comments_before;
- var lastComment = comments_before && comments_before[comments_before.length - 1];
- return lastComment && /@const\b/.test(lastComment.value);
-});
-
AST_Toplevel.DEFMETHOD("_default_mangler_options", function(options){
return defaults(options, {
except : [],
join_vars : true,
sequences : false,
collapse_vars : false,
+ reduce_vars : true,
}
input: {
function foo(rot) {
join_vars : true,
sequences : false,
collapse_vars : false,
+ reduce_vars : true,
}
input: {
function f1() {const a = "X"; return a + a;}
join_vars : true,
sequences : false,
collapse_vars : false,
+ reduce_vars : true,
}
input: {
function foo(a) {
join_vars : true,
sequences : false,
collapse_vars : false,
+ reduce_vars : true,
}
input: {
(function(){
loops : true,
booleans : true,
conditionals : true,
- evaluate : true
+ evaluate : true,
+ reduce_vars : true,
};
input: {
var unused;
loops : true,
booleans : true,
conditionals : true,
- evaluate : true
+ evaluate : true,
+ reduce_vars : true,
};
input: {
var unused;
loops : true,
booleans : true,
conditionals : true,
- evaluate : true
+ evaluate : true,
+ reduce_vars : true,
};
input: {
var unused_var;
var beef = 'good';
var meat = 'beef';
var pork = 'bad';
- 'good' === pork && console.log('reached, not const');
}
}
foo(), bar();
}
}
+
+const_assign: {
+ options = {
+ evaluate: true,
+ reduce_vars: true,
+ unused: true,
+ }
+ input: {
+ function f() {
+ const b = 2;
+ return 1 + b;
+ }
+
+ function g() {
+ const b = 2;
+ b = 3;
+ return 1 + b;
+ }
+ }
+ expect: {
+ function f() {
+ return 3;
+ }
+
+ function g() {
+ const b = 2;
+ b = 3;
+ return 1 + b;
+ }
+ }
+}
call_args: {
options = {
evaluate: true,
+ reduce_vars: true,
}
input: {
const a = 1;
const_pragma: {
options = {
- evaluate: true
+ evaluate: true,
+ reduce_vars: true,
};
input: {
// for completeness' sake
not_const: {
options = {
- evaluate: true
+ evaluate: true,
+ reduce_vars: true,
};
input: {