ekj
ekj

Reputation: 1082

How to load an AMD Module from a Dojo Layer

In our application we use dojo for some widgets, including several custom widgets, and use the AMD format for several modules.

e.g.

define("foo.bar.module", ["dojo/_base/declare"], function(declare) {

   var module  = declare("foo.bar.module", [], {
      // Do Stuff
   }

   return module;
});

This works fine currently, since each module is requested individually. However, we have determined that using a dojo layer, to collapse this into one request would be a good optimisation.

The problem is, that we load the layer upfront, then attempt to require the modules defined in the layer, but the dojo loader cannot find the modules. Is there something in particular needed in the build profile to make this work? Some help, or links to documentation would be greatly appreciated.

Upvotes: 1

Views: 669

Answers (1)

C Snover
C Snover

Reputation: 18766

Module IDs are paths, not object identifiers. The first argument to define is just wrong; it should be foo/bar/module if it is going to exist. However, you should not ever provide the first string argument to define, as this breaks portability. You should also not provide the first string argument to declare unless you are intentionally trying to create constructors in the global scope.

In summary, your module definition should be:

define(["dojo/_base/declare"], function(declare) {

   var module = declare([], {
      // Do Stuff
   }

   return module;
});

Finally, there are two important things to note about built layers:

  1. Layers are just built modules that also contain additional modules. They should only be created from modules that already exist in your application prior to a build. For example if you have an app/main module that you use to load your entire app, that would be a good layer module. Creating a new app/layerA module just for a new layer would be wrong.
  2. The loader can’t know which modules a layer contains until the layer is loaded. If you build layer "a" with modules "a" "b" and "c", then require([ "a", "b", "c" ]), all three modules will be loaded as separate requests because the loader can’t know that "a" contains "b" and "c". In this case you have to always load "a" first, then load "b" and "c" afterwards, at which point they will just be loaded from the layer instead of separately.
  3. With the exception of the one layer that has boot: true in your build profile (dojo/dojo), layers must be loaded the same way as any other module—that is, using require or define, not by including a <script> tag for the layer module.

Upvotes: 3

Related Questions