Modules FTW, goodbye globals

205 views
Skip to first unread message

Brian Cavalier

unread,
Sep 13, 2012, 3:02:52 PM9/13/12
to cuj...@googlegroups.com
Cujo.js is a modern framework. The browser global is an outdated model. So, we've decided it's time:

With the exception of curl.js, upcoming releases of all cujo.js components will only support modular Javascript environments, and *will not* publish properties in the global namespace.

Curl.js, cujo.js's AMD loader, *will* continue to publish a browser global, since it must provide a module-loading bootstrap entry point (as any module loader must) for browser platforms.

Here's our plan:
  1. Deprecate browser globals in existing components when their next versions are released.  For example, meld.js 0.8.0, released today, deprecates `window.meld`.
  2. Remove browser globals in subsequent releases.  For example, the upcoming meld.js 1.0.0 release will support AMD and CommonJS module environments, such as Node and RingoJS, but *will not* create `window.meld`.
In addition to AMD and CommonJS modules, we're also keeping an eye on the Harmony Module spec. When it gets closer to being a reality, we'll be looking into supporting it.

unscriptable

unread,
Sep 13, 2012, 3:39:54 PM9/13/12
to cuj...@googlegroups.com
poll: Should curl remove it's global once it's been configured? How about a config option to remove it?  It seems this might help module n00bs by preventing them from accessing window.curl in their code (it's available as a module, ya know: `define(['curl'], function (curl) {});`).

James

unread,
Sep 14, 2012, 8:03:33 AM9/14/12
to cuj...@googlegroups.com
I love the idea of removing the global! :) 

+1 for config option. 

define will still need to hang around for module loading, correct?

unscriptable

unread,
Sep 14, 2012, 8:22:09 AM9/14/12
to cuj...@googlegroups.com
Heh yah. define() will need to stick around.  oops :)

KidkArolis

unread,
Sep 14, 2012, 7:39:03 PM9/14/12
to cuj...@googlegroups.com
It doesn't have to? If you build and wrap the entire app in a closure :)
I guess you can't avoid it if you want dynamically load some parts of the app.

If you were to remove all these globals (which I like the sound of), does that mean the only way to use cujo libs will be via AMD/CJS loader?

James

unread,
Sep 15, 2012, 8:21:46 AM9/15/12
to cuj...@googlegroups.com
I use requirejs in my thirdparty JS framework. I hide define inside of a wrapper during build. Works great, but my dynamically loaded modules are wrapped into another wrapper which can access my local copy of define on my namespace. That way I dont collide with other JS that might be using AMD on the page. I need to get my library into a same domain iframe to avoid more conflicts but I'm not there yet. :)  

Brian Cavalier

unread,
Sep 17, 2012, 8:08:16 AM9/17/12
to cuj...@googlegroups.com
Right, it seems like define() will have to be available at the time a new module is dynamically loaded (e.g. via local AMD require) ... I wonder if it's possible to make define available just-in-time in those cases.  Seems pretty tricky, though, given all the asynchrony involved in module loading.

Given that window.define is part of the AMD standard (whereas window.require and window.curl aren't), it doesn't feel as messy to leave it as a global.

And yep, cujo is will be targeting module environments-only.  For now that means AMD and CJS.  We'll be deprecating the globals of all the cujo libs in upcoming releases.  See the original post in this thread for a bit more info.

On Friday, September 14, 2012 7:39:03 PM UTC-4, KidkArolis wrote:

unscriptable

unread,
Sep 17, 2012, 8:12:32 AM9/17/12
to cuj...@googlegroups.com
On Friday, September 14, 2012 7:39:03 PM UTC-4, KidkArolis wrote:
It doesn't have to? If you build and wrap the entire app in a closure :)
I guess you can't avoid it if you want dynamically load some parts of the app.

If you were to remove all these globals (which I like the sound of), does that mean the only way to use cujo libs will be via AMD/CJS loader?

Correct.

unscriptable

unread,
Sep 17, 2012, 8:22:03 AM9/17/12
to cuj...@googlegroups.com
On Monday, September 17, 2012 8:08:16 AM UTC-4, Brian Cavalier wrote:
Right, it seems like define() will have to be available at the time a new module is dynamically loaded (e.g. via local AMD require) ... I wonder if it's possible to make define available just-in-time in those cases.  Seems pretty tricky, though, given all the asynchrony involved in module loading.

Currently, there's no signal or event that a script element's source is about to be evaluated.  We only get a signal afterwards (load or readystatechange event).  

Hm, it would be interesting to be able to set a script's scope -- limit each script to a different global env.  IIUC, node creates a different global env for each package.  If this were possible for scripts, we could inject a define() into the script's global scope....

...but then again, I'm not sure this is any better than current solutions.

 
Given that window.define is part of the AMD standard (whereas window.require and window.curl aren't), it doesn't feel as messy to leave it as a global.

Yah, this is probably the best way -- except for ppl who are creating third-party widgets and libs that get injected at run time (such as James' project).  curl.js supports config params to remap the globals (curl() and define()) to help with this.  There's more to it than that as James suggests.  A build step is also necessary since you have to modify all of your modules to use the remapped define().

James

unread,
Sep 18, 2012, 8:02:21 AM9/18/12
to cuj...@googlegroups.com

Hm, it would be interesting to be able to set a script's scope -- limit each script to a different global env.  IIUC, node creates a different global env for each package.  If this were possible for scripts, we could inject a define() into the script's global scope....

This could be done in the browser with a same domain hidden iframe :)  

Create a same domain iframe and expose define in the iframe. Then create the script tag within the iframe and there you have it a different global env in the browser :)  Since the iframe is same domain you can call functions and pass objects between the two.

voltron

unread,
Sep 18, 2012, 9:50:33 AM9/18/12
to cuj...@googlegroups.com
I'm not sure about this, what about functions that are used inline but are loaded with Curl?

In my HTML

<span><script>myModule.getTrans('Hello")</script></span>

myModule is a module acquired using Curl, this module in turn, has many dependencies that are also retrieved with curl. I think globals still have their uses

Brian Cavalier

unread,
Sep 18, 2012, 11:52:35 AM9/18/12
to cuj...@googlegroups.com
Hey voltron,

Other modules will still be able to declare globals (although we do feel that not using them is a more scalable approach).  The original post is referring to the fact that cujo's own libraries will no longer add themselves to the global namespace.  For example, meld.js had previously declared window.meld when loaded directly via a script tag, but in the upcoming 1.0.0 release, it won't.  It'll only be available as an AMD or CommonJS module.

So, excluding curl.js, cujo libs won't declare their own globals, but also won't clobber/prevent any globals you create.  Does that clarify?

unscriptable

unread,
Sep 18, 2012, 11:56:04 AM9/18/12
to cuj...@googlegroups.com
Hey Voltron!

We're not going to get rid of the curl() and define() globals any time soon.  There are some web app architectures that obviously require a global or two.  Also, as I realized after posting on this thread, it's very complicated to do script loading in today's browsers without at least one global.  

FWIW, inline script elements are problematic for several reasons.  Sorry, to pick on your code, but...

1) They have been linked with performance issues (at least in some browsers)
2) They violate the basic "Separation of Concerns" rule

You may want to investigate some of the cool in-browser MVC frameworks out there.  I'd encourage you to investigate the innovative cujojs/cola.js, but it's still in "alpha" (dev branch) and we haven't even documented it, yet.  

Regards,

-- John


On Tuesday, September 18, 2012 9:50:33 AM UTC-4, voltron wrote:
Reply all
Reply to author
Forward
0 new messages