Make browserify work with Google Closure Compiler - google-closure-compiler

I am trying to compile my code generated by browserify with Google Closure Compiler using Advanced Optimization.
Tried running browserify with different flags, no success so far.
Have any one have some experience with that?

I had to change the file: /node_modules/browserify/node_modules/browser-pack/_prelude.js with google closure annotations and add the externs files as
/**
* #param {*=}o
* #param {*=}u
*/
function require(o,u){}
What errors/warnings do you get?

Related

Is it possible to create API bindings for GJS in other languages?

What I mean specifically is if it's possible to have some code written, say in C (or some other compiled language), and then expose it and use from within a GJS runtime.
In fact, this is how all of GJS works. Just as node.js is ECMAScript on top of node's own platform, GJS was created so that ECMAScript could be used with the GNOME platform libraries.
This is effectively limited to C libraries written with GObject, but of course anything you can use from C can be wrapped into a GObject-based library. There are Boxed Types for integrating foreign structures into the GLib type system, or you can wrap things into the structure of a GObject subclass.
The principle is pretty straight-forward and relies on use GObject-Introspection Annotiations to express function signatures, memory ownership and so on. Below is a simple example:
/**
* namespace_copy_string:
* #input: (transfer none): an input string
*
* This function copies a string and returns the result.
*
* Returns: (transfer full): a new string
*/
char *
namespace_copy_string (const char *input)
{
return g_strdup (input);
}
The headers and source are then scanned for public symbols with these annotations, and use to generate an XML-format and compiled typelib. meson is the recommended build-system for GObject-based libraries and includes helpers for generating the introspection data. You can also use gi-docgen to easily generate documentation from this output.
Once installed, the result can be imported into any language binding that supports GObject-Introspection (GJS, Python, etc):
const Namespace = imports.gi.Namespace;
let copy = Namespace.copy_string("content");

How do I tell Flow that there will be a class on window without explicitly specifying its type?

I want to incorporate the Google Maps JS library into a Flow-typed project. Since there aren't any remotely complete Flow externs for the library, I'd like to tell Flow to accept whatever methods and constants I call from the class as Function and any, respectively. I know that the best answer would be to write a complete extern for GMaps and post it on Github, but I've got deadlines to meet. Using flow-typed is also an option to generate stubs, but that only seems to work on npm packages. What would be the best way to tackle this?
If you want to completely skip checks, you can simply declare:
declare var google: any;
Which will allow you to do whatever you want to google:
google.maps.Map();
google();
google.maps.Map.call();
Or if you wanted to at least ensure you always call google.maps.something and never google by itself:
declare var google: { maps: Object };

Why isn't Closure Compiler trimming down Three.js completely?

I am copying the source of THREE.js from this link, and pasting it into Closure Compiler UI. I have the following options set:
// ==ClosureCompiler==
// #compilation_level ADVANCED_OPTIMIZATIONS
// #language ECMASCRIPT5
// #output_file_name default.js
// ==/ClosureCompiler==
Yet, for some reason, clicking compile only gets this down to 271KB uncompressed.
My question is, THREE.js doesn't seem to have any exports, so why doesn't Closure Compiler trim it out completely with ADVANCED_OPTIMIZATIONS?
I am building a library on top of THREE.js, and would like to utilize Closure Compiler's dead code removal to make the bundle more manageable. What else should I be doing to trim out functions in THREE.js that are never called?
It doesn't appear that three.js is compatible with Closure-compiler's ADVANCED_OPTIMIZATIONS mode.
The over 1800 warnings I got when compiling the source were a pretty big clue as well.

Compile moment.js with google closure and advanced optimizations

