Tuesday 6 November 2012

Combining Different Versions of Dojo

During a project I've been working on for the past couple of months my office mate and I needed to work out how to combine a recent version of Dojo and use it on a page where an old version of Dojo was already present.  Our reasons were simple, we were writing a Dojo Mobile app and hence required the use of a new version of Dojo.  However, we were displaying content within our app from a product that embeds an older version of Dojo.

With not much in the way of documentation on how to do this available, I asked our local Dojo guru for some advice and he pointed me towards the "noGlobals" option in dojoConfig.  This is the key to getting things working as it stops the new version of Dojo from writing to the global name space i.e. when you include the old version of Dojo it sets up a global variable called "dojo" if you simply include the new version of Dojo it will also write to the "dojo" global variable.  That means which ever version of Dojo you include last will always be the one you're using when you reference the "dojo" variable.  With the "noGlboals" option in place (which is adhered to by Dojo 1.7 and above I believe) you can continue to use old versions of Dojo from the global name space in conjunction with locally scoped newer versions of Dojo.

It appears there's still not a great deal of examples out there on how to do this so this is my attempt to put together a simple example to show how it's done by combining the ancient Dojo 1.3.3 with the latest at the time of writing Dojo 1.8.1:

<html>
<head>
<title>Dojo Mix-Up</title>

<!-- 
  lets start by including a really old version of Dojo 
-->
<script type="text/javascript" 
  data-dojo-config="isDebug: false, parseOnLoad: false" 
  src="dojo-release-1.3.3/dojo/dojo.js">
</script>

<!-- 
  configure Dojo to load without trampling the global namespace
-->
<script language="JavaScript" type="text/javascript">
  var dojoConfig = {
    noGlobals : true,
  };
</script>

<!-- 
  load the latest version of dojo
-->
<script type="text/javascript" 
  data-dojo-config="isDebug: false, parseOnLoad: false"
  src="dojo-release-1.8.1/dojo/dojo.js">
</script>

</head>

<body>

<!--
  Shove in a couple of divs to write to
-->
<div id="oldDojo"></div>
<div id="newDojo"></div>

<script type="text/javascript">
  // output our global namespace Dojo version (1.3.3)
  dojo.byId("oldDojo").innerHTML = dojo.version;
  
  // output our new Dojo version (1.8.1)
  require(["dojo/dom", "dojo"], function(dom,dojo){
    dom.byId("newDojo").innerHTML = dojo.version;
  });
</script>

</body>
</html>

14 comments:

Limited Time said...

I'm doing something similar and ran into the same issues. I have a web application that is using Dojo 1.6.1 and I'm trying to embed an iFrame that uses Dojo 1.9.1. Both pages work independently without any issues, but together the contents of the iFrame are acting like they might be hitting conflicts or using the old version.

Any ideas on how to fix this issue?

Thanks, TJ

Graham White said...

Hi TJ,

That's the exact problem I've explained how to fix above. Use the noGlobals option (careful of case) to mix the two. For you, include dojo 1.6.1, then configure the option, then include 1.9.1. The code example should help (I tested it as working), not a lot else I can say other than what's in the main post above.

Carl said...

I'm very new to DoJo and trying to get a new version of DoJo working in a product from IBM called Maximo. It has 1.7.1 built in but i'm trying to use the new calendar in 1.9.

Tried various things with no joy so now trying to get multiple version working on the same page. In a local Eclipse workspace i have a js_library folder in WbeContent and in there two version of dojo (dojoroot17 and dojoroot19) Now i've copied your example and made the changes to use my version but it just doesn't work.

Can't include my code as it won't let me.

When i run this on a HTTP Preview server i get

1.7.1 (23930)
1.7.1 (23930)

If i use the developer tools in chrome i see the following in the
console

message: "defineAlreadyDefined"
src: "dojoLoader"

Tried various examples across the web with no luck at all.

Any suggestions?

In Maximo when it builds the EAR for the application it also builds the DoJo. Tried putting my new version into this but even though it seems to get so far it fails the ANT with a rubbish error of Java Returns 1....

Cheers

Carl

Graham White said...

Hi Carl,

I guess you could always try and port the calendar from 1.9 back to 1.7.1 and just include it as a module? Presumably you've at least been able to get my example on this page working?

