[dojo-contributors] Code style change (was Re: Allow multiple dojo versions in a page for 1.1?)

James Burke jburke at dojotoolkit.org
Sun Jan 27 05:40:38 UTC 2008


On Jan 25, 2008 4:58 PM, Shane O'Sullivan <shaneosullivan1 at gmail.com> wrote:
> Hi James,
>
> Answers inline
>
> > That would only work in dev if you manually modify the script-included
> > file to insert the function wrapper?
>
> Not so.  If the file took the form:
>   dojo.require("dijit.form.Button");
>   dojo.require("dijit.form.FilteringSelect");
> etc, then at development time the dojo.require function call would
> take care of the scoping. The build system would then replace this
> file with the contents of the files that it dojo.require's, and wrap
> that in a function call, so that it'll work then too, without having
> to go through the dojo.require system.

Let's say you want to load a script named dojo/foo.js and it has these
contents (it is basically like a layer file that will be replaced with
inlined content once you do a build):
dojo.provide("dojo.foo");
dojo.require("dijit.form.Button");
dojo.require("dijit.form.FilteringSelect");

In development, you load this file via a script tag after dojo.js:
<script type="text/javascript" src="dojo/foo.js"></script>

Now suppose you configured dojo.js to use scopes via
djConfig.scopeMap. The scopeMap configures dojo to really be bar in
the global scope, dijit is bijit and dojox is barx. Once you do that,
loading dojo/foo.js will break. "dojo" will not be exported out of
dojo.js as a global (just "bar), so the contents of dojo/foo.js will
call on a non-existent "dojo", resulting in an error.

The only way to get this to work in dev is to manually change the
contents of dojo/foo.js to this:
(function(dojo, dijit, dojox){
dojo.provide("dojo.foo");
dojo.require("dijit.form.Button");
dojo.require("dijit.form.FilteringSelect");
})(bar, bijit, barx);

To me, that is not a desirable solution to get this to work in dev. I
much rather prefer to give our normal advice ("use dojo.require").

> > I think the takeway is that it would be nice to support loading layer
> > files via plain script tags, but not have to do an xdomain build. Does
> > that sound right?
>
> Precisely. Making it work with one approach and not the other could be
> very confusing, and will lead to many many user requests for the
> script tag method to work.  Better to put it in now rather than have
> to add it later once people realise how cool this is but want it to
> work with browser caches.
>
> > My first inclination is to not support this. This means another build option
>
> Not necessarily.  You've already put in the build option to specify
> the scope names.  We just change that option to perform the extra work
> needed, rather than just putting a single array into the bootstrap
> code, as is done now. This will give people a consistent behavior.
> For example, I personally was confused for a bit after I did my build
> that script including a file didn't work - I never dojo.require files
> unless absolutely necessary, so it didn't even occur to me to do so.
> I'm sure a lot of other people will find the same problem.

You got started before I could do the documentation. I still need to
do a fix for the debugAtAllCosts case before I did the docs. So you
got hit with some confusing parts of using the feature. I consider
this a very "advanced" feature, so I think it is fine that it needs
some explanation in the documentation.

Also, using raw script tags and not using dojo.require means you are
not using the loader in the "standard" way. You are free to do that if
you know what you are doing, but it will be more work going outside
that path. However, I'm not sure I should put in extra code to support
this path for an advanced feature like multiple version support. I was
able to introduce the feature easily by leveraging the work that
dojo.require does.

[snip]
>
> > I'm trying to walk the line of not giving too many degrees of freedom,
> > particularly as we get into further "fringe" use cases, like
> > multiversion support, but still have the feature usable.
>
> Agreed.  However in this case, with the existing build option we can
> make this work both with dojo.require and with script tags, with no
> extra complexity than already exists.

I would not want this behavior (injecting the anonymous function
wrapper in the source as part of a build) as a default part of the
build because that means you have to know the new scope names *up
front* when you do the build (see the bar, bijit and barx example
above).

The way it works now, there is no assumption on the scope names, and
you can decide at runtime what they will be. I like that as a default
because it means you can do a build without specifying any
scope-related stuff and it will work.

However, if you want to "burn in" scope names, then there is a build
option for that. That is necessary to make sure you can provide your
own library under your own namespace without needing your users to
configure it.

There are also build options for the xdomain case, because that one
uses script tags to load things, and it needs to know the global names
so it can register the loaded code correctly. It is unfortunate that
you need these at all, and I tried to avoid it, but cannot given that
scripts are loaded in the global scope.

I'm just not seeing a good case to introduce another option for a use
case that does not follow our standard use advice, mainly use
dojo.require to load code. Particularly when, to get it to work in
dev, you also have to do manual function trickery for it to work (the
bar/bijit/barx example above).

Also, I'm hoping that after I get the documentation finished, it will
help some, and will have saved some of the frustration you encountered
when first trying to use the feature.

James


More information about the dojo-contributors mailing list