- Notifications
You must be signed in to change notification settings - Fork91
SlimIt - a JavaScript minifier/parser in Python
License
rspivak/slimit
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Repository files navigation
_____ _ _____ __ __ _____ _______ / ____| | |_ _| \/ |_ _|__ __|| (___ | | | | | \ / | | | | | \___ \| | | | | |\/| | | | | | ____) | |____ _| |_| | | |_| |_ | ||_____/|______|_____|_| |_|_____| |_|
SlimIt is a JavaScript minifier written in Python.It compiles JavaScript into more compact code so that it downloadsand runs faster.
SlimIt also provides a library that includes a JavaScript parser,lexer, pretty printer and a tree visitor.
https://slimit.readthedocs.io/
$ [sudo] pip install slimit
Or the bleeding edge version from the git master branch:
$ [sudo] pip install git+https://github.com/rspivak/slimit.git#egg=slimit
There is also an official DEB package available athttp://packages.debian.org/sid/slimit
From the command line:
$ slimit -hUsage: slimit [options] [input file]If no input file is provided STDIN is used by default.Minified JavaScript code is printed to STDOUT.Options: -h, --help show this help message and exit -m, --mangle mangle names -t, --mangle-toplevel mangle top level scope (defaults to False)$ cat test.jsvar foo = function( obj ) { for ( var name in obj ) { return false; } return true;};$$ slimit --mangle < test.jsvar foo=function(a){for(var b in a)return false;return true;};
Or using library API:
>>>from slimitimport minify>>> text="""... var foo= function( obj ) {...for ( var namein obj ) {...return false;... }...return true;... };...""">>>print minify(text,mangle=True,mangle_toplevel=True)var a=function(a){for(var b in a)return false;return true;};
>>>from slimit.parserimport Parser>>>from slimit.visitorsimport nodevisitor>>>from slimitimport ast>>>>>> parser= Parser()>>> tree= parser.parse('for(var i=0; i<10; i++) {var x=5+i;}')>>>for nodein nodevisitor.visit(tree):...ifisinstance(node, ast.Identifier)and node.value=='i':... node.value='hello'...>>>print tree.to_ecma()# print awesome javascript :)for (var hello = 0; hello < 10; hello++) { var x = 5 + hello;}>>>
>>>from slimit.parserimport Parser>>>from slimit.visitors.nodevisitorimport ASTVisitor>>>>>> text="""... var x= {..."key1":"value1",..."key2":"value2"... };...""">>>>>>classMyVisitor(ASTVisitor):...defvisit_Object(self,node):..."""Visit object literal."""...for propin node:... left, right= prop.left, prop.right...print'Property key=%s, value=%s'% (left.value, right.value)...# visit all children in turn...self.visit(prop)...>>>>>> parser= Parser()>>> tree= parser.parse(text)>>> visitor= MyVisitor()>>> visitor.visit(tree)Property key="key1", value="value1"Property key="key2", value="value2"
>>>from slimit.lexerimport Lexer>>> lexer= Lexer()>>> lexer.input('a = 1;')>>>for tokenin lexer:...print token...LexToken(ID,'a',1,0)LexToken(EQ,'=',1,2)LexToken(NUMBER,'1',1,4)LexToken(SEMI,';',1,5)
You can get one token at a time usingtoken
method:
>>> lexer.input('a = 1;')>>>whileTrue:... token= lexer.token()...ifnot token:...break...print token...LexToken(ID,'a',1,0)LexToken(EQ,'=',1,2)LexToken(NUMBER,'1',1,4)LexToken(SEMI,';',1,5)
LexToken instance has different attributes:
>>> lexer.input('a = 1;')>>> token= lexer.token()>>> token.type, token.value, token.lineno, token.lexpos('ID', 'a', 1, 0)
SAM - JQuery size after minification in bytes (the smaller number the better)
Original jQuery 1.6.1 (bytes) | SlimIt SAM | rJSmin SAM | jsmin SAM |
---|---|---|---|
234,995 | 94,290 | 134,215 | 134,819 |
- when doing name mangling handle cases with 'eval' and 'with'
- foo["bar"] ==> foo.bar
- consecutive declarations: var a = 10; var b = 20; ==> var a=10,b=20;
- reduce simple constant expressions if the result takes less space:1 +2 * 3 ==> 7
- IF statement optimizations
- if (foo) bar(); else baz(); ==> foo?bar():baz();
- if (!foo) bar(); else baz(); ==> foo?baz():bar();
- if (foo) bar(); ==> foo&&bar();
- if (!foo) bar(); ==> foo||bar();
- if (foo) return bar(); else return baz(); ==> return foo?bar():baz();
- if (foo) return bar(); else something(); ==> {if(foo)return bar();something()}
- remove unreachable code that follows a return, throw, break orcontinue statement, except function/variable declarations
- parsing speed improvements
- The lexer and parser are built withPLY
- Several test cases and regexes fromjslex
- Some visitor ideas -pycparser
- Many grammar rules are taken fromrkelly
- Name mangling and different optimization ideas -UglifyJS
- ASI implementation was inspired bypyjsparser
The MIT License (MIT)
About
SlimIt - a JavaScript minifier/parser in Python
Resources
License
Uh oh!
There was an error while loading.Please reload this page.