Graham

Carl said...

Hi Graham,

No not able to get your example working. I've copied it exactly into an HTML page in eclipse which is in a Web Project. As part of that i've added a js_library folder under WebContent which contains a folder for each version of dojo i'm trying to use.

I've then ran the page on a HTTP Preview Server in eclipse and i get

1.7.1 (23930)
1.7.1 (23930)

on the page. If i then use chrome dev tools to look at the page i see this in the console

message: "defineAlreadyDefined"
src: "dojoLoader"

Graham White said...

The example on this page still works for me. I've just tried it with Dojo 1.3.3 and 1.9.3. What I did was:

1) Create a test directory
2) Copy the sample from this page as index.html
3) Download Dojo 1.9.3 and extract it into the test directory
4) Modify the sample index.html to update the include from 1.8.1 to 1.9.3
5) Download Dojo 1.3.3 and extract it into the test directory
6) Go to the index.html page in a web browser

Results show:
1.3.3 (21524)
1.9.3 (fd52c96)

Carl said...

Is it a particular download version? Src? build? Very new to Dojo thats all

Could it be done using a hosted version like google for example to prove it works?

Do you run the index.html from a server or simply open it from an explorer and view it in IE or Chrome? Cause obviously a lot of browsing block those now

Cheers

Carl

Carl said...

Right here is what i did.

1 - Create test directory
2 - Copied Dojo 1.7.1 to it
3 - Copied Dojo 1.9.1 to it
4 - Created index.html with your code
5 - Changed code to load 1.7.1 and 1.9.1
6 - Opened Index.html in IE and allowed blocked content.
7 - Showed

1.7.1 (23930)
1.7.1 (23930)

Cheers

Carl

Carl said...

Getting weird results depending on version i use.

So trying version 1.3.1 src and 1.7.1 src and in the console on IE i get

SCRIPT5: The system cannot locate the resource specified.

dojo.js, line 290 character 5
SCRIPT5: The system cannot locate the resource specified.

dojo.js, line 290 character 5

but it shows

1.3.3 (21524)

On the page.

Same for 181 src, & 193 src.

If i change to use 171 as the older version and 181 as the new version i get the following in the IE console

SCRIPT5: The system cannot locate the resource specified.

dojo.js, line 295 character 5
SCRIPT5009: 'dojo' is undefined
index.html, line 42 character 3
[object Error]
LOG: description:timeout
LOG: message:timeout
LOG: src:dojoLoader
LOG: info:[object Object]
LOG: name:Error
LOG: .

and nothing in the page.

Obviously just not getting all this. Probably something around builds and src version of dojo.

Best get my reading glasses on..

Graham White said...

I'm not sure whether this sample will work for combining two newer versions of dojo, I'd have to look into that myself too. This example is for mixing a newer version of dojo with something really old (I'd guess around 1.6 or prior). With newer versions of Dojo you can contain things separately and hence (I would guess) there is probably some configuration option for dojo to define how these are loaded.

Carl said...

Thanks for the reply.

I'll try with your versions in your example and see what happens but expecting the same result.

Because i'm wanting to use the calendar i would have to use a version that started in perhaps. Currently our maximo is using a 1.7.1 version which doesn't have it.

Carl said...

I actually have tested it with fresh src dl's of 1.3.3 and 1.8.1 and still doesn't work.

I get

SCRIPT5: The system cannot locate the resource specified.

dojo.js, line 295 character 5
SCRIPT5: The system cannot locate the resource specified.

dojo.js, line 295 character 5
[object Error]
LOG: description:timeout
LOG: message:timeout
LOG: src:dojoLoader
LOG: info:[object Object]
LOG: name:Error
LOG: .

in the console and

1.3.3 (21524)

in the page.

Mmm if i switch the old and new versions around in the code i get
1.8.1 (29801)
1.8.1 (29801)
in the page and no errors...

Graham White said...

Well what you're doing certainly looks possible with newer versions of Dojo i.e. you should be able to combine 1.7.1 and 1.9.1 for example. Take a look at the options around Dojo modules and the AMD loader - the packageMap option is probably what you want.

Carl said...

Thanks will investigate now.