Opened 10 years ago
Closed 10 years ago
#15856 closed defect (fixed)
boot: true for a layer leaves out the text for that layer
Reported by: | ben hockey | Owned by: | Rawld Gill |
---|---|---|---|
Priority: | blocker | Milestone: | 1.8.1 |
Component: | BuildSystem | Version: | 1.8.0 |
Keywords: | Cc: | ||
Blocked By: | Blocking: |
Description
if i try to build a layer (besides dojo/dojo) with boot: true
the text for that layer is not included.
i can see that the call to writeAmd.getLayerText
at http://bugs.dojotoolkit.org/browser/dojo/util/trunk/build/transforms/writeDojo.js?rev=29358#L152 does not match the signature of getLayerText
at http://bugs.dojotoolkit.org/browser/dojo/util/trunk/build/transforms/writeAmd.js?rev=28477#L182
Attachments (2)
Change History (16)
comment:1 Changed 10 years ago by
comment:2 Changed 10 years ago by
Just to note I think this is the same issue I'm facing with #15814 trying to build a single boot layer (which isn't dojo).
comment:4 Changed 10 years ago by
Milestone: | tbd → 1.8.1 |
---|
comment:14 Changed 10 years ago by
Resolution: | → fixed |
---|---|
Status: | new → closed |
fixed and backported to 1.7 and 1.8
comment:15 Changed 10 years ago by
Resolution: | fixed |
---|---|
Status: | closed → reopened |
this is not quite right. i don't get the same output when i use dojo.js as a boot layer that includes another layer compared to making a layer bootable.
if you build a layer into dojo.js you get the equivalent of this (loader, layer, boot)
(function (userConfig, defaultConfig) { // a few hundred lines of loader })(this.dojoConfig || this.djConfig || this.require || {}, userConfig); require({ cache: { // layer contents }); /* dojoBootText */ (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); })();
if you make a layer bootable you get this (loader, boot, layer)
(function (userConfig, defaultConfig) { // a few hundred lines of loader })(this.dojoConfig || this.djConfig || this.require || {}, userConfig); /* dojoBootText */ (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); })(); require({ cache: { // layer contents });
this isn't right because the cache hasn't been primed before the boot tries to potentially consume something that is in the cache.
comment:16 Changed 10 years ago by
Priority: | undecided → blocker |
---|
comment:17 Changed 10 years ago by
In addition to the issue described by neonstalwart at comment 15, there is another problem.
The layer for a boot resource must be composed slightly differently than a normal boot layer because of a subtle interaction with i18n backcompat. Recall that, owing to backcompat, a layer may be constructed that preloads localizations. This task is accomplished with a *now
directive in the cache. Further recall that a normal layer includes a cache of zero-to-many modules followed by a single AMD define()
application that defines the layer module. When such a layer is evaluated during boot--that is, when nothing, including dojo base in general, and i18n in particular, has been instantiated--the *now
directive will cause the i18n module and its dependency graph to be instantiated. This causes a series of AMD define()
applications. So the first time the loader consumes a define()
application it is presented with two anonymous defines (the layer define and the first define consequent to resolving the *now
directive. This causes the load to fail.
The simple workaround is to specify an empty localeList in the build profile, thereby resulting in no preloading of localizations, thereby resulting in no *now directive.
The proper fix is that boot layers should not explicitly define any modules. Instead use one of the following methods to start loading modules:
- provide a loader deps value
- provide a layer bootText value
- provide a custom dojoBootText value
- add a script element after the script element that injects the bootable layer and use require()
Changed 10 years ago by
Attachment: | demo-calendar-boot-layer.profile.js added |
---|
demo profile to build a boot-layer for dijit/tests/CalendarLite demo
Changed 10 years ago by
Attachment: | CalendarLite.html added |
---|
modifications to dijit/tests/CalendarLite.html to demo a boot layer
comment:19 Changed 10 years ago by
I've attached a couple of files to demo the layer boot functionality based on the dijit/tests/CalendarLite.html test. To see this work:
- Put the profile in util/buildscripts/profiles
- Replace dijit/tests/CalendarLite.html with the file provided.
- Run the build command...
~/dev/dtk/util/buildscripts:./build.sh -p demo-calendar-boot-layer -r --copyTests 1 --layerOptimize 0 --optimize 0
(of course your paths may be different)
- Navigate your browser to the built html in
path/to/demo-calendar-boot-layer/dijit/tests/CalendarLite.html
You should see a nicely optimized load. You may also edit the built file and change async to truthy and see it load asynchronously...but there's not much difference after building.
it looks like r28456 changed the signature but writeDojo was not updated to match.