~ubuntu-branches/ubuntu/vivid/emscripten/vivid

« back to all changes in this revision

Viewing changes to tools/eliminator/node_modules/uglify-js/README.html

  • Committer: Package Import Robot
  • Author(s): Sylvestre Ledru
  • Date: 2013-05-02 13:11:51 UTC
  • Revision ID: package-import@ubuntu.com-20130502131151-q8dvteqr1ef2x7xz
Tags: upstream-1.4.1~20130504~adb56cb
Import upstream version 1.4.1~20130504~adb56cb

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
<?xml version="1.0" encoding="utf-8"?>
 
2
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
 
3
               "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
 
4
<html xmlns="http://www.w3.org/1999/xhtml"
 
5
lang="en" xml:lang="en">
 
6
<head>
 
7
<title>UglifyJS -- a JavaScript parser/compressor/beautifier</title>
 
8
<meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
 
9
<meta name="generator" content="Org-mode"/>
 
10
<meta name="generated" content="2011-08-20 10:08:28 EEST"/>
 
11
<meta name="author" content="Mihai Bazon"/>
 
12
<meta name="description" content="a JavaScript parser/compressor/beautifier in JavaScript"/>
 
13
<meta name="keywords" content="javascript, js, parser, compiler, compressor, mangle, minify, minifier"/>
 
14
<style type="text/css">
 
15
 <!--/*--><![CDATA[/*><!--*/
 
16
  html { font-family: Times, serif; font-size: 12pt; }
 
17
  .title  { text-align: center; }
 
18
  .todo   { color: red; }
 
19
  .done   { color: green; }
 
