Opened 6 years ago

Last modified 3 years ago

#17440 new defect

dojo/has!condition sometimes executes before dojoConfig processed

Reported by: bill Owned by:
Priority: undecided Milestone: 1.15
Component: Core Version: 1.9.1
Keywords: Cc: Clement Mathieu
Blocked By: Blocking:

Description

dojo/_base/config.js parses that djConfig global variable, adding the specified has flags in a case like:

djConfig = {
   has : { "dojo-bidi" : true }
};

However, a module dependency like dojo/has!dojo-bidi?myModule can execute before the code in dojo/_base/config.js has executed, thus returning null instead of loading the specified module. Actually there's no guarantee that the code in dojo/_base/config will load at all. At least when using RequireJS as a loader; I haven't looked into what dojo.js does.

A workaround is to define all of our modules to explicitly load dojo/_base/config first:

require(["dojo/_base/config"], function(){
   define([
       ...
       "dojo/has!dojo-bidi?myModule",

However that's pretty onerous and I'm not sure if it would work with the builder.

Change History (7)

comment:1 Changed 6 years ago by ben hockey

is it naive to think that adding dojo/_base/config as a dependency to dojo/has will fix this? i haven't looked into it but it sounds like that would do it.

comment:2 Changed 6 years ago by Bryan Forbes

dojo/_base/config already depends on dojo/has, so setting up the reverse dependency would give us a circular dependency.

comment:3 Changed 6 years ago by bill

Right, it's a true circular dependency. I thought about just putting all the code from config.js into has.js, but config.js has a comment indicating that users may override the module in a build:

By defining user configuration as a module value, an entire configuration can be specified in a build, thereby eliminating the need for sniffing and or explicitly setting in the global variable dojoConfig. Also, when multiple instances of dojo exist in a single application, each will necessarily be located at an unique absolute module identifier as given by the package configuration. Implementing configuration as a module allows for specifying unique, per-instance configurations.

comment:4 Changed 6 years ago by cjolif

Cc: Clement Mathieu added

comment:5 Changed 6 years ago by bill

Perhaps we should stop depending on dojoConfig altogether and instead use standard AMD module configuration setting. As documented on stack overflow (and probably other better places), we should be able to do something like:

var require = {
    config: {
         'dojo/has': {
              'dojo-bidi': true
         }
    }
};

The code in dojo/has.js is actually already setup to handle this. Unfortunately it's inside an if() block that doesn't normally execute:

if(!has("dojo-has-api")){
        ...
        cache = (module.config && module.config()) || {};

The code that runs instead is in dojo.js:

hasCache = has.cache = defaultConfig.hasCache;

Actually, I guess if we just fix dojo.js so that hasCache is populated from userConfig in addition to defaultConfig, things should start working.

comment:6 Changed 4 years ago by dylan

Milestone: tbd1.12

comment:7 Changed 3 years ago by dylan

Milestone: 1.131.15

Ticket planning... move current 1.13 tickets out to 1.15 to make it easier to move tickets into the 1.13 milestone.

Note: See TracTickets for help on using tickets.