Any advanced tool to compress a JS file? - javascript

I'm looking for a tool to compress my JS files.
What I want is not just simply remove unneccessary characters;
I prefer to tool to be able to reduce the lengths of
local variables in functions also.
Even better I the tool can reduce the lengths of all other
stuff like global variables, function names, etc. This is to protect the code from being used by web viewers without our consent.
For example, the tool should rename a variable or function name from "some_variable", "some_function" to "sv", "sf", etc. And then refactoring all related references.
I've tried to dig the net but couldn't find something similar.

I think that this one can help you : http://www.minifyjavascript.com/
I've used it in the past and it does a good job!

The Google Closure Compiler does this. It has various settings, but even the "simple optimizations" setting will shorten variable names and (in cases where it knows the function will never be called outside the script) function names. It will even inline functions when there's a savings to be had.
For example, given this script:
jQuery(function($) {
var allDivsOnThePage = $("div"),
someParagraphsAsWell = $("p");
setColor(allDivsOnThePage, "blue");
setColor(someParagraphsAsWell, "green");
function setColor(elms, color) {
return elms.css("color", color);
}
});
Using the closure compiler with simple optimizations (and telling it we're using jQuery) yields:
jQuery(function(a){var b=a("div"),a=a("p");b.css("color","blue");a.css("color","green")});
Note how it's not only shortened the identifiers, but reused one where it detected it could (in this case that didn't save us anything, but in some other cases it could), and inlined the setColor function since that resulted in a savings.

Try YUI Compressor:
http://developer.yahoo.com/yui/compressor/
For me it seems to be one of the most powerful at the moment.

Related

How do I write JavaScript which is compression-friendly?

I want to minimize the size of the Javascript code I have to send over the wire for my personal website. Are there any tricks to writing code that will compress better? I'm thinking about both min-ification and gzip.
Do I need to use short variable names? Or can min-ification just find all instances of those and shorten them? Or is it fine because gzip will detect them and compress over the wire? For functions, is it better to pass in an object with properties? Or just have individual parameters for each value needed? (I can imagine that parameters would be safe for min-ification to shorten because they are always local to the function)
I have a cursory understanding of what these tools do, but it's not enough to be confident in how I should write my Javascript to compress as small as possible.
If you are using a minification tool, you don't need to use short names for your variables, the minifier will take care of that.
As for function arguments, from a minification point of view, it's better to use individual parameters instead of object properties, because the minifier can't rename object properties, but will rename the parameters.
I don't feel qualified to advise you on how to write more compressable code from a Gzip point of view, but I can give you some advice on writing more minifiable Javascript code.
My first advice is that you run your favorite minifier on your code and then compare the pretty printed version of it, with the original code. That way you will learn what kind of changes your minifier makes on your code.
Usually, minifiers rename variables an function names to shorter ones, but can't rename object properties.
So avoid this:
foo.bar.baz.A = 1;
foo.bar.baz.B = 2;
foo.bar.baz.C = 3;
And instead, do this:
var shortcut = foo.bar.baz;
shortcut.d = 1;
shortcut.e = 2;
shortcut.f = 3;
A minifier will rename shortcut to a one or two letters variable.
Another good practice is using method chaining as much as possible (specially if you are using JQuery)
For example, avoid this:
$div.css('background', 'blue'); // set BG
$div.height(100); // set height
$div.fadeIn(200); // show element
And do this instead:
$('#my-div')
.css('background', 'blue')
.height(100)
.fadeIn(200);
You should use both minification and gzipping, see https://css-tricks.com/the-difference-between-minification-and-gzipping/ for some results.
You should also consider using client side caching, as this will eliminate over the wire cost altogether on cache hits.
Also make sure you're not sending any redundant http headers on your response.

Is there a way to tell Google Closure Compiler to *NOT* inline my local functions?

