Skip to content

Instantly share code, notes, and snippets.

@stdavis
Last active March 20, 2017 22:25
Show Gist options
  • Save stdavis/9347356 to your computer and use it in GitHub Desktop.
Save stdavis/9347356 to your computer and use it in GitHub Desktop.
Dojo 1.9.3 `customBoot` layer not interning widget templates properly.

I'm having a problem with my layer file not properly interning my widget template strings resulting in separate requests for each template file: requests

I have set up a simple example repo with an application containing two widgets (App & Widget). My goal is to build my entire application (JS & HTML) into one file. Here's my build profile:

var profile = {
    basePath: '../src/',
    action: 'release',
    optimize: 'closure',
    selectorEngine: 'acme',
    layers: {
        'dojo/dojo': {
            include: [
                'dojo/i18n',
                'app/run'
            ],
            customBase: true,
            boot: true
        }
    }
};

I've included app/run.js, app/main.js, and app/App.js in this Gist for reference.

There were no errors reported after running the build and I can find my widget in dojo.js.uncompressed.js:

...
'app/App':function(){
define([
    'dojo/_base/declare',

    'dijit/_WidgetBase',
    'dijit/_TemplatedMixin',
    'dijit/_WidgetsInTemplateMixin',

    'dojo/text!./templates/App.html',


    './Widget'
], function (
    declare,

    _WidgetBase,
    _TemplatedMixin,
    _WidgetsInTemplateMixin,

    template
    ) {
    return declare([_WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin], {
        templateString: template,
        widgetsInTemplate: true
    });
});
},
...

I also found my template strings at the very end of this same file:

...
},
'url:app/templates/App.html':"<div>\n    <h2>Hello Dojo Build System</h2>\n    <div data-dojo-type=\"app/Widget\"></div>\n</div>",
'url:app/templates/Widget.html':"<div>I'm a custom widget.</div>"}});
(function(){
	// must use this.require to make this work in node.js
	var require = this.require;
	// consume the cached dojo layer
	require({cache:{}});
	!require.async && require(["dojo"]);
	require.boot && require.apply(null, require.boot);
})();
...

This is how I load dojo in the build version of the app:

<script data-dojo-config='async: 1, deps: ["app/run"]' src='dojo/dojo.js'></script>

So why is my app still requesting my widget templates separately if they are already in the layer file? Any ideas would be greatly appreciated.

[Update: 3-6-14] Response from SitePen support:

Hi Scott,

The problem you are experiencing is caused by the way the loader consumes URL-based cached resources, like template strings. Because the app package is not defined at the time the cached templates are consumed by the loader, the URLs in the cache are transformed to ../app/templates/ (from app/templates/), as per the loader configuration at the time of the cache insertion. Once the configuration is changed and app is defined as a package later on (by app/run), the loader tries to retrieve templates from app/templates/, not ../app/templates/, and therefore they are no longer discovered in the module cache and are re-requested from the server.

The easiest solution is to make sure the app is defined as a package before your module cache is loaded. Since you have built everything into dojo.js, you would need to set this package configuration in your data-dojo-config attribute.

Please let us know if you have any other questions. Thanks!

I ended up remedying this situation by including some package names in the userConfig build profile property:

// build.profile.js
...
userConfig: {
    packages: ['app', 'dojo', 'dijit']
}
...
define([
'dojo/_base/declare',
'dijit/_WidgetBase',
'dijit/_TemplatedMixin',
'dijit/_WidgetsInTemplateMixin',
'dojo/text!./templates/App.html',
'./Widget'
], function (
declare,
_WidgetBase,
_TemplatedMixin,
_WidgetsInTemplateMixin,
template
) {
return declare([_WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin], {
templateString: template,
widgetsInTemplate: true
});
});
define([
'app/App',
'dojo/dom',
'dojo/domReady!'
], function(
App,
dom
) {
var app = new App({}, dom.byId('appDiv'));
app.startup();
});
(function () {
config = {
baseUrl: './',
packages: [
'dojo',
'dijit',
'app'
]
};
require(config, ['app']);
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment