~ubuntu-branches/ubuntu/utopic/slimit/utopic

« back to all changes in this revision

Viewing changes to README.rst

  • Committer: Package Import Robot
  • Author(s): TANIGUCHI Takaki
  • Date: 2012-04-09 00:21:58 UTC
  • Revision ID: package-import@ubuntu.com-20120409002158-9i3uaczeuvrj32wg
Tags: upstream-0.6.2
ImportĀ upstreamĀ versionĀ 0.6.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
::
 
2
 
 
3
      _____ _      _____ __  __ _____ _______
 
4
     / ____| |    |_   _|  \/  |_   _|__   __|
 
5
    | (___ | |      | | | \  / | | |    | |
 
6
     \___ \| |      | | | |\/| | | |    | |
 
7
     ____) | |____ _| |_| |  | |_| |_   | |
 
8
    |_____/|______|_____|_|  |_|_____|  |_|
 
9
 
 
10
 
 
11
Welcome to SlimIt
 
12
==================================
 
13
 
 
14
`SlimIt` is a JavaScript minifier written in Python.
 
15
It compiles JavaScript into more compact code so that it downloads
 
16
and runs faster.
 
17
 
 
18
`SlimIt` also provides a library that includes a JavaScript parser,
 
19
lexer, pretty printer and a tree visitor.
 
20
 
 
21
`http://slimit.readthedocs.org/ <http://slimit.readthedocs.org/>`_
 
22
 
 
23
Installation
 
24
------------
 
25
 
 
26
::
 
27
 
 
28
    $ [sudo] pip install slimit
 
29
 
 
30
Or the bleeding edge version from the git master branch:
 
31
 
 
32
::
 
33
 
 
34
    $ [sudo] pip install git+https://github.com/rspivak/slimit.git#egg=slimit
 
35
 
 
36
 
 
37
Let's minify some code
 
38
----------------------
 
39
 
 
40
From the command line:
 
41
 
 
42
::
 
43
 
 
44
    $ slimit -h
 
45
    Usage: slimit [options] [input file]
 
46
 
 
47
    If no input file is provided STDIN is used by default.
 
48
    Minified JavaScript code is printed to STDOUT.
 
49
 
 
50
    Options:
 
51
      -h, --help            show this help message and exit
 
52
      -m, --mangle          mangle names
 
53
      -t, --mangle-toplevel
 
54
                            mangle top level scope (defaults to False)
 
55
 
 
56
    $ cat test.js
 
57
    var foo = function( obj ) {
 
58
            for ( var name in obj ) {
 
59
                    return false;
 
60
            }
 
61
            return true;
 
62
    };
 
63
    $
 
64
    $ slimit --mangle < test.js
 
65
    var foo=function(a){for(var b in a)return false;return true;};
 
66
 
 
67
Or using library API:
 
68
 
 
69
>>> from slimit import minify
 
70
>>> text = """
 
71
... var foo = function( obj ) {
 
72
...         for ( var name in obj ) {
 
73
...                 return false;
 
74
...         }
 
75
...         return true;
 
76
... };
 
77
... """
 
78
>>> print minify(text, mangle=True, mangle_toplevel=True)
 
79
var a=function(a){for(var b in a)return false;return true;};
 
80
 
 
81
 
 
82
Iterate over, modify a JavaScript AST and pretty print it
 
83
---------------------------------------------------------
 
84
 
 
85
>>> from slimit.parser import Parser
 
86
>>> from slimit.visitors import nodevisitor
 
87
>>> from slimit import ast
 
88
>>>
 
89
>>> parser = Parser()
 
90
>>> tree = parser.parse('for(var i=0; i<10; i++) {var x=5+i;}')
 
91
>>> for node in nodevisitor.visit(tree):
 
92
...     if isinstance(node, ast.Identifier) and node.value == 'i':
 
93
...         node.value = 'hello'
 
94
...
 
95
>>> print tree.to_ecma() # print awesome javascript :)
 
96
for (var hello = 0; hello < 10; hello++) {
 
97
  var x = 5 + hello;
 
98
}
 
99
>>>
 
100
 
 
101
Writing custom node visitor
 
102
---------------------------
 
103
 
 
104
>>> from slimit.parser import Parser
 
105
>>> from slimit.visitors.nodevisitor import ASTVisitor
 
106
>>>
 
107
>>> text = """
 
108
... var x = {
 
109
...     "key1": "value1",
 
110
...     "key2": "value2"
 
111
... };
 
112
... """
 
