Opened 8 years ago

Closed 8 years ago

Last modified 8 years ago

#13147 closed defect (invalid)

Parser not called in page using layers created by the new 1.7 build system [ccla]

Reported by: Eric Durocher Owned by: Rawld Gill
Priority: high Milestone: 1.7
Component: BuildSystem Version:
Keywords: Cc:
Blocked By: Blocking:

Description

I am trying to create a layer file containing the code of a custom dijit (based on GFX). I am using the new 1.7 build script for this. The layer seems to be created correctly, but when I use it in an HTML page, the Dojo parser is not called.

Note that I am using dependency layers to exclude and dojo/dojox code from my layer. This was previously broken as reported here: http://bugs.dojotoolkit.org/ticket/13062 , but this has been fixed since then (thanks!).

Note also that I am using Dojo 1.6-style require() calls in my widget and in my page.

I am attaching a sample module to reproduce the parser problem:

  • put the testModule directory in the same parent dir as dojo/dijit/dojox
  • run the build script using test.profile.js:
build.bat profile=../../testModule/test.profile.js action=release
  • run the test.html page from the resulting release directory -> the widget declared in the markup is not created.

(the test page works fine when run from the toplevel testModule, where the layer file is not present).

Attachments (1)

testModule.zip (1.9 KB) - added by Eric Durocher 8 years ago.

Download all attachments as: .zip

Change History (14)

Changed 8 years ago by Eric Durocher

Attachment: testModule.zip added

comment:1 Changed 8 years ago by Rawld Gill

Status: newassigned

comment:2 Changed 8 years ago by Rawld Gill

I don't see a widget declared in the markup in the html file that's in the archive. Also, the file in the archive is strangely named...did you include the correct file.

I tried to duplicate the report and was unable. Could you please recheck the archive to make sure it is complete.

Thanks!

comment:3 Changed 8 years ago by Eric Durocher

I checked the archive, it seems OK... Here are more explanations.

The archive contains 3 files in a testModule directory:

  • MyGfxWidget?.js: contains the code of a simple widget (that uses dojox.gfx)
  • test.html: a test page that creates a MyGfxWidget? instance by markup (see the 'mywidget' div)
  • test.profile.js: the build tool profile used to create the layer file
  1. The testModule dir must be extracted at the same level as dojo/dijit/dojox.

If you launch the test.html page, you should see a blue square (displayed by the MyGfxWidget? instance), and the following text below it in green: Test OK: my widget = [Widget testModule.MyGfxWidget?, mywidget]

  1. Run the build script as in the description.
  1. Copy the resulting layer file release/dojo/testModule/testModule_layer.js to the original testModule directory and run the test.html page. Now, test.html finds the layer file and loads it. The blue square is not displayed, and the following message is displayed in red:

Test KO: my widget was not created

(Variant of step 3: you can launch test.html directly from release/dojo/testModule, so it will use the dojo.js resulting from the build. The result is the same (failure). Note that our real use case is closer to 3. as I described it, since our layer files are meant to be used either with a non-built dojo or with a built dojo - we do not want to force either one or the other for our users, and this used to work fine up to 1.6).

This means that the MyGfxWidget? that should have been created by the parser when parsing the 'mywidget' div with the dojoType 'testModule.MyGfxWidget?' has not been created.

The problems seems to be that the parser is never called (I added console logs and debugger calls to parser.js and they are never hit).

I have verified that the testModule.MyGfxWidget? class does exist, and if I create the widget programmatically.

Hope you can reproduce now, otherwise please tell me, thanks!

comment:4 Changed 8 years ago by tissandier

The strange line :

define([], 1);

that appears at the end of the testModule_layer.js seems to break the sample.

If you remove this line, everything seems to work fine.

comment:5 Changed 8 years ago by Chris Mitchell

Priority: normalhigh

would like to get this in beta if possible

comment:6 Changed 8 years ago by Rawld Gill

Resolution: invalid
Status: assignedclosed

The loader and builder are operating correctly.

The problem is the script injection of ./testModule_layer.js

It is normally illegal to load AMD modules with a script element. As of v1.7+ all built resources (this includes layers) are, in fact, AMD modules. (Of course this doesn't apply to the loader dojo.js which happens to include the dojo layer in a built version). The reason behind this limitation is that, by default, all built AMD resources are anonymous modules. Therefore, when the loader is presented an anonymous module definition that it did not ask for, it is impossible to determine the module id to which the definition applies.

There are two solutions. The easiest and proper solution is to remove the script injection line and replace it with

dojo.require("testModule.testModule_layer");

in the next script element just before the line

dojo.require("dojo.parser");

The second, though less desirable solution is to set the build switch insertAbsMids to truthy. For example, try the following build command:

 ./build.sh profile=../../testModule/test.profile.js action=release insertAbsMids=1

This causes all modules to include an absolute module id, and therefore not be anonymous modules. You may script inject such modules.

Tested both solutions and they both work for me.

Sorry for the mixup on the attached archive; it must have downloaded improperly when I tried it the first time.

comment:7 Changed 8 years ago by Eric Durocher

Yes, that works better, thanks!

I have still a problem though: everything runs as expected if I use the dojo.js resulting from the build: the layer is loaded correctly, and the MyGfxWidget?.js source file is not loaded. Good. But If I use testModule_layer.js with a "source" dojo, then MyGfxWidget?.js is still loaded (although the layer file containing the class definition was already loaded). As I explained, our layer files must be usable either with a dojo build or with dojo sources.

To reproduce, just copy the testModule_layer.js to the toplevel testModule directory and launch test.html from there. I tried this with the two solutions that you propose, the result is the same: MyGfxWidget?.js is loaded in both cases (visible in Firebug). Any idea why this happens?

comment:8 Changed 8 years ago by Eric Durocher

I investigated again and found that if I add a 'packages' definition to my djConfig then all works fine. For example, with my testModule sample:

var djConfig = {

parseOnLoad:true, packages: [ { name: 'testModule', location: '../testModule' } ]

}

Now MyGfxWidget?.js is not reloaded any more even if I use the source dojo.js.

The reason it worked with the dojo build is that this declaration is included in the default config.

Of course it would be nice if this was not necessary... This looks a lot like a default case, so I wonder why this would be necessary. Do you think this could be fixed?

comment:9 Changed 8 years ago by Rawld Gill

Resolution: invalid
Status: closedreopened

Need to investigate implications of previous comment by edurocher; reopening.

comment:10 Changed 8 years ago by Rawld Gill

Status: reopenednew

comment:11 Changed 8 years ago by Rawld Gill

Status: newassigned

comment:12 in reply to:  8 Changed 8 years ago by Rawld Gill

Priority: highnormal
Resolution: invalid
Status: assignedclosed

Replying to edurocher:

I investigated again and found that if I add a 'packages' definition to my djConfig then all works fine. [snip]

Nice detective work!

I considered making the loader automatically configure any unknown top-level-module as a package. Unfortunately, it is impossible to do that because a package maps the module with the id equal to the package name as given by the package.main config variable. So, if every top-level module was a package, then it would be impossible to load the module "someModuleName" (notice a single segment). While I certainly agree this would be odd, it would also work in v1.6- so we must support in 1.7+.

The best soln to your problem is using the config as you discovered for yourself (I would recommend that in any event). fyi--djConfig is deprecated; you might want to use dojoConfig.

comment:13 Changed 8 years ago by Eric Durocher

Thanks for the answer. OK, I can live with that. Is all this documented somewhere? Or is that still in your plans?

Btw I have to stick to djConfig since we must support earlier Dojos too...

Note: See TracTickets for help on using tickets.