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-