3

This is my distillation of a build failure I was getting. The symptom was that when optimizing with shrinksafe my build would fail with the error:

 [exec] js: "<eval'ed string>#1(Function)#1(eval)", line 127: uncaught JavaScript runtime exception: TypeError: Cannot read property "1" from null
 [exec]     at <eval'ed string>#1(Function)#1(eval):127
 [exec]     at <eval'ed string>#1(Function)#1(eval):163

If my code pulled in its nls files with a pattern such as

"dojo/i18n!./nls/MyResource"

However, this construct is common throughout much dojo code, which builds cleanly. So I experimented by copying some dojo code into my module and discovered that if the nls resource was loaded into the dojo/dojo layer then my layers built correctly, if I loaded the same nls resource in my own layer then we get the failure above.

So cutting this right down to a minimal case, I copied dijit/form/_ComboBoxMenuMixin.js to my own module and also the corresponding nls resources.

I have three test cases, one works, the other two give the failure above.

My questions:

Seems like I need to include my own nls resources in the "dojo/dojo" layer, it must be precisely this layer. Surely this can't be right? What are my alternatives?

Working profile:

layers: {
"dojo/dojo" : {
    customBase: false,
    include: [         
              "modules/nls/ComboBox",
    ],
    exclude: []
},
"MyLayer" : {
    customBase: false,
    include: [                            
              "modules/ComboCopy",                      
    ],
    exclude: []
},
}

Failure: nls in same layer

layers: {
"dojo/dojo" : {
    customBase: false,
    include: [         

    ],
    exclude: []
},
"MyLayer" : {
    customBase: false,
    include: [   
                  "modules/nls/ComboBox",                         
              "modules/ComboCopy",                      
    ],
    exclude: []
},
}

failure, load nls in a different layer name

 layers: {
"myNlsLayer" : {
    customBase: false,
    include: [         
              "modules/nls/ComboBox",
    ],
    exclude: []
},
"MyLayer" : {
    customBase: false,
    include: [                            
              "modules/ComboCopy",                      
    ],
    exclude: []
},
Tobias Kienzler
  • 25,759
  • 22
  • 127
  • 221
djna
  • 54,992
  • 14
  • 74
  • 117

1 Answers1

8

NLS modules shouldn’t be specified as being included in layers. When your layer modules are processed, all of their NLS dependencies will be automatically bundled into related layers with a filename suffix corresponding to each possible locale. e.g. for a layer MyLayer.js you will also get a MyLayer_en-us.js, MyLayer_es-es.js, etc. This enables visitors to load only the language bundle they need.

If you want to forcibly include a particular locale within your layers (for example, because you know all your visitors only speak English), you can use the includeLocales property to do so:

layers: {
    MyLayer: {
        includeLocales: [ 'en-us' ]
    }
}

Whilst your first profile may appear to work, it is unlikely that it is actually doing what you expect, which is probably why ShrinkSafe is crashing.

A couple other notes:

  1. ShrinkSafe is deprecated; you should really use Closure Compiler or UglifyJS instead.
  2. The customBase flag applies only to the main dojo/dojo layer and means “do not automatically include the default Dojo Base modules”. You do not need to apply it to your other layers.
C Snover
  • 17,908
  • 5
  • 29
  • 39