I'm investigating using the Closure Compiler & library in an existing
web application.
This has some constraints in that not all scripts can/will (currently)
be managed by Closure, some code is injected as web-services for
example.
When using the module handling goog.provide/require in uncompiled mode
everything works fine. But, in compiled mode I get clashes with
existing code that shares namespaces.
This boils down to that goog.provide is "polite" in that it doesn't
replace existing namespaces. Compiled code on the other hand injects
explicit namespaces that doesn't do any checks. This results in that
uncompiled and compiled code aren't interchangeable with respect to
other code outside the control of Closure.
Example:
"goog.provide('Foo.Bar');" ---> compilation translates this to: "var
Foo = {}; Foo.Bar = {};"
Wouldn't it be possible to use this common pattern instead?
"if (typeof(Foo) == 'undefined') Foo = {}; Foo.Bar = Foo.Bar || {};"
add an "--enable_soft_namespaces" flag perhaps? :)
----
Essentially, I would like to be able to use compiled code but with
goog.provide style namespaces. Is this possible somehow?
// Fredrik
To unsubscribe from this group, send email to closure-compiler-discuss+unsubscribegooglegroups.com or reply to this email with the words "REMOVE ME" as the subject.
options.closurePass = false;
What compilation level are you using right now?
Also, a simpler workaround might be:
var myRequire = goog.require;
and then use myRequire instead of goog.require in your code, though
I'm not sure if that will work. This is based on the assumption that
the Compiler only rewrites calls to goog.require, but not aliased
ones.
Is that option same as the "process_closure_primitives" CLI flag? In
that case I've already tried it (that's when I found this by the way;
http://code.google.com/p/closure-compiler/issues/detail?id=130).
Perhaps that's an option, but then I would need to add duplicate code
to describe namespaces everywhere? Similarly, using an aliased
goog.provide would mean both closurebuilder and depswriter (and my own
tool) would need to be patched. I'll try to do some more tests with
this though.
To clarify my scenario:
----------
This is the setup I was trying to achieve:
* Debug mode:
load base.js + deps file(s) that contains "all" available script
files. (this works fine)
* Compiled mode:
load base.js + deps files(s) that points to compiled modules. (here's
were I currently fail)
---------
Application code will then _always_ use goog.require calls. Debug vs
compiled mode is handled by simply switching the deps file.
I thought the above setup would be a simple and flexible way to get
most of the Closure benefits. Only thing that is "sacrificed" is
advanced compilation.
Does the above look reasonable? Or should I go with some other setup?
---
The ideal features needed to achieve this setup would be:
- Compiler should be able to output compiled code that keeps the
original goog.provide/require calls.
- When compiling modules the compiler should move all provide/require
tags to the top of the file so that
they can be parsed using depswriter (depswriter currently chokes and
outputs syntax errors on require/provides that are spread inside a
file).
I even tried using the "module_wrapper" flag to re-inject goog.provide/
requires at the top of the compiled module-files. If the compiler had
used "soft"
namespace merging that would have worked.
Digging in the compiler source.. would it perhaps be possible to
modify makeAssignmentExprNode and makeVarDeclNode in
ProcessClosurePrimitives.java to output code that would do namespace
merging? (Or am I getting waay out here?...)
Regards
// Fredrik
Your suggestion looked plausible, but doesn't seem to work for me.
When compiling in simple mode the compiler inserts same "hard"
namespace code anyway.
var Foo=Foo||{};Foo.Bar=Foo.Bar||{};
Also, if using warning_level=VERBOSE, that pattern won't compile at
all since it is interpreted as duplicate variable declarations (Foo).
var Foo = Foo || {};
Foo.Bar = Foo.Bar || {};
-----
(i.e the above will fail in when compiled in VERBOSE mode)
I figured a provide('Foo.Bar'); made provide('Foo') redundant (if I
didn't wan't to use it as a bundle module).
Logically I guess it is, but in this special case after compilation I
can see how it "fixes" things.
Short term this pattern might actually make my project compilable. I
need to add duplicate namespace declarations everywhere.
(note: can't seem to wrap it in a separate namespace generator
function if not using advanced mode compilation though. Simple mode
will not analyze the call and would still insert the "hard"
namespace).
Thanks!
// Fredrik
On Mar 25, 5:43 pm, John Lenz <concavel...@gmail.com> wrote:
> On Thu, Mar 25, 2010 at 8:09 AM, Fredrik <fblomqv...@gmail.com> wrote:
> > Your suggestion looked plausible, but doesn't seem to work for me.
> > When compiling in simple mode the compiler inserts same "hard"
> > namespace code anyway.
>
> I don't see this. Ignoring the code from base.js, this is what I see:
>
> var Foo=Foo||{};Foo.Bar=Foo.Bar||{};
>
> Usinghttp://closure-compiler.appspot.com/ this is what I did:
To unsubscribe from this group, send email to closure-compiler-discuss+unsubscribegooglegroups.com or reply to this email with the words "REMOVE ME" as the subject.
A bit cumbersome yes, but doable.
I'd be interested to hear about other suggestions for cases like this,
this kind of
requirements and constraints must be quite common I'd say(?).
During development of this I also wrote a generic "modulebuilder" tool
that figures out module-module
dependencies to enable easy module compilation.
Syntax example:
"pyhton modulebuilder.py --root code/myscripts --module
module1:ns1,ns2 --module module2:ns3 --keep_dep_tags true --
list_unused_files true --compiler_flags ...."
("keep_dep_tags" does the special provide/require re-injection I
needed)
If anyone is interested, I'm considering making it OS. Perhaps it
could even fit in the Closure toolbox? (It uses closurebuilder's
depstree extraction for example).
// Fredrik
> > > Usinghttp://closure-compiler.appspot.com/this is what I did:
To unsubscribe from this group, send email to closure-compiler-discuss+unsubscribegooglegroups.com or reply to this email with the words "REMOVE ME" as the subject.
Thanks for your support
// Fredrik
> > > > > Usinghttp://closure-compiler.appspot.com/thisis what I did:
> > To unsubscribe from this group, send email to closure-compiler-discuss+