113
>>>
 
114
>>> class MyVisitor(ASTVisitor):
 
115
...     def visit_Object(self, node):
 
116
...         """Visit object literal."""
 
117
...         for prop in node:
 
118
...             left, right = prop.left, prop.right
 
119
...             print 'Property key=%s, value=%s' % (left.value, right.value)
 
120
...             # visit all children in turn
 
121
...             self.visit(prop)
 
122
...
 
123
>>>
 
124
>>> parser = Parser()
 
125
>>> tree = parser.parse(text)
 
126
>>> visitor = MyVisitor()
 
127
>>> visitor.visit(tree)
 
128
Property key="key1", value="value1"
 
129
Property key="key2", value="value2"
 
130
 
 
131
Using lexer in your project
 
132
---------------------------
 
133
 
 
134
>>> from slimit.lexer import Lexer
 
135
>>> lexer = Lexer()
 
136
>>> lexer.input('a = 1;')
 
137
>>> for token in lexer:
 
138
...     print token
 
139
...
 
140
LexToken(ID,'a',1,0)
 
141
LexToken(EQ,'=',1,2)
 
142
LexToken(NUMBER,'1',1,4)
 
143
LexToken(SEMI,';',1,5)
 
144
 
 
145
You can get one token at a time using ``token`` method:
 
146
 
 
147
>>> lexer.input('a = 1;')
 
148
>>> while True:
 
149
...     token = lexer.token()
 
150
...     if not token:
 
151
...         break
 
152
...     print token
 
153
...
 
154
LexToken(ID,'a',1,0)
 
155
LexToken(EQ,'=',1,2)
 
156
LexToken(NUMBER,'1',1,4)
 
157
LexToken(SEMI,';',1,5)
 
158
 
 
159
`LexToken` instance has different attributes:
 
160
 
 
161
>>> lexer.input('a = 1;')
 
162
>>> token = lexer.token()
 
163
>>> token.type, token.value, token.lineno, token.lexpos
 
164
('ID', 'a', 1, 0)
 
165
 
 
166
Benchmarks
 
167
----------
 
168
 
 
169
**SAM** - JQuery size after minification in bytes (the smaller number the better)
 
170
 
 
171
+-------------------------------+------------+------------+------------+
 
172
| Original jQuery 1.6.1 (bytes) | SlimIt SAM | rJSmin SAM | jsmin SAM  |
 
173
+===============================+============+============+============+
 
174
| 234,995                       | 94,290     | 134,215    | 134,819    |
 
175
+-------------------------------+------------+------------+------------+
 
176
 
 
177
Roadmap
 
178
-------
 
179
- when doing name mangling handle cases with 'eval' and 'with'
 
180
- foo["bar"] ==> foo.bar
 
181
- consecutive declarations: var a = 10; var b = 20; ==> var a=10,b=20;
 
182
- reduce simple constant expressions if the result takes less space:
 
183
  1 +2 * 3 ==> 7
 
184
- IF statement optimizations
 
185
 
 
186
  1. if (foo) bar(); else baz(); ==> foo?bar():baz();
 
187
  2. if (!foo) bar(); else baz(); ==> foo?baz():bar();
 
188
  3. if (foo) bar(); ==> foo&&bar();
 
189
  4. if (!foo) bar(); ==> foo||bar();
 
190
  5. if (foo) return bar(); else return baz(); ==> return foo?bar():baz();
 
191
  6. if (foo) return bar(); else something(); ==> {if(foo)return bar();something()}
 
192
 
 
193
- remove unreachable code that follows a return, throw, break or
 
194
  continue statement, except function/variable declarations
 
195
- parsing speed improvements
 
196
 
 
197
Acknowledgments
 
198
---------------
 
199
- The lexer and parser are built with `PLY <http://www.dabeaz.com/ply/>`_
 
200
- Several test cases and regexes from `jslex <https://bitbucket.org/ned/jslex>`_
 
201
- Some visitor ideas - `pycparser <http://code.google.com/p/pycparser/>`_
 
202
- Many grammar rules are taken from `rkelly <https://github.com/tenderlove/rkelly>`_
 
203
- Name mangling and different optimization ideas - `UglifyJS <https://github.com/mishoo/UglifyJS>`_
 
204
- ASI implementation was inspired by `pyjsparser <http://bitbucket.org/mvantellingen/pyjsparser>`_
 
205
 
 
206
License
 
207
-------
 
208
The MIT License (MIT)
 
 
b'\\ No newline at end of file'