Search code examples
sapui5amd

How do I detect cyclic dependent modules in UI5?


Given:

sap.ui.define([ // in my/ModuleA.js
  // "...",
  "./ModuleB",
], function (/*...,*/ModuleB) {
  // ...             ModuleB is undefined here
  return/*...*/;
});
sap.ui.define([ // in my/ModuleB.js
  // "...",
  "./ModuleA"
], function (/*...,*/ModuleA) {
  // ...             ModuleA is undefined here
  return/*...*/;
});

After building and running the application, inspecting the generated Component-preload.js shows that the ModuleB parameter in my/ModuleA.js or the ModuleA parameter in my/ModuleB.js is undefined.

It's easy to detect such cyclic dependencies in a small project. But how can I detect such flaws easily if there are multiple modules and their dependencies are complex?


Solution

    1. Open the browser console and make sure to enable viewing all "Verbose" logs.

    2. Run the application with the following UI5 config parameter sap-ui-xx-debugModuleLoading with the value true.

    3. In the log, filter by "cycle detected".

      cycle detected between 'my/ModuleB.js' and 'my/ModuleA.js', returning undefined for 'my/ModuleA.js' - sap.ui.ModuleSystem
      cycle detected between 'my/ModuleA.js' and 'my/ModuleB.js', returning undefined for 'my/ModuleB.js' - sap.ui.ModuleSystem

      And since e7daa82 (UI5 1.121), an actual error is logged with the message:

      Dependency cycle detected: [...] sap.ui.ModuleSystem.

    In UI5 library development

    Initializing your library with the API initLibrary from the required "sap/ui/core/Core" module is allowed only since UI5 1.91 (commit: d83868e). In lower UI5 versions, the "sap/ui/core/Core" module might resolve to undefined if required early during the bootstrap process due to a cyclic dependency.

    Resolution

    • Double-check if the dependency to the ModuleA or ModuleB is really necessary in the module definition itself. If it's not used, remove the dependency from the list.
    • Follow the Best Practices for Loading Modules and its child topics from the documentation.

    Related Q&A on resolving the error "Modules that use an anonymous define() call must be loaded with a require() call".