Here's what I'm looking for:
I want to use the wonderful features of SIMPLE mode minification while disabling just one specific feature (disable local function inline).
UPDATE: The answer is NO, it's not possible given my setup. But for me there is a workaround given I am using Grails.
As #Chad has explained below, "This violates core assumptions of the compiler". See my UPDATE3 below for more info.
IN QUESTION FORM:
I'm using CompilationLevel.SIMPLE_OPTIMIZATIONS which does everything I want, except that it's inlining my local functions.
Is there any way around this? For example, is there a setting I can place in my JS files to tell Google Closure not to inline my local functions?
It would be cool to have some directives at the top of my javascript file such as:
// This is a JS comment...
// google.closure.compiler = [inlineLocalFunctions: false]
I'm developing a Grails app and using the Grails asset-pipeline plugin, which uses Google Closure Compiler (hereafter, Compiler). The plugin supports the different minification levels that Compiler supports via the Grails config grails.assets.minifyOptions. This allows for 'SIMPLE', 'ADVANCED', 'WHITESPACE_ONLY'.
AssetCompiler.groovy (asset-pipeline plugin) calls ClosureCompilerProcessor.process()
That eventually assigns SIMPLE_OPTIMIZATIONS on the CompilerOptions object. And by doing so, CompilerOptions.inlineLocalFunctions = true as a byproduct (this is hard coded behavior in Compiler). If I were to use WHITESPACE_ONLY the result would be inlineLocalFunctions=false.
So by using Asset Pipeline's 'SIMPLE' setting, local functions are being inlined and that is causing me trouble. Example: ExtJS ext-all-debug.js which uses lots of local functions.
SO post Is it possible to make Google Closure compiler *not* inline certain functions? provides some help. I can use its window['dontBlowMeAway'] = dontBlowMeAway trick to keep my functions from inlining. However I have LOTS of functions and I'm not about to manually do this for each one; nor would I want to write a script to do it for me. Creating a JS model and trying to identity local functions doesn't sound safe, fun nor fast.
The previous SO post directs the reader to https://developers.google.com/closure/compiler/docs/api-tutorial3#removal, where the window['bla'] trick is explained, and it works.
Wow thanks for reading this long.
Help? :-)
UPDATE1:
Okay. While spending all the effort in writing this question, I may have a trick that could work. Grails uses Groovy. Groovy makes method call interception easy using its MetaClass API.
I'm going to try intercepting the call to:
com.google.javascript.jscomp.Compiler.compile(
List<T1> externs, List<T2> inputs, CompilerOptions options)
My intercepting method will look like:
options.inlineLocalFunctions=false
// Then delegate call to the real compile() method
It's bed time so I'll have to try this later. Even so, it would be nice to solve this without a hack.
UPDATE2:
The response in a similar post (Is it possible to make Google Closure compiler *not* inline certain functions?) doesn't resolve my problem because of the large quantity of functions I need inlined. I've already explained this point.
Take the ExtJS file I cited above as an example of why the above similar SO post doesn't resolve my problem. Look at the raw code for ext-all-debug.js. Find the byAttribute() function. Then keep looking for the string "byAttribute" and you'll see that it is part of strings that are being defined. I am not familiar with this code, but I'm supposing that these string-based values of byAttribute are later being passed to JS's eval() function for execution. Compiler does not alter these values of byAttribute when it's part of a string. Once function byAttribute is inlined, attempts to call the function is no longer possible.
UPDATE3: I attempted two strategies to resolve this problem and both proved unsuccessful. However, I successfully implemented a workaround. My failed attempts:
Use Groovy method interception (Meta Object Protocol, aka MOP) to intercept com.google.javascript.jscomp.Compiler.compile().
Fork the closure-compiler.jar (make my own custom copy) and modify com.google.javascript.jscomp.applySafeCompilationOptions() by setting options.setInlineFunctions(Reach.NONE); instead of LOCAL.
Method interception doesn't work because Compiler.compile() is a Java class which is invoked by a Groovy class marked as #CompileStatic. That means Groovy's MOP is not used when process() calls Google's Compiler.compile(). Even ClosureCompilerProcessor.translateMinifyOptions() (Groovy code) can't be intercepted because the class is #CompileStatic. The only method that can be intercepted is ClosureCompilerProcessor.process().
Forking Google's closure-compiler.jar was my last ugly resort. But just like #Chad said below, simply inserting options.setInlineFunctions(Reach.NONE) in the right place didn't resurrect my inline JS functions names. I tried toggling other options such as setRemoveDeadCode=false to no avail. I realized what Chad said was right. I would end up flipping settings around and probably destroying how the minification works.
My solution: I pre-compressed ext-all-debug.js with UglifyJS and added them to my project. I could have named the files ext-all-debug.min.js to do it more cleanly but I didn't. Below are the settings I placed in my Grails Config.groovy:
grails.assets.minifyOptions = [
optimizationLevel: 'SIMPLE' // WHITESPACE_ONLY, SIMPLE or ADVANCED
]
grails.assets.minifyOptions.excludes = [
'**ext-all-debug.js',
'**ext-theme-neptune.js'
]
Done. Problem solved.
Keywords: minify, minification, uglify, UglifyJS, UglifyJS2
In this case, you would either need to make a custom build of the compiler or use the Java API.
However - disabling inlining is not enough to make this safe. Renaming and dead code elimination will also cause problems. This violates core assumptions of the compiler. This local function is ONLY referenced from within strings.
This code is only safe for the WHITESPACE_ONLY mode of the compiler.
Use the function constructor
var fnc = new Function("param1", "param2", "alert(param1+param2);");
Closure will leave the String literals alone.
See https://developer.mozilla.org/de/docs/Web/JavaScript/Reference/Global_Objects/Function

