Compare commits
14 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
557b3e412f | ||
|
|
8d74f34373 | ||
|
|
266ddd9639 | ||
|
|
e51c6ba380 | ||
|
|
6389e52305 | ||
|
|
e05510f3bc | ||
|
|
fc9804b909 | ||
|
|
4761d07e0b | ||
|
|
0111497fc9 | ||
|
|
7d8dea3b26 | ||
|
|
25fc02743a | ||
|
|
0bd8053524 | ||
|
|
1a78bbcd23 | ||
|
|
8430123e9d |
19
README.md
19
README.md
@@ -62,6 +62,7 @@ The available options are:
|
||||
--source-map-include-sources Pass this flag if you want to include the
|
||||
content of source files in the source map as
|
||||
sourcesContent property.
|
||||
--source-map-inline Write base64-encoded source map to the end of js output.
|
||||
--in-source-map Input source map, useful if you're compressing
|
||||
JS that was generated from some other original
|
||||
code.
|
||||
@@ -97,8 +98,8 @@ The available options are:
|
||||
"@preserve". You can optionally pass one of the
|
||||
following arguments to this flag:
|
||||
- "all" to keep all comments
|
||||
- a valid JS regexp (needs to start with a
|
||||
slash) to keep only comments that match.
|
||||
- a valid JS RegExp like `/foo/` or `/^!/` to
|
||||
keep only matching comments.
|
||||
Note that currently not *all* comments can be
|
||||
kept when compression is on, because of dead
|
||||
code removal or cascading statements into
|
||||
@@ -348,6 +349,9 @@ to set `true`; it's effectively a shortcut for `foo=true`).
|
||||
- `collapse_vars` -- default `false`. Collapse single-use `var` and `const`
|
||||
definitions when possible.
|
||||
|
||||
- `reduce_vars` -- default `false`. Improve optimization on variables assigned
|
||||
with and used as constant values.
|
||||
|
||||
- `warnings` -- display warnings when dropping unreachable code or unused
|
||||
declarations etc.
|
||||
|
||||
@@ -638,7 +642,9 @@ var result = UglifyJS.minify({"file1.js": "var a = function () {};"}, {
|
||||
|
||||
Note that the source map is not saved in a file, it's just returned in
|
||||
`result.map`. The value passed for `outSourceMap` is only used to set the
|
||||
`file` attribute in the source map (see [the spec][sm-spec]).
|
||||
`file` attribute in the source map (see [the spec][sm-spec]). You can set
|
||||
option `sourceMapInline` to be `true` and source map will be appended to
|
||||
code.
|
||||
|
||||
You can also specify sourceRoot property to be included in source map:
|
||||
```javascript
|
||||
@@ -849,8 +855,11 @@ which we care about here are `source_map` and `comments`.
|
||||
#### Keeping comments in the output
|
||||
|
||||
In order to keep certain comments in the output you need to pass the
|
||||
`comments` option. Pass a RegExp or a function. If you pass a RegExp, only
|
||||
those comments whose body matches the regexp will be kept. Note that body
|
||||
`comments` option. Pass a RegExp (as string starting and closing with `/`
|
||||
or pass a RegExp object), a boolean or a function. Stringified options
|
||||
`all` and `some` can be passed too, where `some` behaves like it's cli
|
||||
equivalent `--comments` without passing a value. If you pass a RegExp,
|
||||
only those comments whose body matches the RegExp will be kept. Note that body
|
||||
means without the initial `//` or `/*`. If you pass a function, it will be
|
||||
called for every comment in the tree and will receive two arguments: the
|
||||
node that the comment is attached to, and the comment token itself.
|
||||
|
||||
55
bin/uglifyjs
55
bin/uglifyjs
@@ -23,6 +23,7 @@ mangling you need to use `-c` and `-m`.\
|
||||
.describe("source-map", "Specify an output file where to generate source map.")
|
||||
.describe("source-map-root", "The path to the original source to be included in the source map.")
|
||||
.describe("source-map-url", "The path to the source map to be added in //# sourceMappingURL. Defaults to the value passed with --source-map.")
|
||||
.describe("source-map-inline", "Write base64-encoded source map to the end of js output. Disabled by default")
|
||||
.describe("source-map-include-sources", "Pass this flag if you want to include the content of source files in the source map as sourcesContent property.")
|
||||
.describe("in-source-map", "Input source map, useful if you're compressing JS that was generated from some other original code.")
|
||||
.describe("screw-ie8", "Do not support Internet Explorer 6-8 quirks. This flag is enabled by default.")
|
||||
@@ -46,7 +47,7 @@ Use -c with no argument to use the default compression options.")
|
||||
By default this works like Google Closure, keeping JSDoc-style comments that contain \"@license\" or \"@preserve\". \
|
||||
You can optionally pass one of the following arguments to this flag:\n\
|
||||
- \"all\" to keep all comments\n\
|
||||
- a valid JS regexp (needs to start with a slash) to keep only comments that match.\n\
|
||||
- a valid JS RegExp like `/foo/`or `/^!/` to keep only matching comments.\n\
|
||||
\
|
||||
Note that currently not *all* comments can be kept when compression is on, \
|
||||
because of dead code removal or cascading statements into sequences.")
|
||||
@@ -76,6 +77,7 @@ You need to pass an argument to this option to specify the name that your module
|
||||
.describe("name-cache", "File to hold mangled names mappings")
|
||||
.describe("pure-funcs", "List of functions that can be safely removed if their return value is not used")
|
||||
.describe("dump-spidermonkey-ast", "Dump SpiderMonkey AST to stdout.")
|
||||
.describe("wrap-iife", "Wrap IIFEs in parenthesis. Note: this disables the negate_iife compression option")
|
||||
|
||||
.alias("p", "prefix")
|
||||
.alias("o", "output")
|
||||
@@ -112,6 +114,7 @@ You need to pass an argument to this option to specify the name that your module
|
||||
.array("pure-funcs")
|
||||
|
||||
.boolean("expr")
|
||||
.boolean("source-map-inline")
|
||||
.boolean("source-map-include-sources")
|
||||
.boolean("screw-ie8")
|
||||
.boolean("support-ie8")
|
||||
@@ -130,6 +133,7 @@ You need to pass an argument to this option to specify the name that your module
|
||||
.boolean("bare-returns")
|
||||
.boolean("keep-fnames")
|
||||
.boolean("reserve-domprops")
|
||||
.boolean("wrap-iife")
|
||||
|
||||
.wrap(80)
|
||||
|
||||
@@ -247,28 +251,18 @@ if (ARGS.keep_fnames) {
|
||||
if (MANGLE) MANGLE.keep_fnames = true;
|
||||
}
|
||||
|
||||
if (ARGS.wrap_iife) {
|
||||
if (COMPRESS) COMPRESS.negate_iife = false;
|
||||
OUTPUT_OPTIONS.wrap_iife = true;
|
||||
}
|
||||
|
||||
if (BEAUTIFY)
|
||||
UglifyJS.merge(OUTPUT_OPTIONS, BEAUTIFY);
|
||||
|
||||
if (ARGS.comments != null) {
|
||||
if (/^\/.*\/[a-zA-Z]*$/.test(ARGS.comments)) {
|
||||
try {
|
||||
OUTPUT_OPTIONS.comments = extractRegex(ARGS.comments);
|
||||
} catch (e) {
|
||||
print_error("ERROR: Invalid --comments: " + e.message);
|
||||
}
|
||||
} else if (ARGS.comments == "all") {
|
||||
OUTPUT_OPTIONS.comments = true;
|
||||
} else {
|
||||
OUTPUT_OPTIONS.comments = function(node, comment) {
|
||||
var text = comment.value;
|
||||
var type = comment.type;
|
||||
if (type == "comment2") {
|
||||
// multiline comment
|
||||
return /@preserve|@license|@cc_on/i.test(text);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ARGS.comments === "") {
|
||||
OUTPUT_OPTIONS.comments = "some";
|
||||
} else {
|
||||
OUTPUT_OPTIONS.comments = ARGS.comments;
|
||||
}
|
||||
|
||||
var files = ARGS._.slice();
|
||||
@@ -317,7 +311,7 @@ var TOPLEVEL = null;
|
||||
var P_RELATIVE = ARGS.p && ARGS.p == "relative";
|
||||
var SOURCES_CONTENT = {};
|
||||
|
||||
var SOURCE_MAP = ARGS.source_map ? UglifyJS.SourceMap({
|
||||
var SOURCE_MAP = (ARGS.source_map || ARGS.source_map_inline) ? UglifyJS.SourceMap({
|
||||
file: P_RELATIVE ? path.relative(path.dirname(ARGS.source_map), OUTPUT_FILE) : OUTPUT_FILE,
|
||||
root: ARGS.source_map_root,
|
||||
orig: ORIG_MAP,
|
||||
@@ -482,13 +476,18 @@ async.eachLimit(files, 1, function (file, cb) {
|
||||
output = output.get();
|
||||
|
||||
if (SOURCE_MAP) {
|
||||
fs.writeFileSync(ARGS.source_map, SOURCE_MAP, "utf8");
|
||||
var source_map_url = ARGS.source_map_url || (
|
||||
P_RELATIVE
|
||||
? path.relative(path.dirname(OUTPUT_FILE), ARGS.source_map)
|
||||
: ARGS.source_map
|
||||
);
|
||||
output += "\n//# sourceMappingURL=" + source_map_url;
|
||||
if (ARGS.source_map_inline) {
|
||||
var base64_string = new Buffer(SOURCE_MAP.toString()).toString('base64');
|
||||
output += "\n//# sourceMappingURL=data:application/json;charset=utf-8;base64," + base64_string;
|
||||
} else {
|
||||
fs.writeFileSync(ARGS.source_map, SOURCE_MAP, "utf8");
|
||||
var source_map_url = ARGS.source_map_url || (
|
||||
P_RELATIVE
|
||||
? path.relative(path.dirname(OUTPUT_FILE), ARGS.source_map)
|
||||
: ARGS.source_map
|
||||
);
|
||||
output += "\n//# sourceMappingURL=" + source_map_url;
|
||||
}
|
||||
}
|
||||
|
||||
if (OUTPUT_FILE) {
|
||||
|
||||
@@ -67,6 +67,7 @@ function Compressor(options, false_by_default) {
|
||||
if_return : !false_by_default,
|
||||
join_vars : !false_by_default,
|
||||
collapse_vars : false,
|
||||
reduce_vars : false,
|
||||
cascade : !false_by_default,
|
||||
side_effects : !false_by_default,
|
||||
pure_getters : false,
|
||||
@@ -831,6 +832,13 @@ merge(Compressor.prototype, {
|
||||
};
|
||||
|
||||
function negate_iifes(statements, compressor) {
|
||||
function is_iife_call(node) {
|
||||
if (node instanceof AST_Call) {
|
||||
return node.expression instanceof AST_Function || is_iife_call(node.expression);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
statements.forEach(function(stat){
|
||||
if (stat instanceof AST_SimpleStatement) {
|
||||
stat.body = (function transform(thing) {
|
||||
@@ -838,7 +846,7 @@ merge(Compressor.prototype, {
|
||||
if (node instanceof AST_New) {
|
||||
return node;
|
||||
}
|
||||
if (node instanceof AST_Call && node.expression instanceof AST_Function) {
|
||||
if (is_iife_call(node)) {
|
||||
return make_node(AST_UnaryPrefix, node, {
|
||||
operator: "!",
|
||||
expression: node
|
||||
@@ -1100,7 +1108,7 @@ merge(Compressor.prototype, {
|
||||
this._evaluating = true;
|
||||
try {
|
||||
var d = this.definition();
|
||||
if (d && d.constant && d.init) {
|
||||
if (d && (d.constant || compressor.option("reduce_vars") && !d.modified) && d.init) {
|
||||
return ev(d.init, compressor);
|
||||
}
|
||||
} finally {
|
||||
@@ -2306,6 +2314,12 @@ merge(Compressor.prototype, {
|
||||
// typeof always returns a non-empty string, thus it's
|
||||
// always true in booleans
|
||||
compressor.warn("Boolean expression always true [{file}:{line},{col}]", self.start);
|
||||
if (self.expression.has_side_effects(compressor)) {
|
||||
return make_node(AST_Seq, self, {
|
||||
car: self.expression,
|
||||
cdr: make_node(AST_True, self)
|
||||
});
|
||||
}
|
||||
return make_node(AST_True, self);
|
||||
}
|
||||
if (e instanceof AST_Binary && self.operator == "!") {
|
||||
@@ -2492,8 +2506,8 @@ merge(Compressor.prototype, {
|
||||
case "+":
|
||||
var ll = self.left.evaluate(compressor);
|
||||
var rr = self.right.evaluate(compressor);
|
||||
if ((ll.length > 1 && ll[0] instanceof AST_String && ll[1]) ||
|
||||
(rr.length > 1 && rr[0] instanceof AST_String && rr[1])) {
|
||||
if ((ll.length > 1 && ll[0] instanceof AST_String && ll[1] && !self.right.has_side_effects(compressor)) ||
|
||||
(rr.length > 1 && rr[0] instanceof AST_String && rr[1] && !self.left.has_side_effects(compressor))) {
|
||||
compressor.warn("+ in boolean context always true [{file}:{line},{col}]", self.start);
|
||||
return make_node(AST_True, self);
|
||||
}
|
||||
@@ -2648,16 +2662,26 @@ merge(Compressor.prototype, {
|
||||
});
|
||||
|
||||
var ASSIGN_OPS = [ '+', '-', '/', '*', '%', '>>', '<<', '>>>', '|', '^', '&' ];
|
||||
var ASSIGN_OPS_COMMUTATIVE = [ '*', '|', '^', '&' ];
|
||||
OPT(AST_Assign, function(self, compressor){
|
||||
self = self.lift_sequences(compressor);
|
||||
if (self.operator == "="
|
||||
&& self.left instanceof AST_SymbolRef
|
||||
&& self.right instanceof AST_Binary
|
||||
&& self.right.left instanceof AST_SymbolRef
|
||||
&& self.right.left.name == self.left.name
|
||||
&& member(self.right.operator, ASSIGN_OPS)) {
|
||||
self.operator = self.right.operator + "=";
|
||||
self.right = self.right.right;
|
||||
if (self.operator == "=" && self.left instanceof AST_SymbolRef && self.right instanceof AST_Binary) {
|
||||
// x = expr1 OP expr2
|
||||
if (self.right.left instanceof AST_SymbolRef
|
||||
&& self.right.left.name == self.left.name
|
||||
&& member(self.right.operator, ASSIGN_OPS)) {
|
||||
// x = x - 2 ---> x -= 2
|
||||
self.operator = self.right.operator + "=";
|
||||
self.right = self.right.right;
|
||||
}
|
||||
else if (self.right.right instanceof AST_SymbolRef
|
||||
&& self.right.right.name == self.left.name
|
||||
&& member(self.right.operator, ASSIGN_OPS_COMMUTATIVE)
|
||||
&& !self.right.left.has_side_effects(compressor)) {
|
||||
// x = 2 & x ---> x &= 2
|
||||
self.operator = self.right.operator + "=";
|
||||
self.right = self.right.left;
|
||||
}
|
||||
}
|
||||
return self;
|
||||
});
|
||||
|
||||
@@ -67,9 +67,54 @@ function OutputStream(options) {
|
||||
screw_ie8 : true,
|
||||
preamble : null,
|
||||
quote_style : 0,
|
||||
keep_quoted_props: false
|
||||
keep_quoted_props: false,
|
||||
wrap_iife : false,
|
||||
}, true);
|
||||
|
||||
// Convert comment option to RegExp if neccessary and set up comments filter
|
||||
if (typeof options.comments === "string" && /^\/.*\/[a-zA-Z]*$/.test(options.comments)) {
|
||||
var regex_pos = options.comments.lastIndexOf("/");
|
||||
options.comments = new RegExp(
|
||||
options.comments.substr(1, regex_pos - 1),
|
||||
options.comments.substr(regex_pos + 1)
|
||||
);
|
||||
}
|
||||
if (options.comments instanceof RegExp) {
|
||||
options.comments = (function(f) {
|
||||
return function(comment) {
|
||||
return comment.type == "comment5" || f.test(comment.value);
|
||||
}
|
||||
})(options.comments);
|
||||
}
|
||||
else if (typeof options.comments === "function") {
|
||||
options.comments = (function(f) {
|
||||
return function(comment) {
|
||||
return comment.type == "comment5" || f(this, comment);
|
||||
}
|
||||
})(options.comments);
|
||||
}
|
||||
else if (options.comments === "some") {
|
||||
options.comments = function(comment) {
|
||||
var text = comment.value;
|
||||
var type = comment.type;
|
||||
if (type == "comment2") {
|
||||
// multiline comment
|
||||
return /@preserve|@license|@cc_on/i.test(text);
|
||||
}
|
||||
return type == "comment5";
|
||||
}
|
||||
}
|
||||
else if (options.comments){ // NOTE includes "all" option
|
||||
options.comments = function() {
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
// Falsy case, so reject all comments, except shebangs
|
||||
options.comments = function(comment) {
|
||||
return comment.type == "comment5";
|
||||
}
|
||||
}
|
||||
|
||||
var indentation = 0;
|
||||
var current_col = 0;
|
||||
var current_line = 1;
|
||||
@@ -435,7 +480,7 @@ function OutputStream(options) {
|
||||
|
||||
AST_Node.DEFMETHOD("add_comments", function(output){
|
||||
if (output._readonly) return;
|
||||
var c = output.option("comments"), self = this;
|
||||
var self = this;
|
||||
var start = self.start;
|
||||
if (start && !start._comments_dumped) {
|
||||
start._comments_dumped = true;
|
||||
@@ -458,19 +503,7 @@ function OutputStream(options) {
|
||||
}));
|
||||
}
|
||||
|
||||
if (!c) {
|
||||
comments = comments.filter(function(comment) {
|
||||
return comment.type == "comment5";
|
||||
});
|
||||
} else if (c.test) {
|
||||
comments = comments.filter(function(comment){
|
||||
return comment.type == "comment5" || c.test(comment.value);
|
||||
});
|
||||
} else if (typeof c == "function") {
|
||||
comments = comments.filter(function(comment){
|
||||
return comment.type == "comment5" || c(self, comment);
|
||||
});
|
||||
}
|
||||
comments = comments.filter(output.option("comments"), self);
|
||||
|
||||
// Keep single line comments after nlb, after nlb
|
||||
if (!output.option("beautify") && comments.length > 0 &&
|
||||
@@ -521,7 +554,16 @@ function OutputStream(options) {
|
||||
// a function expression needs parens around it when it's provably
|
||||
// the first token to appear in a statement.
|
||||
PARENS(AST_Function, function(output){
|
||||
return first_in_statement(output);
|
||||
if (first_in_statement(output)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (output.option('wrap_iife')) {
|
||||
var p = output.parent();
|
||||
return p instanceof AST_Call && p.expression === this;
|
||||
}
|
||||
|
||||
return false;
|
||||
});
|
||||
|
||||
// same goes for an object literal, because otherwise it would be
|
||||
@@ -531,8 +573,6 @@ function OutputStream(options) {
|
||||
});
|
||||
|
||||
PARENS([ AST_Unary, AST_Undefined ], function(output){
|
||||
if (this.expression instanceof AST_Call)
|
||||
return false;
|
||||
var p = output.parent();
|
||||
return p instanceof AST_PropAccess && p.expression === this
|
||||
|| p instanceof AST_Call && p.expression === this;
|
||||
|
||||
18
lib/scope.js
18
lib/scope.js
@@ -197,12 +197,16 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){
|
||||
}
|
||||
if (node instanceof AST_SymbolRef) {
|
||||
var name = node.name;
|
||||
if (name == "eval" && tw.parent() instanceof AST_Call) {
|
||||
var parent = tw.parent();
|
||||
if (name == "eval" && parent instanceof AST_Call) {
|
||||
for (var s = node.scope; s && !s.uses_eval; s = s.parent_scope) {
|
||||
s.uses_eval = true;
|
||||
}
|
||||
}
|
||||
var sym = node.scope.find_variable(name);
|
||||
if (node.scope instanceof AST_Lambda && name == "arguments") {
|
||||
node.scope.uses_arguments = true;
|
||||
}
|
||||
if (!sym) {
|
||||
var g;
|
||||
if (globals.has(name)) {
|
||||
@@ -213,12 +217,12 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){
|
||||
g.global = true;
|
||||
globals.set(name, g);
|
||||
}
|
||||
node.thedef = g;
|
||||
if (func && name == "arguments") {
|
||||
func.uses_arguments = true;
|
||||
}
|
||||
} else {
|
||||
node.thedef = sym;
|
||||
sym = g;
|
||||
}
|
||||
node.thedef = sym;
|
||||
if (parent instanceof AST_Unary && (parent.operator === '++' || parent.operator === '--')
|
||||
|| parent instanceof AST_Assign && parent.left === node) {
|
||||
sym.modified = true;
|
||||
}
|
||||
node.reference();
|
||||
return true;
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
"homepage": "http://lisperator.net/uglifyjs",
|
||||
"author": "Mihai Bazon <mihai.bazon@gmail.com> (http://lisperator.net/)",
|
||||
"license": "BSD-2-Clause",
|
||||
"version": "2.7.2",
|
||||
"version": "2.7.4",
|
||||
"engines": {
|
||||
"node": ">=0.8.0"
|
||||
},
|
||||
|
||||
@@ -90,13 +90,13 @@ asm_mixed: {
|
||||
}
|
||||
function no_asm_GeometricMean(stdlib, foreign, buffer) {
|
||||
function logSum(start, end) {
|
||||
start = 0 | start, end = 0 | end;
|
||||
start |= 0, end |= 0;
|
||||
var sum = 0, p = 0, q = 0;
|
||||
for (p = start << 3, q = end << 3; (0 | p) < (0 | q); p = p + 8 | 0) sum += +log(values[p >> 3]);
|
||||
return +sum;
|
||||
}
|
||||
function geometricMean(start, end) {
|
||||
return start = 0 | start, end = 0 | end, +exp(+logSum(start, end) / +(end - start | 0));
|
||||
return start |= 0, end |= 0, +exp(+logSum(start, end) / +(end - start | 0));
|
||||
}
|
||||
var exp = stdlib.Math.exp, log = stdlib.Math.log, values = new stdlib.Float64Array(buffer);
|
||||
return { geometricMean: geometricMean };
|
||||
|
||||
238
test/compress/assignment.js
Normal file
238
test/compress/assignment.js
Normal file
@@ -0,0 +1,238 @@
|
||||
op_equals_left_local_var: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
}
|
||||
input: {
|
||||
var x;
|
||||
|
||||
x = x + 3;
|
||||
x = x - 3;
|
||||
x = x / 3;
|
||||
x = x * 3;
|
||||
x = x >> 3;
|
||||
x = x << 3;
|
||||
x = x >>> 3;
|
||||
x = x | 3;
|
||||
x = x ^ 3;
|
||||
x = x % 3;
|
||||
x = x & 3;
|
||||
|
||||
x = x + g();
|
||||
x = x - g();
|
||||
x = x / g();
|
||||
x = x * g();
|
||||
x = x >> g();
|
||||
x = x << g();
|
||||
x = x >>> g();
|
||||
x = x | g();
|
||||
x = x ^ g();
|
||||
x = x % g();
|
||||
x = x & g();
|
||||
}
|
||||
expect: {
|
||||
var x;
|
||||
|
||||
x += 3;
|
||||
x -= 3;
|
||||
x /= 3;
|
||||
x *= 3;
|
||||
x >>= 3;
|
||||
x <<= 3;
|
||||
x >>>= 3;
|
||||
x |= 3;
|
||||
x ^= 3;
|
||||
x %= 3;
|
||||
x &= 3;
|
||||
|
||||
x += g();
|
||||
x -= g();
|
||||
x /= g();
|
||||
x *= g();
|
||||
x >>= g();
|
||||
x <<= g();
|
||||
x >>>= g();
|
||||
x |= g();
|
||||
x ^= g();
|
||||
x %= g();
|
||||
x &= g();
|
||||
}
|
||||
}
|
||||
|
||||
op_equals_right_local_var: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
}
|
||||
input: {
|
||||
var x;
|
||||
|
||||
x = (x -= 2) ^ x;
|
||||
|
||||
x = 3 + x;
|
||||
x = 3 - x;
|
||||
x = 3 / x;
|
||||
x = 3 * x;
|
||||
x = 3 >> x;
|
||||
x = 3 << x;
|
||||
x = 3 >>> x;
|
||||
x = 3 | x;
|
||||
x = 3 ^ x;
|
||||
x = 3 % x;
|
||||
x = 3 & x;
|
||||
|
||||
x = g() + x;
|
||||
x = g() - x;
|
||||
x = g() / x;
|
||||
x = g() * x;
|
||||
x = g() >> x;
|
||||
x = g() << x;
|
||||
x = g() >>> x;
|
||||
x = g() | x;
|
||||
x = g() ^ x;
|
||||
x = g() % x;
|
||||
x = g() & x;
|
||||
}
|
||||
expect: {
|
||||
var x;
|
||||
|
||||
x = (x -= 2) ^ x;
|
||||
|
||||
x = 3 + x;
|
||||
x = 3 - x;
|
||||
x = 3 / x;
|
||||
x *= 3;
|
||||
x = 3 >> x;
|
||||
x = 3 << x;
|
||||
x = 3 >>> x;
|
||||
x |= 3;
|
||||
x ^= 3;
|
||||
x = 3 % x;
|
||||
x &= 3;
|
||||
|
||||
x = g() + x;
|
||||
x = g() - x;
|
||||
x = g() / x;
|
||||
x = g() * x;
|
||||
x = g() >> x;
|
||||
x = g() << x;
|
||||
x = g() >>> x;
|
||||
x = g() | x;
|
||||
x = g() ^ x;
|
||||
x = g() % x;
|
||||
x = g() & x;
|
||||
}
|
||||
}
|
||||
op_equals_left_global_var: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
}
|
||||
input: {
|
||||
x = x + 3;
|
||||
x = x - 3;
|
||||
x = x / 3;
|
||||
x = x * 3;
|
||||
x = x >> 3;
|
||||
x = x << 3;
|
||||
x = x >>> 3;
|
||||
x = x | 3;
|
||||
x = x ^ 3;
|
||||
x = x % 3;
|
||||
x = x & 3;
|
||||
|
||||
x = x + g();
|
||||
x = x - g();
|
||||
x = x / g();
|
||||
x = x * g();
|
||||
x = x >> g();
|
||||
x = x << g();
|
||||
x = x >>> g();
|
||||
x = x | g();
|
||||
x = x ^ g();
|
||||
x = x % g();
|
||||
x = x & g();
|
||||
}
|
||||
expect: {
|
||||
x += 3;
|
||||
x -= 3;
|
||||
x /= 3;
|
||||
x *= 3;
|
||||
x >>= 3;
|
||||
x <<= 3;
|
||||
x >>>= 3;
|
||||
x |= 3;
|
||||
x ^= 3;
|
||||
x %= 3;
|
||||
x &= 3;
|
||||
|
||||
x += g();
|
||||
x -= g();
|
||||
x /= g();
|
||||
x *= g();
|
||||
x >>= g();
|
||||
x <<= g();
|
||||
x >>>= g();
|
||||
x |= g();
|
||||
x ^= g();
|
||||
x %= g();
|
||||
x &= g();
|
||||
}
|
||||
}
|
||||
|
||||
op_equals_right_global_var: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
}
|
||||
input: {
|
||||
x = (x -= 2) ^ x;
|
||||
|
||||
x = 3 + x;
|
||||
x = 3 - x;
|
||||
x = 3 / x;
|
||||
x = 3 * x;
|
||||
x = 3 >> x;
|
||||
x = 3 << x;
|
||||
x = 3 >>> x;
|
||||
x = 3 | x;
|
||||
x = 3 ^ x;
|
||||
x = 3 % x;
|
||||
x = 3 & x;
|
||||
|
||||
x = g() + x;
|
||||
x = g() - x;
|
||||
x = g() / x;
|
||||
x = g() * x;
|
||||
x = g() >> x;
|
||||
x = g() << x;
|
||||
x = g() >>> x;
|
||||
x = g() | x;
|
||||
x = g() ^ x;
|
||||
x = g() % x;
|
||||
x = g() & x;
|
||||
}
|
||||
expect: {
|
||||
x = (x -= 2) ^ x;
|
||||
|
||||
x = 3 + x;
|
||||
x = 3 - x;
|
||||
x = 3 / x;
|
||||
x *= 3;
|
||||
x = 3 >> x;
|
||||
x = 3 << x;
|
||||
x = 3 >>> x;
|
||||
x |= 3;
|
||||
x ^= 3;
|
||||
x = 3 % x;
|
||||
x &= 3;
|
||||
|
||||
x = g() + x;
|
||||
x = g() - x;
|
||||
x = g() / x;
|
||||
x = g() * x;
|
||||
x = g() >> x;
|
||||
x = g() << x;
|
||||
x = g() >>> x;
|
||||
x = g() | x;
|
||||
x = g() ^ x;
|
||||
x = g() % x;
|
||||
x = g() & x;
|
||||
}
|
||||
}
|
||||
49
test/compress/issue-1275.js
Normal file
49
test/compress/issue-1275.js
Normal file
@@ -0,0 +1,49 @@
|
||||
string_plus_optimization: {
|
||||
options = {
|
||||
side_effects : true,
|
||||
evaluate : true,
|
||||
conditionals : true,
|
||||
comparisons : true,
|
||||
dead_code : true,
|
||||
booleans : true,
|
||||
unused : true,
|
||||
if_return : true,
|
||||
join_vars : true,
|
||||
cascade : true,
|
||||
hoist_funs : true,
|
||||
};
|
||||
input: {
|
||||
function foo(anything) {
|
||||
function throwing_function() {
|
||||
throw "nope";
|
||||
}
|
||||
try {
|
||||
console.log('0' + throwing_function() ? "yes" : "no");
|
||||
} catch (ex) {
|
||||
console.log(ex);
|
||||
}
|
||||
console.log('0' + anything ? "yes" : "no");
|
||||
console.log(anything + '0' ? "Yes" : "No");
|
||||
console.log('' + anything);
|
||||
console.log(anything + '');
|
||||
}
|
||||
foo();
|
||||
}
|
||||
expect: {
|
||||
function foo(anything) {
|
||||
function throwing_function() {
|
||||
throw "nope";
|
||||
}
|
||||
try {
|
||||
console.log('0' + throwing_function() ? "yes" : "no");
|
||||
} catch (ex) {
|
||||
console.log(ex);
|
||||
}
|
||||
console.log("yes");
|
||||
console.log("Yes");
|
||||
console.log('' + anything);
|
||||
console.log(anything + '');
|
||||
}
|
||||
foo();
|
||||
}
|
||||
}
|
||||
@@ -158,3 +158,17 @@ issue_1254_negate_iife_true: {
|
||||
}
|
||||
expect_exact: '!function(){return function(){console.log("test")}}()();'
|
||||
}
|
||||
|
||||
issue_1254_negate_iife_nested: {
|
||||
options = {
|
||||
negate_iife: true,
|
||||
}
|
||||
input: {
|
||||
(function() {
|
||||
return function() {
|
||||
console.log('test')
|
||||
};
|
||||
})()()()()();
|
||||
}
|
||||
expect_exact: '!function(){return function(){console.log("test")}}()()()()();'
|
||||
}
|
||||
|
||||
@@ -75,3 +75,10 @@ call_with_unary_arguments: {
|
||||
}
|
||||
expect_exact: "x();x(-1);x(-1,-2);x(void 1,+2,-3,~4,!5,--a,++b,c--,d++,typeof e,delete f);(-1)();(-1)(-2);"
|
||||
}
|
||||
|
||||
new_with_unary_prefix: {
|
||||
input: {
|
||||
var bar = (+new Date()).toString(32);
|
||||
}
|
||||
expect_exact: 'var bar=(+new Date).toString(32);';
|
||||
}
|
||||
|
||||
171
test/compress/reduce_vars.js
Normal file
171
test/compress/reduce_vars.js
Normal file
@@ -0,0 +1,171 @@
|
||||
reduce_vars: {
|
||||
options = {
|
||||
conditionals : true,
|
||||
evaluate : true,
|
||||
global_defs : {
|
||||
C : 0
|
||||
},
|
||||
reduce_vars : true,
|
||||
unused : true
|
||||
}
|
||||
input: {
|
||||
var A = 1;
|
||||
(function f0() {
|
||||
var a = 2;
|
||||
console.log(a - 5);
|
||||
console.log(A - 5);
|
||||
})();
|
||||
(function f1() {
|
||||
var a = 2;
|
||||
console.log(a - 5);
|
||||
eval("console.log(a);");
|
||||
})();
|
||||
(function f2(eval) {
|
||||
var a = 2;
|
||||
console.log(a - 5);
|
||||
eval("console.log(a);");
|
||||
})(eval);
|
||||
(function f3() {
|
||||
var b = typeof C !== "undefined";
|
||||
var c = 4;
|
||||
if (b) {
|
||||
return 'yes';
|
||||
} else {
|
||||
return 'no';
|
||||
}
|
||||
})();
|
||||
console.log(A + 1);
|
||||
}
|
||||
expect: {
|
||||
var A = 1;
|
||||
(function() {
|
||||
console.log(-3);
|
||||
console.log(-4);
|
||||
})();
|
||||
(function f1() {
|
||||
var a = 2;
|
||||
console.log(-3);
|
||||
eval("console.log(a);");
|
||||
})();
|
||||
(function f2(eval) {
|
||||
var a = 2;
|
||||
console.log(-3);
|
||||
eval("console.log(a);");
|
||||
})(eval);
|
||||
(function() {
|
||||
return "yes";
|
||||
})();
|
||||
console.log(2);
|
||||
}
|
||||
}
|
||||
|
||||
modified: {
|
||||
options = {
|
||||
conditionals : true,
|
||||
evaluate : true,
|
||||
reduce_vars : true,
|
||||
unused : true
|
||||
}
|
||||
input: {
|
||||
function f0() {
|
||||
var a = 1, b = 2;
|
||||
b++;
|
||||
console.log(a + 1);
|
||||
console.log(b + 1);
|
||||
}
|
||||
|
||||
function f1() {
|
||||
var a = 1, b = 2;
|
||||
--b;
|
||||
console.log(a + 1);
|
||||
console.log(b + 1);
|
||||
}
|
||||
|
||||
function f2() {
|
||||
var a = 1, b = 2, c = 3;
|
||||
b = c;
|
||||
console.log(a + b);
|
||||
console.log(b + c);
|
||||
console.log(a + c);
|
||||
console.log(a + b + c);
|
||||
}
|
||||
|
||||
function f3() {
|
||||
var a = 1, b = 2, c = 3;
|
||||
b *= c;
|
||||
console.log(a + b);
|
||||
console.log(b + c);
|
||||
console.log(a + c);
|
||||
console.log(a + b + c);
|
||||
}
|
||||
|
||||
function f4() {
|
||||
var a = 1, b = 2, c = 3;
|
||||
if (a) {
|
||||
b = c;
|
||||
} else {
|
||||
c = b;
|
||||
}
|
||||
console.log(a + b);
|
||||
console.log(b + c);
|
||||
// TODO: as "modified" is determined in "figure_out_scope",
|
||||
// even "passes" wouldn't improve this any further
|
||||
console.log(a + c);
|
||||
console.log(a + b + c);
|
||||
}
|
||||
|
||||
function f5(a) {
|
||||
B = a;
|
||||
console.log(A ? 'yes' : 'no');
|
||||
console.log(B ? 'yes' : 'no');
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function f0() {
|
||||
var b = 2;
|
||||
b++;
|
||||
console.log(2);
|
||||
console.log(b + 1);
|
||||
}
|
||||
|
||||
function f1() {
|
||||
var b = 2;
|
||||
--b;
|
||||
console.log(2);
|
||||
console.log(b + 1);
|
||||
}
|
||||
|
||||
function f2() {
|
||||
var a = 1, b = 2, c = 3;
|
||||
b = c;
|
||||
console.log(a + b);
|
||||
console.log(b + c);
|
||||
console.log(4);
|
||||
console.log(a + b + c);
|
||||
}
|
||||
|
||||
function f3() {
|
||||
var a = 1, b = 2, c = 3;
|
||||
b *= c;
|
||||
console.log(a + b);
|
||||
console.log(b + c);
|
||||
console.log(4);
|
||||
console.log(a + b + c);
|
||||
}
|
||||
|
||||
function f4() {
|
||||
var a = 1, b = 2, c = 3;
|
||||
b = c;
|
||||
console.log(a + b);
|
||||
console.log(b + c);
|
||||
console.log(a + c);
|
||||
console.log(a + b + c);
|
||||
}
|
||||
|
||||
function f5(a) {
|
||||
B = a;
|
||||
console.log(A ? 'yes' : 'no');
|
||||
console.log(B ? 'yes' : 'no');
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -23,3 +23,25 @@ typeof_evaluation: {
|
||||
h='undefined';
|
||||
}
|
||||
}
|
||||
|
||||
typeof_in_boolean_context: {
|
||||
options = {
|
||||
booleans : true,
|
||||
evaluate : true,
|
||||
conditionals : true,
|
||||
};
|
||||
input: {
|
||||
function f1(x) { return typeof x ? "yes" : "no"; }
|
||||
function f2() { return typeof g()? "Yes" : "No"; }
|
||||
typeof 0 ? foo() : bar();
|
||||
!typeof console.log(1);
|
||||
var a = !typeof console.log(2);
|
||||
}
|
||||
expect: {
|
||||
function f1(x) { return "yes"; }
|
||||
function f2() { return g(), "Yes"; }
|
||||
foo();
|
||||
!(console.log(1), !0);
|
||||
var a = !(console.log(2), !0);
|
||||
}
|
||||
}
|
||||
|
||||
48
test/compress/wrap_iife.js
Normal file
48
test/compress/wrap_iife.js
Normal file
@@ -0,0 +1,48 @@
|
||||
wrap_iife: {
|
||||
options = {
|
||||
negate_iife: false,
|
||||
}
|
||||
beautify = {
|
||||
wrap_iife: true,
|
||||
}
|
||||
input: {
|
||||
(function() {
|
||||
return function() {
|
||||
console.log('test')
|
||||
};
|
||||
})()();
|
||||
}
|
||||
expect_exact: '(function(){return function(){console.log("test")}})()();'
|
||||
}
|
||||
|
||||
wrap_iife_in_expression: {
|
||||
options = {
|
||||
negate_iife: false,
|
||||
}
|
||||
beautify = {
|
||||
wrap_iife: true,
|
||||
}
|
||||
input: {
|
||||
foo = (function () {
|
||||
return bar();
|
||||
})();
|
||||
}
|
||||
expect_exact: 'foo=(function(){return bar()})();'
|
||||
}
|
||||
|
||||
wrap_iife_in_return_call: {
|
||||
options = {
|
||||
negate_iife: false,
|
||||
}
|
||||
beautify = {
|
||||
wrap_iife: true,
|
||||
}
|
||||
input: {
|
||||
(function() {
|
||||
return (function() {
|
||||
console.log('test')
|
||||
})();
|
||||
})()();
|
||||
}
|
||||
expect_exact: '(function(){return(function(){console.log("test")})()})()();'
|
||||
}
|
||||
3
test/input/comments/filter.js
Normal file
3
test/input/comments/filter.js
Normal file
@@ -0,0 +1,3 @@
|
||||
// foo
|
||||
/*@preserve*/
|
||||
// bar
|
||||
7
test/input/issue-1323/sample.js
Normal file
7
test/input/issue-1323/sample.js
Normal file
@@ -0,0 +1,7 @@
|
||||
var bar = (function () {
|
||||
function foo (bar) {
|
||||
return bar;
|
||||
}
|
||||
|
||||
return foo;
|
||||
})();
|
||||
@@ -19,4 +19,12 @@ describe("arguments", function() {
|
||||
value // Select function as scope
|
||||
);
|
||||
});
|
||||
|
||||
it("Should recognize when a function uses arguments", function() {
|
||||
var ast = UglifyJS.parse("function a(){function b(){function c(){}; return arguments[0];}}");
|
||||
ast.figure_out_scope();
|
||||
assert.strictEqual(ast.body[0].uses_arguments, false);
|
||||
assert.strictEqual(ast.body[0].body[0].uses_arguments, true);
|
||||
assert.strictEqual(ast.body[0].body[0].body[0].uses_arguments, false);
|
||||
});
|
||||
});
|
||||
@@ -2,11 +2,11 @@ var assert = require("assert");
|
||||
var exec = require("child_process").exec;
|
||||
|
||||
describe("bin/uglifyjs", function () {
|
||||
var uglifyjscmd = '"' + process.argv[0] + '" bin/uglifyjs';
|
||||
it("should produce a functional build when using --self", function (done) {
|
||||
this.timeout(5000);
|
||||
|
||||
var uglifyjs = '"' + process.argv[0] + '" bin/uglifyjs';
|
||||
var command = uglifyjs + ' --self -cm --wrap WrappedUglifyJS';
|
||||
var command = uglifyjscmd + ' --self -cm --wrap WrappedUglifyJS';
|
||||
|
||||
exec(command, function (err, stdout) {
|
||||
if (err) throw err;
|
||||
@@ -19,4 +19,55 @@ describe("bin/uglifyjs", function () {
|
||||
done();
|
||||
});
|
||||
});
|
||||
it("Should be able to filter comments correctly with `--comment all`", function (done) {
|
||||
var command = uglifyjscmd + ' test/input/comments/filter.js --comments all';
|
||||
|
||||
exec(command, function (err, stdout) {
|
||||
if (err) throw err;
|
||||
|
||||
assert.strictEqual(stdout, "// foo\n/*@preserve*/\n// bar\n\n");
|
||||
done();
|
||||
});
|
||||
});
|
||||
it("Should be able to filter comments correctly with `--comment <RegExp>`", function (done) {
|
||||
var command = uglifyjscmd + ' test/input/comments/filter.js --comments /r/';
|
||||
|
||||
exec(command, function (err, stdout) {
|
||||
if (err) throw err;
|
||||
|
||||
assert.strictEqual(stdout, "/*@preserve*/\n// bar\n\n");
|
||||
done();
|
||||
});
|
||||
});
|
||||
it("Should be able to filter comments correctly with just `--comment`", function (done) {
|
||||
var command = uglifyjscmd + ' test/input/comments/filter.js --comments';
|
||||
|
||||
exec(command, function (err, stdout) {
|
||||
if (err) throw err;
|
||||
|
||||
assert.strictEqual(stdout, "/*@preserve*/\n\n");
|
||||
done();
|
||||
});
|
||||
});
|
||||
it("Should append source map to output when using --source-map-inline", function (done) {
|
||||
var command = uglifyjscmd + ' test/input/issue-1323/sample.js --source-map-inline';
|
||||
|
||||
exec(command, function (err, stdout) {
|
||||
if (err) throw err;
|
||||
|
||||
assert.strictEqual(stdout, "var bar=function(){function foo(bar){return bar}return foo}();\n" +
|
||||
"//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInRlc3QvaW5wdXQvaXNzdWUtMTMyMy9zYW1wbGUuanMiXSwibmFtZXMiOlsiYmFyIiwiZm9vIl0sIm1hcHBpbmdzIjoiQUFBQSxHQUFJQSxLQUFNLFdBQ04sUUFBU0MsS0FBS0QsS0FDVixNQUFPQSxLQUdYLE1BQU9DIn0=\n");
|
||||
done();
|
||||
});
|
||||
});
|
||||
it("should not append source map to output when not using --source-map-inline", function (done) {
|
||||
var command = uglifyjscmd + ' test/input/issue-1323/sample.js';
|
||||
|
||||
exec(command, function (err, stdout) {
|
||||
if (err) throw err;
|
||||
|
||||
assert.strictEqual(stdout, "var bar=function(){function foo(bar){return bar}return foo}();\n");
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -7,6 +7,16 @@ describe("comment filters", function() {
|
||||
assert.strictEqual(ast.print_to_string({comments: /^!/}), "/*!test1*/\n//!test3\n//!test6\n//!test8\n");
|
||||
});
|
||||
|
||||
it("Should be able to filter comments with the 'all' option", function() {
|
||||
var ast = UglifyJS.parse("/*!test1*/\n/*test2*/\n//!test3\n//test4\n<!--test5\n<!--!test6\n-->test7\n-->!test8");
|
||||
assert.strictEqual(ast.print_to_string({comments: "all"}), "/*!test1*/\n/*test2*/\n//!test3\n//test4\n//test5\n//!test6\n//test7\n//!test8\n");
|
||||
});
|
||||
|
||||
it("Should be able to filter commments with the 'some' option", function() {
|
||||
var ast = UglifyJS.parse("// foo\n/*@preserve*/\n// bar\n/*@license*/\n//@license with the wrong comment type\n/*@cc_on something*/");
|
||||
assert.strictEqual(ast.print_to_string({comments: "some"}), "/*@preserve*/\n/*@license*/\n/*@cc_on something*/\n");
|
||||
});
|
||||
|
||||
it("Should be able to filter comments by passing a function", function() {
|
||||
var ast = UglifyJS.parse("/*TEST 123*/\n//An other comment\n//8 chars.");
|
||||
var f = function(node, comment) {
|
||||
@@ -16,6 +26,11 @@ describe("comment filters", function() {
|
||||
assert.strictEqual(ast.print_to_string({comments: f}), "/*TEST 123*/\n//8 chars.\n");
|
||||
});
|
||||
|
||||
it("Should be able to filter comments by passing regex in string format", function() {
|
||||
var ast = UglifyJS.parse("/*!test1*/\n/*test2*/\n//!test3\n//test4\n<!--test5\n<!--!test6\n-->test7\n-->!test8");
|
||||
assert.strictEqual(ast.print_to_string({comments: "/^!/"}), "/*!test1*/\n//!test3\n//!test6\n//!test8\n");
|
||||
});
|
||||
|
||||
it("Should be able to get the comment and comment type when using a function", function() {
|
||||
var ast = UglifyJS.parse("/*!test1*/\n/*test2*/\n//!test3\n//test4\n<!--test5\n<!--!test6\n-->test7\n-->!test8");
|
||||
var f = function(node, comment) {
|
||||
@@ -42,4 +57,9 @@ describe("comment filters", function() {
|
||||
|
||||
assert.strictEqual(ast.print_to_string({comments: f}), "#!Random comment\n//test1\n/*test2*/\n");
|
||||
});
|
||||
|
||||
it("Should never be able to filter comment5 when using 'some' as filter", function() {
|
||||
var ast = UglifyJS.parse("#!foo\n//foo\n/*@preserve*/\n/* please hide me */");
|
||||
assert.strictEqual(ast.print_to_string({comments: "some"}), "#!foo\n/*@preserve*/\n");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -75,4 +75,23 @@ describe("minify", function() {
|
||||
'let foo = x => "foo " + x;\nconsole.log(foo("bar"));');
|
||||
});
|
||||
});
|
||||
|
||||
describe("sourceMapInline", function() {
|
||||
it("should append source map to output js when sourceMapInline is enabled", function() {
|
||||
var result = Uglify.minify('var a = function(foo) { return foo; };', {
|
||||
fromString: true,
|
||||
sourceMapInline: true
|
||||
});
|
||||
var code = result.code;
|
||||
assert.strictEqual(code, "var a=function(n){return n};\n" +
|
||||
"//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIj8iXSwibmFtZXMiOlsiYSIsImZvbyJdLCJtYXBwaW5ncyI6IkFBQUEsR0FBSUEsR0FBSSxTQUFTQyxHQUFPLE1BQU9BIn0=");
|
||||
});
|
||||
it("should not append source map to output js when sourceMapInline is not enabled", function() {
|
||||
var result = Uglify.minify('var a = function(foo) { return foo; };', {
|
||||
fromString: true
|
||||
});
|
||||
var code = result.code;
|
||||
assert.strictEqual(code, "var a=function(n){return n};");
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -44,6 +44,7 @@ exports.minify = function(files, options) {
|
||||
sourceRoot : null,
|
||||
inSourceMap : null,
|
||||
sourceMapUrl : null,
|
||||
sourceMapInline : false,
|
||||
fromString : false,
|
||||
warnings : false,
|
||||
mangle : {},
|
||||
@@ -117,7 +118,7 @@ exports.minify = function(files, options) {
|
||||
if (typeof options.inSourceMap == "string") {
|
||||
inMap = JSON.parse(fs.readFileSync(options.inSourceMap, "utf8"));
|
||||
}
|
||||
if (options.outSourceMap) {
|
||||
if (options.outSourceMap || options.sourceMapInline) {
|
||||
output.source_map = UglifyJS.SourceMap({
|
||||
file: options.outSourceMap,
|
||||
orig: inMap,
|
||||
@@ -138,16 +139,19 @@ exports.minify = function(files, options) {
|
||||
var stream = UglifyJS.OutputStream(output);
|
||||
toplevel.print(stream);
|
||||
|
||||
var mappingUrlPrefix = "\n//# sourceMappingURL=";
|
||||
if (options.outSourceMap && typeof options.outSourceMap === "string" && options.sourceMapUrl !== false) {
|
||||
stream += mappingUrlPrefix + (typeof options.sourceMapUrl === "string" ? options.sourceMapUrl : options.outSourceMap);
|
||||
}
|
||||
|
||||
var source_map = output.source_map;
|
||||
if (source_map) {
|
||||
source_map = source_map + "";
|
||||
}
|
||||
|
||||
var mappingUrlPrefix = "\n//# sourceMappingURL=";
|
||||
if (options.sourceMapInline) {
|
||||
stream += mappingUrlPrefix + "data:application/json;charset=utf-8;base64," + new Buffer(source_map).toString("base64");
|
||||
} else if (options.outSourceMap && typeof options.outSourceMap === "string" && options.sourceMapUrl !== false) {
|
||||
stream += mappingUrlPrefix + (typeof options.sourceMapUrl === "string" ? options.sourceMapUrl : options.outSourceMap);
|
||||
}
|
||||
|
||||
return {
|
||||
code : stream + "",
|
||||
map : source_map
|
||||
|
||||
Reference in New Issue
Block a user