[dojo-contributors] Code style change (was Re: Allow multiple dojo versions in a page for 1.1?)
Shane O'Sullivan
shaneosullivan1 at gmail.com
Tue Jan 22 09:15:26 UTC 2008
Hi James,
Answers inline:
> I think the larger issue is why are you doing the script includes?
Script includes should always be used in any high-traffic site. Since
dojo.require calls are no browser cached, they will be pulled down
every time. I would imagine that everyone who is writing non-hobbyist
websites will use script includes for the majority of their code,
leaving dojo.require for the development stage, and for loading
optional code (e.g. browser specific stuff like SVG) or i18n
resources.
Therefore, putting this functionality only in the dojo.require is
basically telling most people that in order for them to use it, their
sites have to take a big performance hit.
> You would have to do a build every time you did a code change
Not necessarily. You could script include a file that is replaced by
a built layer, similar to the dijit-all.js file. So, at development
time, you will be using dojo.require statements (which are all that
are included in the layer file) and at build time the same file is
replaced with the built/compressed code, already surrounded by the
scoped function
Thanks
Shane
On 22/01/2008, James Burke <jburke at dojotoolkit.org> wrote:
> On Jan 21, 2008 3:10 PM, Shane O'Sullivan <shaneosullivan1 at gmail.com> wrote:
> > I think the "gradually migrate" use case is definitely a very common
> > one - my company's client infrastructure is currently very dependent
> > on 0.4.3, and after our major release in a few weeks, we will begin to
> > upgrade to 1.x. Having this functionality work for that case would be
> > extremely useful to us.
>
> The functionality can work for that case, but it requires build step
> iteration for the 1.1 code, if you want to do something like
> debugAtAllCosts. If you do not need to do debugAtAllCosts then you can
> use the functionality as-is, in particular after I get the changes in
> for local djConfig values (so the 1.1 version will not be in
> debugAtAllCosts mode, but the other version can be).
>
> > Since you are wrapping all calls to dojo.require() with a private
> > function defining the scope map, would it not also make sense to do
> > the same in the optional build step - for each JS file that can be
> > dojo.require'd, wrap it's contents in that private function. Would
> > this not function just the same as dojo.require, and work also for
> > script includes? It would also remove the need for easily breakable
> > regexs
>
> This means though that if you develop any new modules, as you are
> developing, they would not fit into the scoped model. You would have
> to do a build every time you did a code change. This seems like an
> undesirably high development cost. Having the function wrapper done in
> the loader instead of every file avoids that issue.
>
> I think the larger issue is why are you doing the script includes? Is
> it for debugging? Do you find debugAtAllCosts not an acceptable
> solution in that case?
>
> [start larger philosophical issue]
>
> I have always been concerned that our loaders do not function the same
> as direct script tags. We get some tangible benefits though from our
> different behavior: dependency resolution, xdomain (CDN) loading, and
> now multiple version support.
>
> What we give up though is that the modules are not evaluated in the
> same scope as compared to plain script tags. Also, in the default
> loader case, trouble debugging because of the use of eval.
>
> There may be a way to get dependency resolution without using eval (IE
> and Safari use a different scope when we use eval):
> http://webreflection.blogspot.com/2007/08/global-scope-evaluation-and-dom.html
>
> (Blog post from Andrea Giammarchi. Basically, create a script node and
> do node.text = script or node.appendChild(textNodeWithScript). This is
> what jQuery 1.2.2 seems to do for one of their methods, and it is
> inspired from the blog post above).
>
> I do not think this would help the debugging case though. I tried
> something earlier with scriptNode.text in Firefox, but Firebug did not
> seem to be able to recognize it as something that was debuggable:
> http://groups.google.com/group/firebug/browse_thread/thread/41080497659c1423?hl=en
>
> And if we want to maintain the xdomain and multiple version support,
> the scope will still be different. So I do not see any good
> alternatives to our current loader approaches, particularly since we
> have debugAtAllCosts, which does attach scripts to the DOM.
>
> The downside is we have a case where debugAtAllCosts breaks down:
> using scoped code with the normal dojo loader when there is another
> version of dojo in the page. It is workable (do a build, or test the
> scoped code separately from the page that has the other dojo) but at
> this point, I think that slight awkwardness is outweighed by the
> benefit of just being able to run two versions of dojo in the page.
>
> But I'm really open to ideas on how to make that case better. Keep the
> ideas coming.
>
> [end larger philosophical issue]
>
> James
>
>
>
> > Thanks
> >
> > Shane
> >
> >
> > On 21/01/2008, James Burke <jburke at dojotoolkit.org> wrote:
> > > On Jan 21, 2008 1:54 PM, Shane O'Sullivan <shaneosullivan1 at gmail.com> wrote:
> > > > How does this work with <script> including files? When I specify the
> > > > scopemap from the trunk code, and include some dojox files, an error
> > > > is thrown saying that dojox is not defined. dojox10 is defined
> > > > instead.
> > > >
> > > > So, does this only work if dojo10.require() is used? Does that
> > > > automatically replace references in 'dojox' with 'dojox10', or how
> > > > does it work?
> > >
> > > Yes, it breaks with script-included files. The scope mechanism works
> > > by wrapping any code that is dojo.required in a function that defines
> > > what dojo, dijit and dojox really are. For example, it does something
> > > like this after fetching the module's source with XHR:
> > >
> > > eval("(function(dojo, dijit, dojox){
> > > //Your module's code goes in here
> > > })(dojo10, dijit10, dojox10);");
> > >
> > > (the xdomain thing does something similar, but you have to know the
> > > scope values at build time for anything beyond dojo, dijit and dojox)
> > >
> > > This has the benefit that we don't have to do some sort of complex
> > > regexp work at runtime or buildtime. I'm not confident we could catch
> > > all the cases using regexps. And it means we can support scoping with
> > > a default build of dojo (we do not have to make the scoping decision
> > > at build time -- we can do it at runtime). However it does break
> > > things if you are trying to manually import code via script tags.
> > >
> > > I will be adding a feature to debugAtAllCosts where if you are using
> > > the scoping stuff, it will create a globally visible dojo, dijit and
> > > dojox and bind them to the dojo10, dijit10, dojox10 (for instance)
> > > variables. This should then allow for doing the normal debugging you
> > > get with inlined script tags.
> > >
> > > *However*, the debugAtAllCosts global thing will make it hard if you
> > > are trying to debug your scoped code with other code on the page that
> > > is using dojo. At that point, I suggest doing a custom build of your
> > > scoped code so that everything is in a built, scoped dojo.js and
> > > proceed from there. That is what I consider the common workflow case
> > > (at least in the future):
> > >
> > > - You want to provide a library that uses dojo underneath, but you
> > > want to scope it to a different name, say "foo", "fijit" and "fojox".
> > > - You develop your library using the scope hooks, but you do not use a
> > > custom build and at this point you are not mixing with other dojo
> > > versions -- you are just developing your code. In this case you can
> > > use the debugAtAllCosts flag to help in your debugging (after I do the
> > > changes mentioned above).
> > > - You get it working, then you do your custom build, and deliver your
> > > foo.js for others to use.
> > > - Other people can use your foo.js in a page with other dojo code. If
> > > they need to debug, hopefully your foo.js is self contained, and the
> > > debugAtAllCosts debugging will only affect the other dojo. There will
> > > also be a build option to burn in a local djConfig so that your
> > > library code does not get weird djConfig values from the other dojo.
> > >
> > > For the other workflow where you have a Dojo 0.4.3 app and want to mix
> > > in Dojo 1.1, then it will require more work -- most likely doing some
> > > custom builds of the scoped 1.1 so everything is in one dojo.js file
> > > that you can import. Even though this use case is more work and
> > > probably the more common case right now, I expect this use case to
> > > shrink to zero with the other use case above being the majority case.
> > >
> > > Hopefully that explains the tradeoffs and why I'm favoring the "make
> > > your own library with dojo" case over the "gradually migrate my app
> > > from 0.4.3 to 1.x" case. I'm happy to hear feedback though. I did this
> > > work mostly in isolation, so I may have missed the mark for what we
> > > want.
> > >
> > > James
> >
> > > _______________________________________________
> > > dojo-contributors mailing list
> > > dojo-contributors at dojotoolkit.org
> > > http://dojotoolkit.org/mailman/listinfo/dojo-contributors
> > >
> > _______________________________________________
> > dojo-contributors mailing list
> > dojo-contributors at dojotoolkit.org
> > http://dojotoolkit.org/mailman/listinfo/dojo-contributors
> >
> _______________________________________________
> dojo-contributors mailing list
> dojo-contributors at dojotoolkit.org
> http://dojotoolkit.org/mailman/listinfo/dojo-contributors
>
More information about the dojo-contributors
mailing list