I work on a project which uses Google's closure compiler with advanced optimizations turned on. I would like to include moment.js in the compilation, however all of my attempts have been fruitless.
I have tried exporting the moment function, but there are still run time problems, and a some compile errors.
Has anyone successfully compiled moment.js with advanced optimizations, or know how to do so?
The only solution I can come up with, is to concatenate the minified file to the compiled source and use externs for every function I use from moment.js. But this is not an ideal solution.
I saw two issues with the code which would have to be corrected before momentjs would be compatible with ADVANCED_OPTIMIZATIONS. There may be more, but these were the glaring ones:
Using an alias for the prototype: All references to .fn would need to be replaced with .prototype.
Using a helper function to add methods: the extend method hides definitions from the compiler. All uses of the extend helper function would have to be refactored so that they do not hide the property assignments from the compiler.
I can't get it to work either as of 26 March 2015, but the existence of this suggests that it's possible. Here are the externs
You've gotta write your own externs file for moment.js for what you use from it (or the entire object, but I find that a bit of extra work for no reason).
For example, I've got this snippet to test if an input's date is within 14 days from now
$checkout.find('.date-input').on('input', /** #this {Element} */ function () {
const $this = $(this);
const Days = Number($this.attr('data-days'));
if (Days > 0 && moment(/** #type {string} */($this.val())).diff(moment(), 'days') < Days) {
$checkout.find('.date-warning').removeClass('d-none');
} else {
$checkout.find('.date-warning').addClass('d-none');
}
});
And the only way I'd get that to compile correctly with advanced mode is by creating this extern.
/**
* #fileoverview Externs for moment
*
* #externs
*/
/**
* #param {string=} date
* #constructor
* #return {!moment}
*/
function moment(date) {}
/**
* #param {!moment} m
* #param {string} unit
* #return {number}
*/
moment.diff = function (m, unit) {};
moment.prototype.diff = moment.diff;
Now clearly that description of the moment function isn't perfect; it's missing some parameters that the moment function has, but I'm not using them so it doesn't matter to me.
But that's how I start my externs. I start basic as the need arises and then I continue to grow the externs file with the more functions I need from a library.
And don't forget to tell Closure Compiler where your extern is located with the flag --externs 'externs/moment.js'.

How do I change Closure Compiler compile options not exported to command line?

I found that some options in CompilerOption are not exported to the command line.
For example, alias all strings is available in the Closure Compiler's Java API CompilerOption but I have no idea how set this in the command line.
I know I can create a new java class, like:
Compiler c = new Compiler();
ComppilerOptions opt = new ComppilerOptions();
opt.setAliasAllString(true);
c.compile(.....);
However I have to handle the command line args myself.
Any simple idea?
============================
In order to try the alias all string option, I write a simple command line application based on compiler.jar.
However I found that, the result I got when open the alias all string is not what I expected.
For example:
a["prototype"]["say"]=function(){
var a="something string";
}
Given the above code, the something string will be replaced by a variable like this:
var xx="something string";
....
var a=xx;
....
This is fine, but how about the string "say"? How does the closure compiler know this should be aliased(replace it use variable) or exported(export this method)?
This is the compiled code now:
a.prototype.say=function(){....}
It seems that it export it.
While I want this:
var a="prototype",b="say",c="something string";
xx[a][b]=function(){.....}
In fact, this is the google_map-like compilation.
Is this possible?
Not all options are available from the command line - this includes aliasAllStrings. For some of them you have the following options:
Build a custom version of the compiler
Use the Java API (see example).
Use plovr
Getting the same level of compression and obfuscation as the Maps API requires code written specifically for the compiler. When properly written, you'll see property and namespace collapsing, prototype aliasing and a whole host of others. For an example of the style of code that will optimize that way, take a look at the Closure Library.
Modifying http://code.google.com/p/closure-compiler/source/browse/trunk/src/com/google/javascript/jscomp/CompilationLevel.java?r=706 is usually easy enough if you just want to play with something.
Plovr (a Closure build tool) provides an option called experimental-compiler-options, which is documented as follows:
The Closure Compiler contains many options that are only available programmatically in Java. Many of these options are experimental or not finalized, so they may not be a permanent part of the API. Nevertheless, many of them will be useful to you today, so plovr attempts to expose these the experimental-compiler-options option. Under the hood, it uses reflection in Java, so it is fairly hacky, but in practice, it is a convenient way to experiment with Closure Compiler options without writing Java code.

Resources