20
  .tag    { background-color: #add8e6; font-weight:normal }
 
21
  .target { }
 
22
  .timestamp { color: #bebebe; }
 
23
  .timestamp-kwd { color: #5f9ea0; }
 
24
  p.verse { margin-left: 3% }
 
25
  pre {
 
26
        border: 1pt solid #AEBDCC;
 
27
        background-color: #F3F5F7;
 
28
        padding: 5pt;
 
29
        font-family: courier, monospace;
 
30
        font-size: 90%;
 
31
        overflow:auto;
 
32
  }
 
33
  table { border-collapse: collapse; }
 
34
  td, th { vertical-align: top; }
 
35
  dt { font-weight: bold; }
 
36
  div.figure { padding: 0.5em; }
 
37
  div.figure p { text-align: center; }
 
38
  textarea { overflow-x: auto; }
 
39
  .linenr { font-size:smaller }
 
40
  .code-highlighted {background-color:#ffff00;}
 
41
  .org-info-js_info-navigation { border-style:none; }
 
42
  #org-info-js_console-label { font-size:10px; font-weight:bold;
 
43
                               white-space:nowrap; }
 
44
  .org-info-js_search-highlight {background-color:#ffff00; color:#000000;
 
45
                                 font-weight:bold; }
 
46
  /*]]>*/-->
 
47
</style>
 
48
<link rel="stylesheet" type="text/css" href="docstyle.css" />
 
49
<script type="text/javascript">
 
50
<!--/*--><![CDATA[/*><!--*/
 
51
 function CodeHighlightOn(elem, id)
 
52
 {
 
53
   var target = document.getElementById(id);
 
54
   if(null != target) {
 
55
     elem.cacheClassElem = elem.className;
 
56
     elem.cacheClassTarget = target.className;
 
57
     target.className = "code-highlighted";
 
58
     elem.className   = "code-highlighted";
 
59
   }
 
60
 }
 
61
 function CodeHighlightOff(elem, id)
 
62
 {
 
63
   var target = document.getElementById(id);
 
64
   if(elem.cacheClassElem)
 
65
     elem.className = elem.cacheClassElem;
 
66
   if(elem.cacheClassTarget)
 
67
     target.className = elem.cacheClassTarget;
 
68
 }
 
69
/*]]>*///-->
 
70
</script>
 
71
 
 
72
</head>
 
73
<body>
 
74
<div id="content">
 
75
 
 
76
<h1 class="title">UglifyJS &ndash; a JavaScript parser/compressor/beautifier</h1>
 
77
 
 
78
 
 
79
<div id="table-of-contents">
 
80
<h2>Table of Contents</h2>
 
81
<div id="text-table-of-contents">
 
82
<ul>
 
83
<li><a href="#sec-1">1 UglifyJS &mdash; a JavaScript parser/compressor/beautifier </a>
 
84
<ul>
 
85
<li><a href="#sec-1_1">1.1 Unsafe transformations </a>
 
86
<ul>
 
87
<li><a href="#sec-1_1_1">1.1.1 Calls involving the global Array constructor </a></li>
 
88
<li><a href="#sec-1_1_2">1.1.2 <code>obj.toString()</code> ==&gt; <code>obj+“”</code> </a></li>
 
89
</ul>
 
90
</li>
 
91
<li><a href="#sec-1_2">1.2 Install (NPM) </a></li>
 
92
<li><a href="#sec-1_3">1.3 Install latest code from GitHub </a></li>
 
93
<li><a href="#sec-1_4">1.4 Usage </a>
 
94
<ul>
 
95
<li><a href="#sec-1_4_1">1.4.1 API </a></li>
 
96
<li><a href="#sec-1_4_2">1.4.2 Beautifier shortcoming &ndash; no more comments </a></li>
 
97
</ul>
 
98
</li>
 
99
<li><a href="#sec-1_5">1.5 Compression &ndash; how good is it? </a></li>
 
100
<li><a href="#sec-1_6">1.6 Bugs? </a></li>
 
101
<li><a href="#sec-1_7">1.7 Links </a></li>
 
102
<li><a href="#sec-1_8">1.8 License </a></li>
 
103
</ul>
 
104
</li>
 
105
</ul>
 
106
</div>
 
107
</div>
 
108
 
 
109
<div id="outline-container-1" class="outline-2">
 
110
<h2 id="sec-1"><span class="section-number-2">1</span> UglifyJS &mdash; a JavaScript parser/compressor/beautifier </h2>
 
111
<div class="outline-text-2" id="text-1">
 
112
 
 
113
 
 
114
<p>
 
115
This package implements a general-purpose JavaScript
 
116
parser/compressor/beautifier toolkit.  It is developed on <a href="http://nodejs.org/">NodeJS</a>, but it
 
117
should work on any JavaScript platform supporting the CommonJS module system
 
118
(and if your platform of choice doesn't support CommonJS, you can easily
 
119
implement it, or discard the <code>exports.*</code> lines from UglifyJS sources).
 
120
</p>
 
121
<p>
 
122
The tokenizer/parser generates an abstract syntax tree from JS code.  You
 
123
can then traverse the AST to learn more about the code, or do various
 
124
manipulations on it.  This part is implemented in <a href="../lib/parse-js.js">parse-js.js</a> and it's a
 
125
port to JavaScript of the excellent <a href="http://marijn.haverbeke.nl/parse-js/">parse-js</a> Common Lisp library from <a href="http://marijn.haverbeke.nl/">Marijn Haverbeke</a>.
 
126
</p>
 
127
<p>
 
128
( See <a href="http://github.com/mishoo/cl-uglify-js">cl-uglify-js</a> if you're looking for the Common Lisp version of
 
129
UglifyJS. )
 
130
</p>
 
131
<p>
 
132
The second part of this package, implemented in <a href="../lib/process.js">process.js</a>, inspects and
 
133
manipulates the AST generated by the parser to provide the following:
 
134
</p>
 
135
<ul>
 
136
<li>
 
137
ability to re-generate JavaScript code from the AST.  Optionally
 
138
indented&mdash;you can use this if you want to “beautify” a program that has
 
139
been compressed, so that you can inspect the source.  But you can also run
 
140
our code generator to print out an AST without any whitespace, so you
 
141
achieve compression as well.
 
142
 
 
143
</li>
 
144
<li>
 
145
shorten variable names (usually to single characters).  Our mangler will
 
146
analyze the code and generate proper variable names, depending on scope
 
147
and usage, and is smart enough to deal with globals defined elsewhere, or
 
148
with <code>eval()</code> calls or <code>with{}</code> statements.  In short, if <code>eval()</code> or
 
149
<code>with{}</code> are used in some scope, then all variables in that scope and any
 
150
variables in the parent scopes will remain unmangled, and any references
 
151
to such variables remain unmangled as well.
 
152
 
 
153
</li>
 
154
<li>
 
155
various small optimizations that may lead to faster code but certainly
 
156
lead to smaller code.  Where possible, we do the following:
 
157
 
 
158
<ul>
 
159
<li>
 
160
foo["bar"]  ==&gt;  foo.bar
 
161
 
 
162
</li>
 
163
<li>
 
164
remove block brackets <code>{}</code>
 
165
 
 
166
</li>
 
167
<li>
 
168
join consecutive var declarations:
 
169
var a = 10; var b = 20; ==&gt; var a=10,b=20;
 
170
 
 
171
</li>
 
172
<li>
 
173
resolve simple constant expressions: 1 +2 * 3 ==&gt; 7.  We only do the
 
174
replacement if the result occupies less bytes; for example 1/3 would
 
175
translate to 0.333333333333, so in this case we don't replace it.
 
176
 
 
177
</li>
 
178
<li>
 
179
consecutive statements in blocks are merged into a sequence; in many
 
180
cases, this leaves blocks with a single statement, so then we can remove
 
181
the block brackets.
 
182
 
 
183
</li>
 
184
<li>
 
185
various optimizations for IF statements:
 
186
 
 
187
<ul>
 
188
<li>
 
189
if (foo) bar(); else baz(); ==&gt; foo?bar():baz();
 
190
</li>
 
191
<li>
 
192
if (!foo) bar(); else baz(); ==&gt; foo?baz():bar();
 
193
</li>
 
194
<li>
 
195
if (foo) bar(); ==&gt; foo&amp;&amp;bar();
 
196
</li>
 
197
<li>
 
198
if (!foo) bar(); ==&gt; foo||bar();
 
199
</li>
 
200
<li>
 
201
if (foo) return bar(); else return baz(); ==&gt; return foo?bar():baz();
 
202
</li>
 
203
<li>
 
204
if (foo) return bar(); else something(); ==&gt; {if(foo)return bar();something()}
 
205
 
 
206
</li>
 
207
</ul>
 
208
</li>
 
209
<li>
 
210
remove some unreachable code and warn about it (code that follows a
 
211
<code>return</code>, <code>throw</code>, <code>break</code> or <code>continue</code> statement, except
 
212
function/variable declarations).
 
213
</li>
 
214
</ul>
 
215
</li>
 
216
</ul>
 
217
 
 
218
 
 
219
 
 
220
</div>
 
221
 
 
222
<div id="outline-container-1_1" class="outline-3">
 
223
<h3 id="sec-1_1"><span class="section-number-3">1.1</span> <span class="target">Unsafe transformations</span>  </h3>
 
224
<div class="outline-text-3" id="text-1_1">
 
225
 
 
226
 
 
227
<p>
 
228
The following transformations can in theory break code, although they're
 
229
probably safe in most practical cases.  To enable them you need to pass the
 
230
<code>--unsafe</code> flag.
 
231
</p>
 
232
 
 
233
</div>
 
234
 
 
235
<div id="outline-container-1_1_1" class="outline-4">
 
236
<h4 id="sec-1_1_1"><span class="section-number-4">1.1.1</span> Calls involving the global Array constructor </h4>
 
237
<div class="outline-text-4" id="text-1_1_1">
 
238
 
 
239
 
 
240
<p>
 
241
The following transformations occur:
 
242
</p>
 
243
 
 
244
 
 
245
 
 
246
<pre class="src src-js"><span style="color: #a020f0;">new</span> <span style="color: #228b22;">Array</span>(1, 2, 3, 4)  =&gt; [1,2,3,4]
 
247
Array(a, b, c)         =&gt; [a,b,c]
 
248
<span style="color: #a020f0;">new</span> <span style="color: #228b22;">Array</span>(5)           =&gt; Array(5)
 
249
<span style="color: #a020f0;">new</span> <span style="color: #228b22;">Array</span>(a)           =&gt; Array(a)
 
250
</pre>
 
251
 
 
252
 
 
253
 
 
254
<p>
 
255
These are all safe if the Array name isn't redefined.  JavaScript does allow
 
256
one to globally redefine Array (and pretty much everything, in fact) but I
 
257
personally don't see why would anyone do that.
 
258
</p>
 
259
<p>
 
260
UglifyJS does handle the case where Array is redefined locally, or even
 
261
globally but with a <code>function</code> or <code>var</code> declaration.  Therefore, in the
 
262
following cases UglifyJS <b>doesn't touch</b> calls or instantiations of Array:
 
263
</p>
 
264
 
 
265
 
 
266
 
 
267
<pre class="src src-js"><span style="color: #b22222;">// </span><span style="color: #b22222;">case 1.  globally declared variable
 
268
</span>  <span style="color: #a020f0;">var</span> <span style="color: #b8860b;">Array</span>;
 
269
  <span style="color: #a020f0;">new</span> <span style="color: #228b22;">Array</span>(1, 2, 3);
 
270
  Array(a, b);
 
271
 
 
272
  <span style="color: #b22222;">// </span><span style="color: #b22222;">or (can be declared later)
 
273
</span>  <span style="color: #a020f0;">new</span> <span style="color: #228b22;">Array</span>(1, 2, 3);
 
274
  <span style="color: #a020f0;">var</span> <span style="color: #b8860b;">Array</span>;
 
275
 
 
276
  <span style="color: #b22222;">// </span><span style="color: #b22222;">or (can be a function)
 
277
</span>  <span style="color: #a020f0;">new</span> <span style="color: #228b22;">Array</span>(1, 2, 3);
 
278
  <span style="color: #a020f0;">function</span> <span style="color: #0000ff;">Array</span>() { ... }
 
279
 
 
280
<span style="color: #b22222;">// </span><span style="color: #b22222;">case 2.  declared in a function
 
281
</span>  (<span style="color: #a020f0;">function</span>(){
 
282
    a = <span style="color: #a020f0;">new</span> <span style="color: #228b22;">Array</span>(1, 2, 3);
 
283
    b = Array(5, 6);
 
284
    <span style="color: #a020f0;">var</span> <span style="color: #b8860b;">Array</span>;
 
285
  })();
 
286
 
 
287
  <span style="color: #b22222;">// </span><span style="color: #b22222;">or
 
288
</span>  (<span style="color: #a020f0;">function</span>(<span style="color: #b8860b;">Array</span>){
 
289
    <span style="color: #a020f0;">return</span> Array(5, 6, 7);
 
290
  })();
 
291
 
 
292
  <span style="color: #b22222;">// </span><span style="color: #b22222;">or
 
293
</span>  (<span style="color: #a020f0;">function</span>(){
 
294
    <span style="color: #a020f0;">return</span> <span style="color: #a020f0;">new</span> <span style="color: #228b22;">Array</span>(1, 2, 3, 4);
 
295
    <span style="color: #a020f0;">function</span> <span style="color: #0000ff;">Array</span>() { ... }
 
296
  })();
 
297
 
 
298
  <span style="color: #b22222;">// </span><span style="color: #b22222;">etc.
 
299
</span></pre>
 
300
 
 
301
 
 
302
 
 
303
</div>
 
304
 
 
305
</div>
 
306
 
 
307
<div id="outline-container-1_1_2" class="outline-4">
 
308
<h4 id="sec-1_1_2"><span class="section-number-4">1.1.2</span> <code>obj.toString()</code> ==&gt; <code>obj+“”</code> </h4>
 
309
<div class="outline-text-4" id="text-1_1_2">
 
310
 
 
311
 
 
312
</div>
 
313
</div>
 
314
 
 
315
</div>
 
316
 
 
317
<div id="outline-container-1_2" class="outline-3">
 
318
<h3 id="sec-1_2"><span class="section-number-3">1.2</span> Install (NPM) </h3>
 
319
<div class="outline-text-3" id="text-1_2">
 
320
 
 
321
 
 
322
<p>
 
323
UglifyJS is now available through NPM &mdash; <code>npm install uglify-js</code> should do
 
324
the job.
 
325
</p>
 
326
</div>
 
327
 
 
328
</div>
 
329
 
 
330
<div id="outline-container-1_3" class="outline-3">
 
331
<h3 id="sec-1_3"><span class="section-number-3">1.3</span> Install latest code from GitHub </h3>
 
332
<div class="outline-text-3" id="text-1_3">
 
333
 
 
334
 
 
335
 
 
336
 
 
337
 
 
338
<pre class="src src-sh"><span style="color: #b22222;">## </span><span style="color: #b22222;">clone the repository
 
339
</span>mkdir -p /where/you/wanna/put/it
 
340
<span style="color: #da70d6;">cd</span> /where/you/wanna/put/it
 
341
git clone git://github.com/mishoo/UglifyJS.git
 
342
 
 
343
<span style="color: #b22222;">## </span><span style="color: #b22222;">make the module available to Node
 
344
</span>mkdir -p ~/.node_libraries/
 
345
<span style="color: #da70d6;">cd</span> ~/.node_libraries/
 
346
ln -s /where/you/wanna/put/it/UglifyJS/uglify-js.js
 
347
 
 
348
<span style="color: #b22222;">## </span><span style="color: #b22222;">and if you want the CLI script too:
 
349
</span>mkdir -p ~/bin
 
350
<span style="color: #da70d6;">cd</span> ~/bin
 
351
ln -s /where/you/wanna/put/it/UglifyJS/bin/uglifyjs
 
352
  <span style="color: #b22222;"># </span><span style="color: #b22222;">(then add ~/bin to your $PATH if it's not there already)
 
353
</span></pre>
 
354
 
 
355
 
 
356
 
 
357
</div>
 
358
 
 
359
</div>
 
360
 
 
361
<div id="outline-container-1_4" class="outline-3">
 
362
<h3 id="sec-1_4"><span class="section-number-3">1.4</span> Usage </h3>
 
363
<div class="outline-text-3" id="text-1_4">
 
364
 
 
365
 
 
366
<p>
 
367
There is a command-line tool that exposes the functionality of this library
 
368
for your shell-scripting needs:
 
369
</p>
 
370
 
 
371
 
 
372
 
 
373
<pre class="src src-sh">uglifyjs [ options... ] [ filename ]
 
374
</pre>
 
375
 
 
376
 
 
377
 
 
378
<p>
 
379
<code>filename</code> should be the last argument and should name the file from which
 
380
to read the JavaScript code.  If you don't specify it, it will read code
 
381
from STDIN.
 
382
</p>
 
383
<p>
 
384
Supported options:
 
385
</p>
 
386
<ul>
 
387
<li>
 
388
<code>-b</code> or <code>--beautify</code> &mdash; output indented code; when passed, additional
 
389
options control the beautifier:
 
390
 
 
391
<ul>
 
392
<li>
 
393
<code>-i N</code> or <code>--indent N</code> &mdash; indentation level (number of spaces)
 
394
 
 
395
</li>
 
396
<li>
 
397
<code>-q</code> or <code>--quote-keys</code> &mdash; quote keys in literal objects (by default,
 
398
only keys that cannot be identifier names will be quotes).
 
399
 
 
400
</li>
 
401
</ul>
 
402
</li>
 
403
<li>
 
404
<code>--ascii</code> &mdash; pass this argument to encode non-ASCII characters as
 
405
<code>\uXXXX</code> sequences.  By default UglifyJS won't bother to do it and will
 
406
output Unicode characters instead.  (the output is always encoded in UTF8,
 
407
but if you pass this option you'll only get ASCII).
 
408
 
 
409
</li>
 
410
<li>
 
411
<code>-nm</code> or <code>--no-mangle</code> &mdash; don't mangle variable names
 
412
 
 
413
</li>
 
414
<li>
 
415
<code>-ns</code> or <code>--no-squeeze</code> &mdash; don't call <code>ast_squeeze()</code> (which does various
 
416
optimizations that result in smaller, less readable code).
 
417
 
 
418
</li>
 
419
<li>
 
420
<code>-mt</code> or <code>--mangle-toplevel</code> &mdash; mangle names in the toplevel scope too
 
421
(by default we don't do this).
 
422
 
 
423
</li>
 
424
<li>
 
425
<code>--no-seqs</code> &mdash; when <code>ast_squeeze()</code> is called (thus, unless you pass
 
426
<code>--no-squeeze</code>) it will reduce consecutive statements in blocks into a
 
427
sequence.  For example, "a = 10; b = 20; foo();" will be written as
 
428
"a=10,b=20,foo();".  In various occasions, this allows us to discard the
 
429
block brackets (since the block becomes a single statement).  This is ON
 
430
by default because it seems safe and saves a few hundred bytes on some
 
431
libs that I tested it on, but pass <code>--no-seqs</code> to disable it.
 
432
 
 
433
</li>
 
434
<li>
 
435
<code>--no-dead-code</code> &mdash; by default, UglifyJS will remove code that is
 
436
obviously unreachable (code that follows a <code>return</code>, <code>throw</code>, <code>break</code> or
 
437
<code>continue</code> statement and is not a function/variable declaration).  Pass
 
438
this option to disable this optimization.
 
439
 
 
440
</li>
 
441
<li>
 
442
<code>-nc</code> or <code>--no-copyright</code> &mdash; by default, <code>uglifyjs</code> will keep the initial
 
443
comment tokens in the generated code (assumed to be copyright information
 
444
etc.).  If you pass this it will discard it.
 
445
 
 
446
</li>
 
447
<li>
 
448
<code>-o filename</code> or <code>--output filename</code> &mdash; put the result in <code>filename</code>.  If
 
449
this isn't given, the result goes to standard output (or see next one).
 
450
 
 
451
</li>
 
452
<li>
 
453
<code>--overwrite</code> &mdash; if the code is read from a file (not from STDIN) and you
 
454
pass <code>--overwrite</code> then the output will be written in the same file.
 
455
 
 
456
</li>
 
457
<li>
 
458
<code>--ast</code> &mdash; pass this if you want to get the Abstract Syntax Tree instead
 
459
of JavaScript as output.  Useful for debugging or learning more about the
 
460
internals.
 
461
 
 
462
</li>
 
463
<li>
 
464
<code>-v</code> or <code>--verbose</code> &mdash; output some notes on STDERR (for now just how long
 
465
each operation takes).
 
466
 
 
467
</li>
 
468
<li>
 
469
<code>--unsafe</code> &mdash; enable other additional optimizations that are known to be
 
470
unsafe in some contrived situations, but could still be generally useful.
 
471
For now only this:
 
472
 
 
473
<ul>
 
474
<li>
 
475
foo.toString()  ==&gt;  foo+""
 
476
 
 
477
</li>
 
478
</ul>
 
479
</li>
 
480
<li>
 
481
<code>--max-line-len</code> (default 32K characters) &mdash; add a newline after around
 
482
32K characters.  I've seen both FF and Chrome croak when all the code was
 
483
on a single line of around 670K.  Pass &ndash;max-line-len 0 to disable this
 
484
safety feature.
 
485
 
 
486
</li>
 
487
<li>
 
488
<code>--reserved-names</code> &mdash; some libraries rely on certain names to be used, as
 
489
pointed out in issue #92 and #81, so this option allow you to exclude such
 
490
names from the mangler.  For example, to keep names <code>require</code> and <code>$super</code>
 
491
intact you'd specify &ndash;reserved-names "require,$super".
 
492
 
 
493
</li>
 
494
<li>
 
495
<code>--inline-script</code> &ndash; when you want to include the output literally in an
 
496
HTML <code>&lt;script&gt;</code> tag you can use this option to prevent <code>&lt;/script</code> from
 
497
showing up in the output.
 
498
 
 
499
</li>
 
500
<li>
 
501
<code>--lift-vars</code> &ndash; when you pass this, UglifyJS will apply the following
 
502
transformations (see the notes in API, <code>ast_lift_variables</code>):
 
503
 
 
504
<ul>
 
505
<li>
 
506
put all <code>var</code> declarations at the start of the scope
 
507
</li>
 
508
<li>
 
509
make sure a variable is declared only once
 
510
</li>
 
511
<li>
 
512
discard unused function arguments
 
513
</li>
 
514
<li>
 
515
discard unused inner (named) functions
 
516
</li>
 
517
<li>
 
518
finally, try to merge assignments into that one <code>var</code> declaration, if
 
519
possible.
 
520
</li>
 
521
</ul>
 
522
</li>
 
523
</ul>
 
524
 
 
525
 
 
526
 
 
527
</div>
 
528
 
 
529
<div id="outline-container-1_4_1" class="outline-4">
 
530
<h4 id="sec-1_4_1"><span class="section-number-4">1.4.1</span> API </h4>
 
531
<div class="outline-text-4" id="text-1_4_1">
 
532
 
 
533
 
 
534
<p>
 
535
To use the library from JavaScript, you'd do the following (example for
 
536
NodeJS):
 
537
</p>
 
538
 
 
539
 
 
540
 
 
541
<pre class="src src-js"><span style="color: #a020f0;">var</span> <span style="color: #b8860b;">jsp</span> = require(<span style="color: #bc8f8f;">"uglify-js"</span>).parser;
 
542
<span style="color: #a020f0;">var</span> <span style="color: #b8860b;">pro</span> = require(<span style="color: #bc8f8f;">"uglify-js"</span>).uglify;
 
543
 
 
544
<span style="color: #a020f0;">var</span> <span style="color: #b8860b;">orig_code</span> = <span style="color: #bc8f8f;">"... JS code here"</span>;
 
545
<span style="color: #a020f0;">var</span> <span style="color: #b8860b;">ast</span> = jsp.parse(orig_code); <span style="color: #b22222;">// </span><span style="color: #b22222;">parse code and get the initial AST
 
546
</span>ast = pro.ast_mangle(ast); <span style="color: #b22222;">// </span><span style="color: #b22222;">get a new AST with mangled names
 
547
</span>ast = pro.ast_squeeze(ast); <span style="color: #b22222;">// </span><span style="color: #b22222;">get an AST with compression optimizations
 
548
</span><span style="color: #a020f0;">var</span> <span style="color: #b8860b;">final_code</span> = pro.gen_code(ast); <span style="color: #b22222;">// </span><span style="color: #b22222;">compressed code here
 
549
</span></pre>
 
550
 
 
551
 
 
552
 
 
553
<p>
 
554
The above performs the full compression that is possible right now.  As you
 
555
can see, there are a sequence of steps which you can apply.  For example if
 
556
you want compressed output but for some reason you don't want to mangle
 
557
variable names, you would simply skip the line that calls
 
558
<code>pro.ast_mangle(ast)</code>.
 
559
</p>
 
560
<p>
 
561
Some of these functions take optional arguments.  Here's a description:
 
562
</p>
 
563
<ul>
 
564
<li>
 
565
<code>jsp.parse(code, strict_semicolons)</code> &ndash; parses JS code and returns an AST.
 
566
<code>strict_semicolons</code> is optional and defaults to <code>false</code>.  If you pass
 
567
<code>true</code> then the parser will throw an error when it expects a semicolon and
 
568
it doesn't find it.  For most JS code you don't want that, but it's useful
 
569
if you want to strictly sanitize your code.
 
570
 
 
571
</li>
 
572
<li>
 
573
<code>pro.ast_lift_variables(ast)</code> &ndash; merge and move <code>var</code> declarations to the
 
574
scop of the scope; discard unused function arguments or variables; discard
 
575
unused (named) inner functions.  It also tries to merge assignments
 
576
following the <code>var</code> declaration into it.
 
577
 
 
578
<p>
 
579
If your code is very hand-optimized concerning <code>var</code> declarations, this
 
580
lifting variable declarations might actually increase size.  For me it
 
581
helps out.  On jQuery it adds 865 bytes (243 after gzip).  YMMV.  Also
 
582
note that (since it's not enabled by default) this operation isn't yet
 
583
heavily tested (please report if you find issues!).
 
584
</p>
 
585
<p>
 
586
Note that although it might increase the image size (on jQuery it gains
 
587
865 bytes, 243 after gzip) it's technically more correct: in certain
 
588
situations, dead code removal might drop variable declarations, which
 
589
would not happen if the variables are lifted in advance.
 
590
</p>
 
591
<p>
 
592
Here's an example of what it does:
 
593
</p>
 
594
</li>
 
595
</ul>
 
596
 
 
597
 
 
598
 
 
599
 
 
600
<pre class="src src-js"><span style="color: #a020f0;">function</span> <span style="color: #0000ff;">f</span>(<span style="color: #b8860b;">a</span>, <span style="color: #b8860b;">b</span>, <span style="color: #b8860b;">c</span>, <span style="color: #b8860b;">d</span>, <span style="color: #b8860b;">e</span>) {
 
601
    <span style="color: #a020f0;">var</span> <span style="color: #b8860b;">q</span>;
 
602
    <span style="color: #a020f0;">var</span> <span style="color: #b8860b;">w</span>;
 
603
    w = 10;
 
604
    q = 20;
 
605
    <span style="color: #a020f0;">for</span> (<span style="color: #a020f0;">var</span> <span style="color: #b8860b;">i</span> = 1; i &lt; 10; ++i) {
 
606
        <span style="color: #a020f0;">var</span> <span style="color: #b8860b;">boo</span> = foo(a);
 
607
    }
 
608
    <span style="color: #a020f0;">for</span> (<span style="color: #a020f0;">var</span> <span style="color: #b8860b;">i</span> = 0; i &lt; 1; ++i) {
 
609
        <span style="color: #a020f0;">var</span> <span style="color: #b8860b;">boo</span> = bar(c);
 
610
    }
 
611
    <span style="color: #a020f0;">function</span> <span style="color: #0000ff;">foo</span>(){ ... }
 
612
    <span style="color: #a020f0;">function</span> <span style="color: #0000ff;">bar</span>(){ ... }
 
613
    <span style="color: #a020f0;">function</span> <span style="color: #0000ff;">baz</span>(){ ... }
 
614
}
 
615
 
 
616
<span style="color: #b22222;">// </span><span style="color: #b22222;">transforms into ==&gt;
 
617
</span>
 
618
<span style="color: #a020f0;">function</span> <span style="color: #0000ff;">f</span>(<span style="color: #b8860b;">a</span>, <span style="color: #b8860b;">b</span>, <span style="color: #b8860b;">c</span>) {
 
619
    <span style="color: #a020f0;">var</span> <span style="color: #b8860b;">i</span>, <span style="color: #b8860b;">boo</span>, <span style="color: #b8860b;">w</span> = 10, <span style="color: #b8860b;">q</span> = 20;
 
620
    <span style="color: #a020f0;">for</span> (i = 1; i &lt; 10; ++i) {
 
621
        boo = foo(a);
 
622
    }
 
623
    <span style="color: #a020f0;">for</span> (i = 0; i &lt; 1; ++i) {
 
624
        boo = bar(c);
 
625
    }
 
626
    <span style="color: #a020f0;">function</span> <span style="color: #0000ff;">foo</span>() { ... }
 
627
    <span style="color: #a020f0;">function</span> <span style="color: #0000ff;">bar</span>() { ... }
 
628
}
 
629
</pre>
 
630
 
 
631
 
 
632
 
 
633
<ul>
 
634
<li>
 
635
<code>pro.ast_mangle(ast, options)</code> &ndash; generates a new AST containing mangled
 
636
(compressed) variable and function names.  It supports the following
 
637
options:
 
638
 
 
639
<ul>
 
640
<li>
 
641
<code>toplevel</code> &ndash; mangle toplevel names (by default we don't touch them).
 
642
</li>
 
643
<li>
 
644
<code>except</code> &ndash; an array of names to exclude from compression.
 
645
 
 
646
</li>
 
647
</ul>
 
648
</li>
 
649
<li>
 
650
<code>pro.ast_squeeze(ast, options)</code> &ndash; employs further optimizations designed
 
651
to reduce the size of the code that <code>gen_code</code> would generate from the
 
652
AST.  Returns a new AST.  <code>options</code> can be a hash; the supported options
 
653
are:
 
654
 
 
655
<ul>
 
656
<li>
 
657
<code>make_seqs</code> (default true) which will cause consecutive statements in a
 
658
block to be merged using the "sequence" (comma) operator
 
659
 
 
660
</li>
 
661
<li>
 
662
<code>dead_code</code> (default true) which will remove unreachable code.
 
663
 
 
664
</li>
 
665
</ul>
 
666
</li>
 
667
<li>
 
668
<code>pro.gen_code(ast, options)</code> &ndash; generates JS code from the AST.  By
 
669
default it's minified, but using the <code>options</code> argument you can get nicely
 
670
formatted output.  <code>options</code> is, well, optional :-) and if you pass it it
 
671
must be an object and supports the following properties (below you can see
 
672
the default values):
 
673
 
 
674
<ul>
 
675
<li>
 
676
<code>beautify: false</code> &ndash; pass <code>true</code> if you want indented output
 
677
</li>
 
678
<li>
 
679
<code>indent_start: 0</code> (only applies when <code>beautify</code> is <code>true</code>) &ndash; initial
 
680
indentation in spaces
 
681
</li>
 
682
<li>
 
683
<code>indent_level: 4</code> (only applies when <code>beautify</code> is <code>true</code>) --
 
684
indentation level, in spaces (pass an even number)
 
685
</li>
 
686
<li>
 
687
<code>quote_keys: false</code> &ndash; if you pass <code>true</code> it will quote all keys in
 
688
literal objects
 
689
</li>
 
690
<li>
 
691
<code>space_colon: false</code> (only applies when <code>beautify</code> is <code>true</code>) &ndash; wether
 
692
to put a space before the colon in object literals
 
693
</li>
 
694
<li>
 
695
<code>ascii_only: false</code> &ndash; pass <code>true</code> if you want to encode non-ASCII
 
696
characters as <code>\uXXXX</code>.
 
697
</li>
 
698
<li>
 
699
<code>inline_script: false</code> &ndash; pass <code>true</code> to escape occurrences of
 
700
<code>&lt;/script</code> in strings
 
701
</li>
 
702
</ul>
 
703
</li>
 
704
</ul>
 
705
 
 
706
 
 
707
</div>
 
708
 
 
709
</div>
 
710
 
 
711
<div id="outline-container-1_4_2" class="outline-4">
 
712
<h4 id="sec-1_4_2"><span class="section-number-4">1.4.2</span> Beautifier shortcoming &ndash; no more comments </h4>
 
713
<div class="outline-text-4" id="text-1_4_2">
 
714
 
 
715
 
 
716
<p>
 
717
The beautifier can be used as a general purpose indentation tool.  It's
 
718
useful when you want to make a minified file readable.  One limitation,
 
719
though, is that it discards all comments, so you don't really want to use it
 
720
to reformat your code, unless you don't have, or don't care about, comments.
 
721
</p>
 
722
<p>
 
723
In fact it's not the beautifier who discards comments &mdash; they are dumped at
 
724
the parsing stage, when we build the initial AST.  Comments don't really
 
725
make sense in the AST, and while we could add nodes for them, it would be
 
726
inconvenient because we'd have to add special rules to ignore them at all
 
727
the processing stages.
 
728
</p>
 
729
</div>
 
730
</div>
 
731
 
 
732
</div>
 
733
 
 
734
<div id="outline-container-1_5" class="outline-3">
 
735
<h3 id="sec-1_5"><span class="section-number-3">1.5</span> Compression &ndash; how good is it? </h3>
 
736
<div class="outline-text-3" id="text-1_5">
 
737
 
 
738
 
 
739
<p>
 
740
Here are updated statistics.  (I also updated my Google Closure and YUI
 
741
installations).
 
742
</p>
 
743
<p>
 
744
We're still a lot better than YUI in terms of compression, though slightly
 
745
slower.  We're still a lot faster than Closure, and compression after gzip
 
746
is comparable.
 
747
</p>
 
748
<table border="2" cellspacing="0" cellpadding="6" rules="groups" frame="hsides">
 
749
<caption></caption>
 
750
<colgroup><col align="left" /><col align="left" /><col align="right" /><col align="left" /><col align="right" /><col align="left" /><col align="right" />
 
751
</colgroup>
 
752
<thead>
 
753
<tr><th scope="col">File</th><th scope="col">UglifyJS</th><th scope="col">UglifyJS+gzip</th><th scope="col">Closure</th><th scope="col">Closure+gzip</th><th scope="col">YUI</th><th scope="col">YUI+gzip</th></tr>
 
754
</thead>
 
755
<tbody>
 
756
<tr><td>jquery-1.6.2.js</td><td>91001 (0:01.59)</td><td>31896</td><td>90678 (0:07.40)</td><td>31979</td><td>101527 (0:01.82)</td><td>34646</td></tr>
 
757
<tr><td>paper.js</td><td>142023 (0:01.65)</td><td>43334</td><td>134301 (0:07.42)</td><td>42495</td><td>173383 (0:01.58)</td><td>48785</td></tr>
 
758
<tr><td>prototype.js</td><td>88544 (0:01.09)</td><td>26680</td><td>86955 (0:06.97)</td><td>26326</td><td>92130 (0:00.79)</td><td>28624</td></tr>
 
759
<tr><td>thelib-full.js (DynarchLIB)</td><td>251939 (0:02.55)</td><td>72535</td><td>249911 (0:09.05)</td><td>72696</td><td>258869 (0:01.94)</td><td>76584</td></tr>
 
760
</tbody>
 
761
</table>
 
762
 
 
763
 
 
764
</div>
 
765
 
 
766
</div>
 
767
 
 
768
<div id="outline-container-1_6" class="outline-3">
 
769
<h3 id="sec-1_6"><span class="section-number-3">1.6</span> Bugs? </h3>
 
770
<div class="outline-text-3" id="text-1_6">
 
771
 
 
772
 
 
773
<p>
 
774
Unfortunately, for the time being there is no automated test suite.  But I
 
775
ran the compressor manually on non-trivial code, and then I tested that the
 
776
generated code works as expected.  A few hundred times.
 
777
</p>
 
778
<p>
 
779
DynarchLIB was started in times when there was no good JS minifier.
 
780
Therefore I was quite religious about trying to write short code manually,
 
781
and as such DL contains a lot of syntactic hacks<sup><a class="footref" name="fnr.1" href="#fn.1">1</a></sup> such as “foo == bar ?  a
 
782
= 10 : b = 20”, though the more readable version would clearly be to use
 
783
“if/else”.
 
784
</p>
 
785
<p>
 
786
Since the parser/compressor runs fine on DL and jQuery, I'm quite confident
 
787
that it's solid enough for production use.  If you can identify any bugs,
 
788
I'd love to hear about them (<a href="http://groups.google.com/group/uglifyjs">use the Google Group</a> or email me directly).
 
789
</p>
 
790
</div>
 
791
 
 
792
</div>
 
793
 
 
794
<div id="outline-container-1_7" class="outline-3">
 
795
<h3 id="sec-1_7"><span class="section-number-3">1.7</span> Links </h3>
 
796
<div class="outline-text-3" id="text-1_7">
 
797
 
 
798
 
 
799
<ul>
 
800
<li>
 
801
Twitter: <a href="http://twitter.com/UglifyJS">@UglifyJS</a>
 
802
</li>
 
803
<li>
 
804
Project at GitHub: <a href="http://github.com/mishoo/UglifyJS">http://github.com/mishoo/UglifyJS</a>
 
805
</li>
 
806
<li>
 
807
Google Group: <a href="http://groups.google.com/group/uglifyjs">http://groups.google.com/group/uglifyjs</a>
 
808
</li>
 
809
<li>
 
810
Common Lisp JS parser: <a href="http://marijn.haverbeke.nl/parse-js/">http://marijn.haverbeke.nl/parse-js/</a>
 
811
</li>
 
812
<li>
 
813
JS-to-Lisp compiler: <a href="http://github.com/marijnh/js">http://github.com/marijnh/js</a>
 
814
</li>
 
815
<li>
 
816
Common Lisp JS uglifier: <a href="http://github.com/mishoo/cl-uglify-js">http://github.com/mishoo/cl-uglify-js</a>
 
817
</li>
 
818
</ul>
 
819
 
 
820
 
 
821
</div>
 
822
 
 
823
</div>
 
824
 
 
825
<div id="outline-container-1_8" class="outline-3">
 
826
<h3 id="sec-1_8"><span class="section-number-3">1.8</span> License </h3>
 
827
<div class="outline-text-3" id="text-1_8">
 
828
 
 
829
 
 
830
<p>
 
831
UglifyJS is released under the BSD license:
 
832
</p>
 
833
 
 
834
 
 
835
 
 
836
<pre class="example">Copyright 2010 (c) Mihai Bazon &lt;mihai.bazon@gmail.com&gt;
 
837
Based on parse-js (http://marijn.haverbeke.nl/parse-js/).
 
838
 
 
839
Redistribution and use in source and binary forms, with or without
 
840
modification, are permitted provided that the following conditions
 
841
are met:
 
842
 
 
843
    * Redistributions of source code must retain the above
 
844
      copyright notice, this list of conditions and the following
 
845
      disclaimer.
 
846
 
 
847
    * Redistributions in binary form must reproduce the above
 
848
      copyright notice, this list of conditions and the following
 
849
      disclaimer in the documentation and/or other materials
 
850
      provided with the distribution.
 
851
 
 
852
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY
 
853
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 
854
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 
855
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
 
856
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
 
857
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 
858
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 
859
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 
860
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
 
861
TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
 
862
THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 
863
SUCH DAMAGE.
 
864
</pre>
 
865
 
 
866
 
 
867
 
 
868
 
 
869
</div>
 
870
</div>
 
871
</div>
 
872
<div id="footnotes">
 
873
<h2 class="footnotes">Footnotes: </h2>
 
874
<div id="text-footnotes">
 
875
<p class="footnote"><sup><a class="footnum" name="fn.1" href="#fnr.1">1</a></sup> I even reported a few bugs and suggested some fixes in the original
 
876
<a href="http://marijn.haverbeke.nl/parse-js/">parse-js</a> library, and Marijn pushed fixes literally in minutes.
 
877
</p>
 
878
</div>
 
879
</div>
 
880
<div id="postamble">
 
881
<p class="author"> Author: Mihai Bazon
 
882
</p>
 
883
<p class="date"> Date: 2011-08-20 10:08:28 EEST</p>
 
884
<p class="creator">HTML generated by org-mode 7.01trans in emacs 23</p>
 
885
</div>
 
886
</div>
 
887
</body>
 
888
</html>