Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

updated doc to point out the potentially unsafe Array transformations

  • Loading branch information...
commit bd7780d7fb3a08194fd3eb89802f3f77a93eb977 1 parent 145317b
@mishoo authored
Showing with 205 additions and 36 deletions.
  1. +133 −32 README.html
  2. +72 −4 README.org
View
165 README.html
@@ -7,7 +7,7 @@
<title>UglifyJS -- a JavaScript parser/compressor/beautifier</title>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
<meta name="generator" content="Org-mode"/>
-<meta name="generated" content="2010-11-18 21:20:37 CET"/>
+<meta name="generated" content="2010-11-29 21:15:01 CET"/>
<meta name="author" content="Mihai Bazon"/>
<meta name="description" content="a JavaScript parser/compressor/beautifier in JavaScript"/>
<meta name="keywords" content="javascript, js, parser, compiler, compressor, mangle, minify, minifier"/>
@@ -82,16 +82,21 @@ <h1 class="title">UglifyJS &ndash; a JavaScript parser/compressor/beautifier</h1
<ul>
<li><a href="#sec-1">1 UglifyJS &mdash; a JavaScript parser/compressor/beautifier </a>
<ul>
-<li><a href="#sec-1_1">1.1 Usage </a>
+<li><a href="#sec-1_1">1.1 Unsafe transformations </a>
<ul>
-<li><a href="#sec-1_1_1">1.1.1 API </a></li>
-<li><a href="#sec-1_1_2">1.1.2 Beautifier shortcoming &ndash; no more comments </a></li>
+<li><a href="#sec-1_1_1">1.1.1 Calls involving the global Array constructor </a></li>
</ul>
</li>
-<li><a href="#sec-1_2">1.2 Compression &ndash; how good is it? </a></li>
-<li><a href="#sec-1_3">1.3 Bugs? </a></li>
-<li><a href="#sec-1_4">1.4 Links </a></li>
-<li><a href="#sec-1_5">1.5 License </a></li>
+<li><a href="#sec-1_2">1.2 Usage </a>
+<ul>
+<li><a href="#sec-1_2_1">1.2.1 API </a></li>
+<li><a href="#sec-1_2_2">1.2.2 Beautifier shortcoming &ndash; no more comments </a></li>
+</ul>
+</li>
+<li><a href="#sec-1_3">1.3 Compression &ndash; how good is it? </a></li>
+<li><a href="#sec-1_4">1.4 Bugs? </a></li>
+<li><a href="#sec-1_5">1.5 Links </a></li>
+<li><a href="#sec-1_6">1.6 License </a></li>
</ul>
</li>
</ul>
@@ -104,11 +109,14 @@ <h2 id="sec-1"><span class="section-number-2">1</span> UglifyJS &mdash; a JavaSc
<p>
+<b>Update</b>: please read the section on <a href="#sec-1_1">unsafe transformations</a>.
+</p>
+<p>
This package implements a general-purpose JavaScript
-parser/compressor/beautifier toolkit. It is developed on <a href="http://nodejs.org/">NodeJS</a>. With
-minimal changes it should work on any JavaScript platform (what is
-Node-specific is usage of <code>exports</code> and <code>JSON.stringify</code>, although the
-latter is quite portable now).
+parser/compressor/beautifier toolkit. It is developed on <a href="http://nodejs.org/">NodeJS</a>, but it
+should work on any JavaScript platform supporting the CommonJS module system
+(and if your platform of choice doesn't support CommonJS, you can easily
+implement it, or discard the <code>exports.*</code> lines from UglifyJS sources).
</p>
<p>
The tokenizer/parser generates an abstract syntax tree from JS code. You
@@ -212,11 +220,104 @@ <h2 id="sec-1"><span class="section-number-2">1</span> UglifyJS &mdash; a JavaSc
</div>
<div id="outline-container-1_1" class="outline-3">
-<h3 id="sec-1_1"><span class="section-number-3">1.1</span> Usage </h3>
+<h3 id="sec-1_1"><span class="section-number-3">1.1</span> <span class="target">Unsafe transformations</span> </h3>
<div class="outline-text-3" id="text-1_1">
<p>
+UglifyJS tries its best to achieve great compression while leaving the
+semantics of the code intact. In general, if your code logic is broken by
+UglifyJS then it's a bug in UglifyJS and you should report it and I should
+fix it. :-)
+</p>
+<p>
+However, I opted to include the following potentially unsafe transformations
+as default behavior. Discussion is welcome, if you have ideas of how to
+handle this better, or any objections to these optimizations, please let me
+know.
+</p>
+
+</div>
+
+<div id="outline-container-1_1_1" class="outline-4">
+<h4 id="sec-1_1_1"><span class="section-number-4">1.1.1</span> Calls involving the global Array constructor </h4>
+<div class="outline-text-4" id="text-1_1_1">
+
+
+<p>
+The following transformations occur:
+</p>
+
+
+
+<pre class="src src-espresso"><span style="color: #afeeee; font-weight: bold;">new</span> <span style="color: #87ceeb; font-weight: bold;">Array</span>(1, 2, 3, 4) =&gt; [1,2,3,4]
+Array(a, b, c) =&gt; [a,b,c]
+<span style="color: #afeeee; font-weight: bold;">new</span> <span style="color: #87ceeb; font-weight: bold;">Array</span>(5) =&gt; Array(5)
+<span style="color: #afeeee; font-weight: bold;">new</span> <span style="color: #87ceeb; font-weight: bold;">Array</span>(a) =&gt; Array(a)
+</pre>
+
+
+
+<p>
+These are all safe unless the Array name isn't redefined. JavaScript does
+allow one to globally redefine Array (and pretty much everything, in fact)
+but I personally don't see why would anyone do that.
+</p>
+<p>
+UglifyJS does handle the case where Array is redefined locally, or even
+globally but with a <code>function</code> or <code>var</code> declaration. Therefore, in the
+following cases UglifyJS <b>doesn't touch</b> calls or instantiations of Array:
+</p>
+
+
+
+<pre class="src src-espresso"><span style="color: #add8e6;">// </span><span style="color: #add8e6;">case 1. globally declared variable
+</span> <span style="color: #afeeee; font-weight: bold;">var</span> <span style="color: #40e0d0; font-weight: bold;">Array</span>;
+ <span style="color: #afeeee; font-weight: bold;">new</span> <span style="color: #87ceeb; font-weight: bold;">Array</span>(1, 2, 3);
+ Array(a, b);
+
+ <span style="color: #add8e6;">// </span><span style="color: #add8e6;">or (can be declared later)
+</span> <span style="color: #afeeee; font-weight: bold;">new</span> <span style="color: #87ceeb; font-weight: bold;">Array</span>(1, 2, 3);
+ <span style="color: #afeeee; font-weight: bold;">var</span> <span style="color: #40e0d0; font-weight: bold;">Array</span>;
+
+ <span style="color: #add8e6;">// </span><span style="color: #add8e6;">or (can be a function)
+</span> <span style="color: #afeeee; font-weight: bold;">new</span> <span style="color: #87ceeb; font-weight: bold;">Array</span>(1, 2, 3);
+ <span style="color: #afeeee; font-weight: bold;">function</span> <span style="color: #7fffd4; font-weight: bold;">Array</span>() { ... }
+
+<span style="color: #add8e6;">// </span><span style="color: #add8e6;">case 2. declared in a function
+</span> (<span style="color: #afeeee; font-weight: bold;">function</span>(){
+ a = <span style="color: #afeeee; font-weight: bold;">new</span> <span style="color: #87ceeb; font-weight: bold;">Array</span>(1, 2, 3);
+ b = Array(5, 6);
+ <span style="color: #afeeee; font-weight: bold;">var</span> <span style="color: #40e0d0; font-weight: bold;">Array</span>;
+ })();
+
+ <span style="color: #add8e6;">// </span><span style="color: #add8e6;">or
+</span> (<span style="color: #afeeee; font-weight: bold;">function</span>(<span style="color: #40e0d0; font-weight: bold;">Array</span>){
+ <span style="color: #afeeee; font-weight: bold;">return</span> Array(5, 6, 7);
+ })();
+
+ <span style="color: #add8e6;">// </span><span style="color: #add8e6;">or
+</span> (<span style="color: #afeeee; font-weight: bold;">function</span>(){
+ <span style="color: #afeeee; font-weight: bold;">return</span> <span style="color: #afeeee; font-weight: bold;">new</span> <span style="color: #87ceeb; font-weight: bold;">Array</span>(1, 2, 3, 4);
+ <span style="color: #afeeee; font-weight: bold;">function</span> <span style="color: #7fffd4; font-weight: bold;">Array</span>() { ... }
+ })();
+
+ <span style="color: #add8e6;">// </span><span style="color: #add8e6;">etc.
+</span></pre>
+
+
+
+</div>
+</div>
+
+</div>
+
+<div id="outline-container-1_2" class="outline-3">
+<h3 id="sec-1_2"><span class="section-number-3">1.2</span> Usage </h3>
+<div class="outline-text-3" id="text-1_2">
+
+
+<p>
There is a helper script now &mdash; <code>bin/uglifyjs</code> &mdash; that uses the library to
compress a script using the maximum compression settings. Synopsis:
</p>
@@ -334,9 +435,9 @@ <h3 id="sec-1_1"><span class="section-number-3">1.1</span> Usage </h3>
</div>
-<div id="outline-container-1_1_1" class="outline-4">
-<h4 id="sec-1_1_1"><span class="section-number-4">1.1.1</span> API </h4>
-<div class="outline-text-4" id="text-1_1_1">
+<div id="outline-container-1_2_1" class="outline-4">
+<h4 id="sec-1_2_1"><span class="section-number-4">1.2.1</span> API </h4>
+<div class="outline-text-4" id="text-1_2_1">
<p>
@@ -429,9 +530,9 @@ <h4 id="sec-1_1_1"><span class="section-number-4">1.1.1</span> API </h4>
</div>
-<div id="outline-container-1_1_2" class="outline-4">
-<h4 id="sec-1_1_2"><span class="section-number-4">1.1.2</span> Beautifier shortcoming &ndash; no more comments </h4>
-<div class="outline-text-4" id="text-1_1_2">
+<div id="outline-container-1_2_2" class="outline-4">
+<h4 id="sec-1_2_2"><span class="section-number-4">1.2.2</span> Beautifier shortcoming &ndash; no more comments </h4>
+<div class="outline-text-4" id="text-1_2_2">
<p>
@@ -452,9 +553,9 @@ <h4 id="sec-1_1_2"><span class="section-number-4">1.1.2</span> Beautifier shortc
</div>
-<div id="outline-container-1_2" class="outline-3">
-<h3 id="sec-1_2"><span class="section-number-3">1.2</span> Compression &ndash; how good is it? </h3>
-<div class="outline-text-3" id="text-1_2">
+<div id="outline-container-1_3" class="outline-3">
+<h3 id="sec-1_3"><span class="section-number-3">1.3</span> Compression &ndash; how good is it? </h3>
+<div class="outline-text-3" id="text-1_3">
<p>
@@ -519,9 +620,9 @@ <h3 id="sec-1_2"><span class="section-number-3">1.2</span> Compression &ndash; h
</div>
-<div id="outline-container-1_3" class="outline-3">
-<h3 id="sec-1_3"><span class="section-number-3">1.3</span> Bugs? </h3>
-<div class="outline-text-3" id="text-1_3">
+<div id="outline-container-1_4" class="outline-3">
+<h3 id="sec-1_4"><span class="section-number-3">1.4</span> Bugs? </h3>
+<div class="outline-text-3" id="text-1_4">
<p>
@@ -545,9 +646,9 @@ <h3 id="sec-1_3"><span class="section-number-3">1.3</span> Bugs? </h3>
</div>
-<div id="outline-container-1_4" class="outline-3">
-<h3 id="sec-1_4"><span class="section-number-3">1.4</span> Links </h3>
-<div class="outline-text-3" id="text-1_4">
+<div id="outline-container-1_5" class="outline-3">
+<h3 id="sec-1_5"><span class="section-number-3">1.5</span> Links </h3>
+<div class="outline-text-3" id="text-1_5">
<ul>
@@ -573,9 +674,9 @@ <h3 id="sec-1_4"><span class="section-number-3">1.4</span> Links </h3>
</div>
-<div id="outline-container-1_5" class="outline-3">
-<h3 id="sec-1_5"><span class="section-number-3">1.5</span> License </h3>
-<div class="outline-text-3" id="text-1_5">
+<div id="outline-container-1_6" class="outline-3">
+<h3 id="sec-1_6"><span class="section-number-3">1.6</span> License </h3>
+<div class="outline-text-3" id="text-1_6">
<p>
@@ -624,7 +725,7 @@ <h2 class="footnotes">Footnotes: </h2>
<div id="postamble">
<p class="author"> Author: Mihai Bazon
</p>
-<p class="date"> Date: 2010-11-18 21:20:37 CET</p>
+<p class="date"> Date: 2010-11-29 21:15:01 CET</p>
<p class="creator">HTML generated by org-mode 7.01trans in emacs 23</p>
</div>
</div>
View
76 README.org
@@ -7,11 +7,13 @@
* UglifyJS --- a JavaScript parser/compressor/beautifier
+*Update*: please read the section on [[unsafe transformations]].
+
This package implements a general-purpose JavaScript
-parser/compressor/beautifier toolkit. It is developed on [[http://nodejs.org/][NodeJS]]. With
-minimal changes it should work on any JavaScript platform (what is
-Node-specific is usage of =exports= and =JSON.stringify=, although the
-latter is quite portable now).
+parser/compressor/beautifier toolkit. It is developed on [[http://nodejs.org/][NodeJS]], but it
+should work on any JavaScript platform supporting the CommonJS module system
+(and if your platform of choice doesn't support CommonJS, you can easily
+implement it, or discard the =exports.*= lines from UglifyJS sources).
The tokenizer/parser generates an abstract syntax tree from JS code. You
can then traverse the AST to learn more about the code, or do various
@@ -70,6 +72,72 @@ manipulates the AST generated by the parser to provide the following:
=return=, =throw=, =break= or =continue= statement, except
function/variable declarations).
+** <<Unsafe transformations>>
+
+UglifyJS tries its best to achieve great compression while leaving the
+semantics of the code intact. In general, if your code logic is broken by
+UglifyJS then it's a bug in UglifyJS and you should report it and I should
+fix it. :-)
+
+However, I opted to include the following potentially unsafe transformations
+as default behavior. Discussion is welcome, if you have ideas of how to
+handle this better, or any objections to these optimizations, please let me
+know.
+
+*** Calls involving the global Array constructor
+
+The following transformations occur:
+
+#+BEGIN_SRC espresso
+new Array(1, 2, 3, 4) => [1,2,3,4]
+Array(a, b, c) => [a,b,c]
+new Array(5) => Array(5)
+new Array(a) => Array(a)
+#+END_SRC
+
+These are all safe unless the Array name isn't redefined. JavaScript does
+allow one to globally redefine Array (and pretty much everything, in fact)
+but I personally don't see why would anyone do that.
+
+UglifyJS does handle the case where Array is redefined locally, or even
+globally but with a =function= or =var= declaration. Therefore, in the
+following cases UglifyJS *doesn't touch* calls or instantiations of Array:
+
+#+BEGIN_SRC espresso
+// case 1. globally declared variable
+ var Array;
+ new Array(1, 2, 3);
+ Array(a, b);
+
+ // or (can be declared later)
+ new Array(1, 2, 3);
+ var Array;
+
+ // or (can be a function)
+ new Array(1, 2, 3);
+ function Array() { ... }
+
+// case 2. declared in a function
+ (function(){
+ a = new Array(1, 2, 3);
+ b = Array(5, 6);
+ var Array;
+ })();
+
+ // or
+ (function(Array){
+ return Array(5, 6, 7);
+ })();
+
+ // or
+ (function(){
+ return new Array(1, 2, 3, 4);
+ function Array() { ... }
+ })();
+
+ // etc.
+#+END_SRC
+
** Usage
There is a helper script now --- =bin/uglifyjs= --- that uses the library to
Please sign in to comment.
Something went wrong with that request. Please try again.