On Sat, Jan 26, 2013 at 7:55 AM, Erik de Bruin <e...@ixsoftware.nl> wrote:

> > code and vice versa. I still think that RequireJS is the better choice,
> as
> > Closure implements *synchronous* require() which does not work
> dynamically
> > in the browser, and the Closure Library comes with many many more
> features,
>
> I really wish you would stop saying this. It is simply not true.
> Please look at the 'js-intermediate' output to see how 'base.js'
> dynamically loads only those files from the 'goog' library it actually
> uses, in the order needed to allow proper instantiation. How is that
> different from RequireJS?
>

No, I won't stop saying this. (I'm a bit stubborn, you know.) Maybe I'll
stop saying it like above, as this is a very short and simplified form,
which I just chose because I thought we had this discussion before. But I
am willing to pick it up again, and I hope you are, too.

That your prototype uses goog.require() and works in the browser is fine,
but it is not a proof that this is the best approach.

I am arguing from a conceptual viewpoint: how can a module loader that uses
*synchronous* require load scripts dynamically, as needed, in the browser,
where everything can only be loaded asynchronously? When looking at this
Google Closure "Getting
Started"<https://developers.google.com/closure/library/docs/gettingstarted>,
I understand that
   goog.require("Foo");
   var foo = new Foo();
can only work if you split it into two scripts (one doing the require, one
using it) or, in your build process, apply the GoogleBuilder tool that
analyzes the code so that the required script is loaded in advance. The
only solution I can think of to make the above example work *as-is* in the
browser would be to do it like Sencha Ext 4 and, in "development mode",
load code via a *synchronous* XHR and then using eval() on the response
text, both of which sounds evil to me.

So to make JavaScript code written the "goog" way actually work in the
browser, you need the GoogleBuilder / Google Closure Compiler tool, right?

RequireJS is different in that it respects the browser's nature of loading
things asynchronously. Thus, it is built into the concept of *Asynchronous*
Module Definitions (AMD) that script loading needs a callback:
require(["scriptA", "scriptB"], function() { ... }); Also see
http://requirejs.org/docs/whyamd.html


> Also, how is 'many, many more features' a bad thing?
>

That statement was too general, sorry. I wouldn't have a problem with
Closure having many (optional) features. The problem I have is that Closure
is not only a runtime library plus a build tool, but it defines *extensions
and restrictions to the JavaScript language itself*. And because it defines
extensions *and* restrictions, I consider the input Closure requires
*another language* than JavaScript. This makes the decision for Closure
much more than whether we want to use synchronous or asynchronous require.

Look at the long list of
restrictions<https://developers.google.com/closure/compiler/docs/limitations>
the
Closure Compiler imposes on your JavaScript code. Especially when using
ADVANCED_OPTIMIZATIONS (without which using Closure misses much of its
value), you cannot expect your completely strict-mode, jslinted,
cross-browser-compatible, fully-tested JavaScript code to still work.
There are many 
annotations<https://developers.google.com/closure/compiler/docs/js-for-compiler>
you
need to use and
patterns<https://developers.google.com/closure/compiler/docs/api-tutorial3>
you
need to follow to take advantage of ADVANCED_OPTIMIZATIONS mode. When you
use a wrong annotation (or no annotation where one was needed), the
optimized code works incorrectly, thus the annotations are not "just for
better optimization", but actually part of the "goog" language semantics,
at least if you use ADVANCED_OPTIMIZATIONS.
That sounds to me like the JavaScript code Closure wants as input is a
custom (proprietary) version of JavaScript, and not the JavaScript we know.

In contrast, RequireJS introduces its Domain-Specific Language for modules
and module dependencies purely based on original JavaScript language
constructs, namely functions. You need no annotations and no build tool to
make the JavaScript code run in the browser as-is, only a library written
in JavaScript, too (require.js or almond.js or any of the many other
implementations). Only to optimize all module scripts into one or several
larger chunks, you need to use the provided build tool (r.js). Even this
build tool does not do much magic, but is only needed to allow the
syntactic sugar to not repeat the module name in the module JS code (it
deduces the module name from the file name when concatenating scripts).
Since we generate the JS code and manage dependencies ourselves, we could
easily add the module name and concatenate the needed scripts ourselves.
Another advantage of AMD is that it does not rely on global variables, but
hands over module references into the callback function's parameters:
require(["com/acme/very/long/Foo"], function(Foo) { /* access
com.acme.very.long.Foo as Foo */ }); These are more efficient to access
without any optimization, and can easily be further optimized (e.g.
abbreviate a long class name) by any JavaScript minifier that is capable of
shortening local variables.

Goggle Closure library + compiler work on many different conceptual levels,
so you don't "buy" a module management system, but a complete JavaScript
(and beyond) ecosystem. It's a matter of choice, but I am more the
standards / modular / cherry-picking type and don't like to rely on an
all-in-one solution by a specific vendor, especially in the JavaScript
world where there are always many alternative libraries / frameworks to
chose from. (So there we also have a connection to the original topic of
this thread ;-)!)


>
> Please take a look at the proof of concept (both the intermediate and
> release code) before making these kinds of statements.
>
> I'd like to, but you admitted yourself that it has quite an initial
overhead to set up. Could you perhaps set up an online demo where one can
observe a running system? Or a download of the compiled application? At
least that's what I did for the AMD approach:

* pure JavaScript prototype:
  http://fwienber.github.com/as-js-runtime-prototype/index.html
* Open Flash Chart demo, compiled with Jangaroo 3:
  http://jangaron.net/ofc5/data-files/joo.html#joo.debug

Greetings
-Frank-

Reply via email to