Does the GWT Compiler reduce unused JavaScript Code of an external Library? - javascript

With GWT I can use JSNI to include external libraries like JQuery.
If I use an external library with JSNI what does the GWT compiler do?
Does it include the hole full size JavaScript library?
Does it include only the code of the library that have been used?

Assuming you copied the whole jQuery script into a JSNI method (ouch!), then GWT will do its best to optimize it, including pruning dead code. Results would really depend on the JS code though, not everything can be statically analyzed to determine what code will or won't be used.

Related

ClojureScript-Lib and my ClojureScript on same page

Let's assume I have a small web-application and want to use a third-party library that comes with an already compiled version of a ClojureScript.
As a user of that library I have to include that generated Javascript file in my HTML page.
<script src="/javascript/gen/lib.js" type="text/javascript">
So far so good. Everything works fine.
But since my web-application needs some frontend-magic, I wanted to include some ClojureScript of my own. So I wrote a couple of lines, compiled it to Javascript and added another line in the HTML head:
<script src="/javascript/gen/lib.js" type="text/javascript">
<script src="/javascript/gen/my-stuff.js" type="text/javascript">
This is, where it gets ugly. I get this error in the javascript console:
Error: Namespace "goog.debug.Error" already declared.
After googling that error, I get multiple pages, that state, that I can not use multiple Google Closure Compiled things on one page. See SO: Multiple ClojureScript files on same page
So, how do I tackle that situation? On one hand I have an already Google Closure compiled lib and on the other hand my ClojureScript stuff. How do I get one (or two) compiled Javascript files out of this?
Would it be easier, if that third-party lib would provide a non-compiled ClojureScript version?
Yes, it would be easier if the third-party library would provide a non-compiled ClojureScript version. Then you would require it and use it from your code and compile everything together. The ClojureScript compiler with require each dependency once (even the shared dependencies) and the Google Closure compiler would do its optimization pass over all the code.
Try to find the library in Clojars or package it as a jar to consume it from your existing ClojureScript setup. (If the library is open source, give us a link and we'll help you out)

Should I concatenate/minify already minified JS/CSS? If so, how?

Our app has several JS library dependencies which are already minified. We're considering concatenating them into a single file to reduce the volume of separate threads the browser needs to download them all.
The minifiers I've looked at so far don't handle this well (examined Google Closure Compiler, YUI Compressor). I don't really need my already minified libraries minified again. What is the standard practice for this in the JS world? And do I need to worry about specifying order?
Question is similar for CSS. These libraries provide pre-minified CSS, which I'd like to concatenate together.
You typically wouldn't minify code that is already minified. If the provided minified library was minified in a bad way (like packer), it would be better to minify the original library source code using your favorite minifier.
In your case it's better to look at concatenation only.
You can do this using Gulp or Grunt. Both are able to generate sourcemaps.
I have not had any trouble with use strict when concatenating multiple libraries to a single file, but it is something to pay attention to. Properly written libraries apply use strict only to their library scope, to not affect the global scope / other libraries.
If some silly library applies use strict to the global scope, and another silly library is not compatible with strict, Firefox (probably Chrome as well) throw a strict violation error immediately, so this error is easy to spot.

How to distribute a library which uses Closure-library without including any of the actual Closure-library source?

I've recently created a JavaScript library using Google's Closure Compiler: https://github.com/bvaughn/task-runner
I intend for this library to be used by applications that also require the full Closure Library, and so I want the built version of my library (Task Runner) not to include a subset of Closure Library. If Task Runner includes a subset of Closure Library, and another application includes the full Closure Library, a race condition will exist between which loads Closure last (last in wins). It also bloats the size of the Task Runner file.
However I'm having trouble. If I don't require any of the Closure library classes, Task Runner builds fine (obviously). However if I require something (goog.dom for instance) then my "compiled" JavaScript file also includes a portion of the Closure library. Is there a way to tell the Closure Compiler to leave certain JavaScript files/modules/whatever out of the built result?
FWIW, the Plovr experimental-exclude-closure-library option seems to somewhat describe the functionality I'm looking for.
On the surface what you are asking makes no sense. You want to depend on/use code from Closure-library, but not include it in your output. This isn't really possible nor how the library and compiler function together.
There is a rather small list of primitive functions defined in Closure-library that are completely removed/replaced when compiled with Closure-compiler. goog.require and goog.provide are the two most prominent of those.
For the vast majority of the Closure-Library, if you use or depend on a class, method or object that specific code will appear in the compiled output. And because that library code itself may depend on other parts of the library, even more code may be included in the compiled result.
The difference between using Closure-compiler with Closure-library as compared to more traditional JavaScript libraries is that ONLY the parts of the code determined to be called and used are included in the output. This is much more granular than a simple file inclusion - prototypes, variables, constants, etc will all be excluded because the compiler can determine that they are never used.
Distributing a Library
If you are building a library which depends on Closure-library, you have two options.
Distribute a compiled/built version
You would compile your library using Closure-library; exporting any public API methods and properties. Others who utilize your library with Closure-compiler or Closure-library will need to use an externs file and include your library AFTER compilation.
Distribute your library as source
You would simply distribute your library source code. Others would goog.require your library as part of their source and build process. If Closure-library is used in both projects, it will only be included once in the build process.
There is no hybrid approach where you compile your code but exclude Closure-library. This violates the principle that all of the source code will be compiled simultaneously.
You can peruse my Geolocation-marker library to see an example. I provide a compiled standalone version of the code for use, but the uncompiled source can also be included in other projects which use Closure-library.

How to port Javascript project to Coffeescript

If I wanted to port an existing project from Javascript to Coffeescript (in my case, within a Rails application), would I need to convert existing Javascript files? I'm worried about converting really large and CDN hosted files like jQuery and jQueryUI. How would I work around that?
As #asawyer stated, you do not need to port existing JavaScript libraries and such to CoffeeScript.
CoffeeScript exists to add convenience for writing your own custom code. Because the CoffeeScript compiles into JavaScript, it plays nicely with other JavaScript libraries like jQuery without your needing to convert those libraries into CoffeeScript.
If you have your own code that you want to convert into CoffeeScript, I've found js2coffee.org very helpful. It also serves as a great learning tool for "thinking in JavaScript" and seeing how it would be done in CoffeeScript.
Within rails, coffeescript is run through a compiler and into javascript anyway. You can include pure javascript files if you want (.js), or coffeescript (.js.coffee), which is compiled into js. If you're just looking to include legacy files, you won't need to do any conversion at all -- Might not make sense to convert to coffeescript, just to have rails compiler convert back to javascript in the asset pipeline... See http://guides.rubyonrails.org/asset_pipeline.html#coding-links-to-assets for more from the rails team on how to use js in the asset pipeline.
jQuery is already included in newer versions of Rails (3.1 onward), so that shouldn't be an issue. http://weblog.rubyonrails.org/2011/4/21/jquery-new-default/
Also, many other jQuery addons have a gem that you can simply include -- no need to reinvent the wheel there.

JavaScript bytecode compiler?

For a project I'm tangentially working on, I need a way to compile JavaScript into some intermediate language or bytecode so that I can single-step through it. I know that many of the JavaScript engines in modern browsers do something like this, but they don't make the resulting bytecode accessible. Is there a good off-the-shelf tool for this sort of JavaScript compilation?
Not exactly sure of your needs, however maybe Rhino could work for you.
The JavaScript compiler translates
JavaScript source into Java class
files. The resulting Java class files
can then be loaded and executed at
another time, providing a convenient
method for transfering JavaScript, and
for avoiding translation cost.
More about the compile function is located here.

Categories

Resources