Clone wiki

YAYUI Compressor / Home

YAYUI Compressor (Yet Another YUI Compressor)

What this appliation does:

  • Take your source code,removes the whitespaces and shorten the variables names
  • Delivers the minified/compressed source code (which theoretically should be fine :-)

How it works:

  • I use no external library/engine/parser (eg. Rhino) whatsoever; everything is done with the aid of plain regular expressions (aka Regex)
    • there are 7 different regex's for trimming the whitespaces (see Minify options)
    • there are few different regex's that together work in cascade helping to capture and replace the functions arguments/variables with shorten names, a-z (see Obfuscate options)

Caveats:

  • This application is experimental. I made it just for fun so use it in production but with care!
  • Normally a minifier/obfuscator should be done with the aid of a parser and not rely only on few regex patterns. Although I tested it against few hundred KB JavaScript source code I cannot guarantee that I've implemented all the possible patterns.
  • By checking all possible options (minify/obfuscate) your code will still work but will not be validated by some code quality tools (eg. JSLint)
  • There is still room for optimization. Perhaps some patterns can be writen even shorter.

Patterns that it uses and the algorithm description:

  • for minification:

    1. remove JavaScript hints : /['"]use\s+strict['"]\s*;/ (see the complete hint list)
    2. remove dispensable semicolons : replace /;[\s|\n]*;/m with ;
    3. remove single line comments : replace /(?<![\'"])\/\/.*/m with '<empty-string>'
    4. remove block comments : replace /\/*([^\/]|[\w\d\s]\/[\w\d\s])**\//m with '<empty-string>'
    5. match these blocks /\b(if|else|while)\b.[^;{]({)([^{}]+)(})/m then:
      • replace the curly braces /[{}]/ with '<blank>' if the code block doesn't match:
        • 2+ /;/ OR 1+ /:/ OR 1+ /\b(function|try|catch)\b/
    6. remove the whitespaces /\s([^\w\d\s])\s|[ ]{2,}/' with '$1'
    7. remove the CR/LF:
      • first replace /(?<=[\W])\n|[ ]{2,}/m with '$1'
      • second replace /\n/m with '<blank>'
  • for obfuscation:

    1. first backup all strings (we don't want to change them) : /([\'"])(\\\1|.)*?\1/m
    2. capture all functions: /\bfunction\b(([\n]|.)?)(?=[^(]\bfunction\b\s[\w\d]+?)/m then for each:
      • capture the function declaration: /\bfunction\b(.*?){/m and split the arguments by comma
      • for each argument (eg. myVar):
        • take the left part /[^\w\d]/ and then replace all its occurences with your obfuscated variable name: replace /([^\w\d\'".])(\bmyVar\b)([^\w\d\'"])/ with '$1myNewVar$3'
      • capture the function inner block codes: /{[^{}]*}/m then:
        • capture the var declaration: /\bvar\b[^;]+/m , split variables by comma and replace /([\s([{+-*\/\|<>;&%!,])(\bmyVar\b)([\s)]}+-*\/\|<>;&!%,.=]?)/ with '$1myNewVar$3'
    3. restore the original strings; there is no risk in changing them now

FAQ

  • Does it work for other languages, such as CSS, PHP, Java, C++, etc? + The minification might work but the obfuscation is not compatible yet
  • Can I get the source code? In what language is it written? + the source code has been made available at its bitbucket.org respository + it is written in PHP and encapsuled in a standalone class

Updated