- rename `screw_ie8` to `ie8`
- rename `mangle.except` to `mangle.reserved`
- rename `mangle.properties.ignore_quoted` to `mangle.properties.keep_quoted`
- compact `sourceMap` options
- more stringent verification on input `options`
- toplevel shorthands
- `ie8`
- `keep_fnames`
- `toplevel`
- `warnings`
- support arrays and unquoted string values on CLI
- drop `fromString` from `minify()`
- `minify()` no longer handles any `fs` operations
- unify order of operations for `mangle_properties()` on CLI & API
- `bin/uglifyjs` used to `mangle_properties()` before even `Compressor`
- `minify()` used to `mangle_properties()` after `Compressor` but before `mangle_names()`
- both will now do `Compressor`, `mangle_names()` then `mangle_properties()`
- `options.parse` / `--parse` for parser options beyond `bare_returns`
- add `mangle.properties.builtins` to disable built-in reserved list
- disable with `--mangle-props builtins` on CLI
- `warnings` now off by default
- add `--warn` and `--verbose` on CLI
- drop `--enclose`
- drop `--export-all`
- drop `--reserved-file`
- use `--mangle reserved` instead
- drop `--reserve-domprops`
- enabled by default, disable with `--mangle-props domprops`
- drop `--prefix`
- use `--source-map base` instead
- drop `--lint`
- remove `bin/extract-props.js`
- limit exposure of internal APIs
- update documentations
closes#96closes#102closes#136closes#166closes#243closes#254closes#261closes#311closes#700closes#748closes#912closes#1072closes#1366fixes#101fixes#123fixes#124fixes#263fixes#379fixes#419fixes#423fixes#461fixes#465fixes#576fixes#737fixes#772fixes#958fixes#1036fixes#1142fixes#1175fixes#1220fixes#1223fixes#1280fixes#1359fixes#1368
- move these optimisations out from `Compressor` to `OutputStream`
- fixes behaviour inconsistency when running uglified code from global or module levels due to redefinition
- omitting trailing semi-colon in do-while breaks non-browser parser, e.g. uglify-js 1.x
- trailing semi-colon only breaks IE8 if followed by `else` or `while`
- always use braces in do-while body to workaround 2nd case with no size loss in compression
fixes#1568
- remove extra tree scanning phase for `negate_iife`
- `negate_iife` now only deals with the narrowest form, i.e. IIFE sitting directly under `AST_SimpleStatement`
- `booleans`, `conditionals` etc. will now take care the rest via more accurate accounting
- `a(); void b();` => `a(); b();`
fixes#1288closes#1451
catch identifier is mangled correctly for ES5 standards-compliant JS engines by default.
Unconditionally use the ie8 if/do-while workaround whether or not --screw-ie8 is enabled.
To support non-standard ie8 javascript use: uglifyjs --support-ie8
The option added in fbbaa42ee5 wasn't
being respected inside object literals, so quoted property names would
still be stripped out with this option.
This is mostly a corner-case, but useful when the output is passed to
something like the Closure compiler, where quoted property names can be
used to prevent mangling.
* Don't interpret strings with escaped content as directive
* Don't interpret strings after empty statement as directive
* Adapt output to prevent strings being represent as directive
* Introduce UGLIFY_DEBUG to allow internal testing like EXPECT_DIRECTIVE
It's now available during tree walking, i.e. walker.has_directive("use
asm"), rather than as part of the scope. It's thus no longer necessary
to call `figure_out_scope` before codegen. Added special bits in the
code generator to overcome the fact that it doesn't inherit from
TreeWalker.
Fix#861
`-q 0` (default) use single or double quotes such as to minimize the number of
bytes (prefers double quotes when both will do); this is the previous
behavior.
`-q 1` -- always use single quotes
`-q 2` -- always use double quotes
`-q 3` or just `-q` -- always use the original quotes.
Related codegen option: `quote_style`.
Close#495Close#460
Some `yargs` guru please tell me why `uglifyjs --help` doesn't display the
help string for `-q` / `--quotes`, and why it doesn't output the expected
argument types anymore, like good old `optimist` did.
`\uFEFF` (ZERO WIDTH NO-BREAK SPACE) is removed when parsing, but was
un-escaped for the output when `ascii_only` was false.
When using
UglifyJS multiple times (creating packages from minified sources, for
example), this would lead to problems because the byte was removed when
parsing for the second time.
NaN and Infinity were replaced in the output generation, instead of
during compression. This could lead to results where `1/0` was inserted
without parens leading to invalid output.
The nodes are replaced in the compression step now, and the output
generation returns their regular names. This should not be a problem,
since they're already only constructed from the original name.
As `maybe_newline()` is only called when `might_need_semicolon` is `true`, the `max_line_len` option has no effect for files without (or with very few) semicolons (like JSON files). A simple for this problem is to use `maybe_newline()` instead of `noop` as the `newline()` function in non-beautify mode.
The "key" property was always "set" or "get", which didn't make much sense.
Now it'll be the actual name of the setter/getter (AST_Node), and the
AST_Accessor object itself, which represents the function, won't store any
name.
Close#319
1529ab96 started to do this (by considering holes to be separate from
"undefined") but it still converted
[1,,] (length 2, last element hole, trailing comma)
to
[1,] (length 1, trailing comma)
Unfortunately the test suite doesn't really make this clear: the new test here
passes with or without this patch because run-tests.js beautifys the expected
output (in "make_code"), which does the incorrect transformation! If you make
some manual change to arrays.js to make the test fail and see the INPUT and
OUTPUT, then you can see that without this fix, [1,,] -> [1,], and with this fix
it stays [1,,].
Since \0 might be mistakenly interpreted as octal if followed by a
number and using literal null is in some cases interpreted as end of
string, escape null as \x00.
1b6bcca7 was a first attempt at this. That commit made Uglify stop replacing
holes with undefined, but instead it started replacing undefined with
holes. This is slightly problematic, because there is a difference between a
hole and an undefined value. More problematically, it changed [1,undefined] to
[1,] which generally doesn't even parse as a hole (just as a trailing comma), so
it didn't even preserve the length of the array!
Instead, parse holes as their own special AST node which prints invisibly.
This is useful while compressing generated code; for example compressing JS
compiled by CoffeeScript (assuming you got a source map):
uglifyjs2 --in-source-map generated.js.map \
--source-map uglified.js.map \
-o uglified.js
The above assumes you have a "generated.js.map" file which is the source
mapping between your CoffeeScript and the generated.js (compiled output from
CoffeeScript). The name of the input file is not present in this example;
it will be fetched from the source map (but it can be passed manually too).
The output will be in "uglified.js" and the output map "uglified.js.map"
will actually map to the original CoffeeScript code, rather than to
generated.js.
- a = a + x ==> a+=x
- joining consecutive var statements (hoisting is not always desirable)
- x == false ==> x == 0, x != true ==> x != 1
- x, x ==> x; x = exp(), x ==> x = exp()
- discarding useless break-s
- all symbols now have a `thedef` property which is a SymbolDef object,
instead of the `uniq` that we had before (pointing to the first occurrence
of the name as declaration).
- for undeclared symbols we still create a SymbolDef object in the toplevel
scope but mark it "undeclared"
- we can now call figure_out_scope after squeezing, which is useful in order
not to mangle names that were dropped by the squeezer
The following nodes were instances of AST_BlockStatement: AST_Scope,
AST_SwitchBlock, AST_SwitchBranch. Also, AST_Try, AST_Catch, AST_Finally
were having a body instanceof AST_BlockStatement.
Overloading the meaning of AST_BlockStatement this way turned out to be a
mess; we now have an AST_Block class that is the base class for things
having a block of statements (might or might not be bracketed). The
`this.body` of AST_Scope, AST_Try, AST_Catch, AST_Finally is now an array of
statements (as they inherit from AST_Block).
Avoiding calling superclass's _walk function in walkers (turns out we walked
a node multiple times).