Dojo FAQ: How do I load multiple versions of Dojo on the same page using modern Dojo?

By on October 22, 2014 1:02 pm

DojoFAQ

The way modules are loaded changed with the introduction of modern Dojo (1.7+). Dojo now uses the AMD format for packaging and loading modules within an application. AMD avoids the use of globals, which limits the likelihood of unintended interactions between modules. By leveraging AMD and the flexible configuration provided by the Dojo loader, we can load different versions of the same package on a page without dangerous interactions.

Relocating module namespaces

If our application contains two packages that depend on different versions of Dojo, we can control which version of Dojo is provided for each package by relocating the Dojo module namespace. The mapping for which Dojo version is provided for each package can be configured in the dojoConfig.

Project structure:

src/
  libs/
    dojo18/
    dojo110/
  app/
    main.js
  oldApp/
    main.js

In the example application, the oldApp package depends on Dojo version 1.8 while the app package works with 1.10.

By configuring a map for both app and oldApp we can control the Dojo version for each. For this example we will be using Dojo 1.10 with the following configuration.

Example Dojo config:

var dojoConfig = {
  baseUrl: '/src',
  packages: [
    { name: 'dojo110', location: 'libs/dojo110' },
    { name: 'dojo18', location: 'libs/dojo18' },
    { name: 'app' },
    { name: 'oldApp'}
  ],
  map: {
    app: { 'dojo': 'dojo110' },
    oldApp: { 'dojo': 'dojo18' }
  }
};

Let’s take a look at the purpose of dojoConfig for this application. We are configuring four packages in our dojoConfig. The first two packages are dojo110 and dojo18. These are the two different versions of Dojo needed by our application. The names must be unique, so we have added a version number to the end of the id. We also provide a location where the loader can find each package when they are required as a dependency.

The next two packages point to our old and new versions of our app named oldApp and app. We then use a map to tell the loader which Dojo to provide when someone requires a Dojo module.

Example app/main:

define(['dojo/main'], function (dojo) {
  console.log(dojo.version); // 1.10.1
});

When our app/main function runs, we log the version of Dojo that was provided by the loader. In this case, we were given Dojo version 1.10.1.

The last package is oldApp. The oldApp package requires Dojo version 1.8, so we have configured the map to point to the dojo18 package when someone requires Dojo as a dependency. Again, this instructs the loader to provide the dojo18 package for any Dojo dependency in the oldApp package.

Example oldApp/main:

define(['dojo/main'], function (dojo) {
  console.log(dojo.version); // 1.8.7
});

Invoking the oldApp/main module will log the version provided by the loader. This time we see that the loader provided Dojo version 1.8.7

Conclusion

Through the use of the dojoConfig, we have the ability to load two different versions of Dojo in the same application. Your team can develop against the newest version of Dojo while still maintaining compatibility in packages that may not be ready for the latest and greatest version of Dojo. In an ideal world, you’ll of course want to eventually update all portions of your application to use the same version, to improve the performance of your application by minimizing the loading of mostly redundant code.

Learning more

We cover advanced AMD topics including map and more in depth in our Dojo workshops offered throughout the US, Canada, and Europe, or at your location. We also provide expert JavaScript and Dojo support and development services, to help you get the most from JavaScript, Dojo, and AMD. Contact us to discuss how we can help.

Comments