How to Encode JavaScript files?

How can I encode my JavaScript file like DLL files?
I mean nobody can understand the code like Dll created from CS file in C#.
I need this because I want to give my functions to some company, but I do not want they to understand inside my functions....just can call the functions.
I see the jQuery files are encode to variables (a,b,c,d,....).
for example encode this simple code:
function CookiesEnabled() {
var result = false;
createCookie("testing", "Hello", 1);
if (readCookie("testing") != null) {
result = true;
eraseCookie("testing");
} return result;
};
There really isn't any way to encrypt/encode code like that in JS (at least I do not know of any way), but the standard way is to use good minifiers i.e. programs that collapse your code, remove comments rename local variables from good long names to stuff like width and height to stuff like a and b. And even re-structure your code so its as compact as possible. They usually end up non-human readable.
Minifing is usually even called JS compiling, but its not really. As with is a good one, well not going to go there, there are so many, but for my purposes I've been using the Microsoft official bundler:
http://www.asp.net/mvc/tutorials/mvc-4/bundling-and-minification
You should also check out this question (all of the big names that I know are all there.):
Is there a good JavaScript minifier?

How to allow minimifying of public functions names in Javascript?

I don't know whether there is a solution to this issue, but I have a large set of Javascript functions bearing long descriptive names, something like:
function getTimeFromTimezoneInMilliseconds(...) { ... };
function computeDifferenceFromUTCInMilliseconds(...) { ... };
...
These long names help explaining what the code does, since some operations are complex and not obvious to understand when reading the code only. It helps maintaining the code too.
I am minimifying this Javascript code, but of course, those names are not minimified.
Is there a refactoring trick in Javascript that would allow minimifiers to pick smaller function names and reduce the code size?
You should wrap your code in an IIFE.
This way, you won't have any public members at all, and the minifier will be able to do whatever it wants.
This has the added advantage of not polluting the global scope.
Don't minify yourself! Let the machine do the hard parts.
There are many different options.
You can use an online site where you paste your code and you get the minified back (manual).
You can automate and use a server-side language to minify your JavaScript.
You can use Google CC or Yahoo YUI Compressor to minify and greatly optimize your code.

Big super happy javascript compression

Now, I've heard of javascript compressors, used a bunch and favour a few. However, they all do the same thing. Remove unnecessary space. That's great, they do exactly what it says on the tin. Compresses Javascript. However, looking through some of the major players that provide legendary libraries (such as jQuery), they offer "minified" sources that are entirely unreadable. Notably, the variable names change from someThingLikeThis to c. This is compression that I cannot seem to find anywhere.
My question is, where can I find a Javascript compressor which compresses variables in addition to removing unnecessary space. Or is it done manually?
For example:
// My Javascript:;
var cats = 'Nyan',
dogs = 'Hound';
alert(cats + dogs);
// jQuery styled compression:
var a='Nyan',b='Hound';alert(a+b);
As far as i know http://developer.yahoo.com/yui/compressor/ Does what you need :)
That should be done by a standard minifier. If it is not, then most likely the variable names just cannot be renamed safely (global variables/functions).
Also what you might be looking for is obfuscator. Check this question:
How can I obfuscate (protect) JavaScript?
Google Closure Compiler is the most advanced tool to transpile/minify JavaScript code.
It basically features two compilation levels—simple and advanced. You can use the simple compilation level on pretty much any JS code.
The true magic is in the advanced level which removes unused code, inlines functions, flattens properties (abc.def.ghi -> a) and renames all custom variables. But you have to write the code in a way the compiler can understand.
If you're serious about JS, read the "Closure: The Definitive Guide" by Michael Bolin who is one of the lead developers of the Closure Tools.

Categories

Resources