In our previous post, we briefly highlighted the distinctions between packages, paths, and aliases. In particular, we noted that you can do some interesting things with paths and aliases for creating shortcuts of a sort, but one of the difficulties is that these shortcuts are global. What if I only want to override a module path, like we would with aliases, but I only want to do that in the context of one specific module? What if I want to be able to have two different modules load app/Widget but have them receive two different versions of the module? We can do that, using map.

First, it’s important to note that this only applies to newer versions of Dojo. If you’re using a newer release of Dojo 1.8 or any of the Dojo 1.9 releases, the map configuration option is available. The value is an object whose keys are the modules to be impacted, and the values of those keys are module IDs to be remapped. It’s a bit verbose in English, so let’s show it in some code.

	map: {
		"app/ModuleA": {
			"app/Widget": "app/DebugWidget"
		}
	}

At its most basic, this is a simple use of map. In this case, if app/ModuleA requests to load app/Widget, it’s actually going to transparently receive the app/DebugWidget module instead. Only app/ModuleA is affected in this case. All other requests for app/Widget (even in app/DebugWidget) will receive the original module.

You may also have a scenario where you have two concurrent versions of modules, and you want to ensure that one module receives a newer version, while a second module receives the older version. You can do this fairly easily with map:

	map: {
		"app/ModuleA": {
			"app/Widget": "app/WidgetOld"
		},
		"app/ModuleB": {
			"app/Widget": "app/WidgetNew"
		}
	}

In this scenario, app/ModuleA will get the old widget while app/ModuleB receives the new widget. Any other requests will just load app/Widget.

In the event that you wish to create a mapping that applies for all modules, map has you covered there, as well. There’s a special "*" module value supported that applies the mapping to all modules. If a more specific module mapping exists, that one will take precedence, so you can safely use "*" and not have to worry about getting the wrong module. Taking our previous example, perhaps we want to ensure that everyone receives the old module, and only app/ModuleB gets the new one. We could extend the previous map like so:

	map: {
		"*": {
			"app/Widget": "app/WidgetOld"
		}
		"app/ModuleA": {
			"app/Widget": "app/WidgetOld"
		},
		"app/ModuleB": {
			"app/Widget": "app/WidgetNew"
		}
	}

You’ll notice that I’ve left app/ModuleA in the mapping, even though it’s redundant with the "*" mapping. Perhaps app/ModuleA has some dependencies on less-than-ideal behaviors in the older widget and it’s stuck using the old one until we’ve had a chance to update app/ModuleA appropriately, but everyone else is ready to move up. That would mean we could make one change to our map, and now everyone would pick up the newer module until we’d had a chance to fix up app/ModuleA:

	map: {
		"*": {
			"app/Widget": "app/WidgetNew"
		}
		"app/ModuleA": {
			"app/Widget": "app/WidgetOld"
		},
		"app/ModuleB": {
			"app/Widget": "app/WidgetNew"
		}
	}

Then, once we’d had a chance to update everyone who used app/Widget, we could clean up and get rid of the excess modules and mappings.

However, this approach is not limited to just remapping specific module IDs. For each of the keys, it’s doing a partial mapping from left to right against module IDs, and so you don’t have to specify individual modules, but can simply list a partial ID, and it will map those out as appropriate, with the longest path taking precedence.

For example, you may wish to do something like use the 1.7 version of Dijit for a specific section of your application, all living under a app/widget folder. You could configure your application like this:

	map: {
		"app/widget": {
			"dijit": "dijit1.7"
		}
	}

Assuming you have dijit1.7 set up as a package, this would ensure that any module within the app/widget directory would receive Dijit 1.7 widgets instead of the current copy of Dijit. Therefore, app/widget/Form might request dijit/form/Form to use as a base, but it will receive the module loaded from dijit1.7/form/Form instead, even though app/widget/Form was not explicitly specified. So long as you’re using the newer version of Dojo as your loader, this will work well. You could even remap entire packages this way:

	map: {
		"package1": {
			"dijit": "dijit1.7"
		},
		"package2": {
			"dijit", "dijit1.8"
		}
	}

The map config option is very powerful, and it currently meets the specification as laid out in the common config section of the amdjs-api wiki. This configuration is incredibly powerful and useful, and we hope that you get some value out of better understanding it!