- 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.
Stars
Watchers
Forks
Packages0
Contributors10
Uh oh!
There was an error while loading.Please reload this page.