The following list contains possible reasons why your module does not load. To see how it is done correctly, see Best Practices for Loading Modules - How to Define Modules.
sap.ui.defineIf you explicitly give the module name in sap.ui.define, you
introduce additional complexity to the project structure which may cause
inconcistencies and clashing module names. This problem is difficult to detect
and can easily and proactively be avoided by omitting the module name in
sap.ui.define.
The following example shows how it must not be done: The library file
structure of myLib does not fit the module name. If there is
another module named MyModule in the myLib
library, the module would be hard to address. If you use an unnamed module
instead, the module names would reflect the library file structure. By this, you
reduce the probability of module name conflicts. In general, when addressing UI5
modules, make sure you separate all parts of the module's name with slashes
instead of dots, for example myLib/MyModule instead of
myLib.MyModule.
myLib/myAdditionalPathSegment/MyModule.js
// CAUTION: BAD EXAMPLE - DON'T DO THIS
sap.ui.define("myLib.MyModule", [], function(){
...
});sap.ui.define calls with unnamed
modulesIf you have more than one sap.ui.define call in a JavaScript file, the
module loader does not know which definition actually represents the module. As
there is no scenario that requires multiple module definitions in one file and
in order to comply with the AMD specification (see https://github.com/amdjs/amdjs-api/wiki/AMD), the
async variant of the SAPUI5 module
loader does not tolerate multiple definitions anymore and throws an
error.
Example: The myModule module is defined
twice. This was most probably done by accident. To resolve this, the two module
definitions have to be split into two separate modules.
myModule.js
// BAD EXAMPLE - DON'T DO THIS
sap.ui.define([], function(){
...
});
sap.ui.define([], function(){
...
});sap.ui.defineConditional module definitions should not be used because of the following reasons:
The modules cannot be required with parameters because the check conditions are related to globals.
The export value is not consistent. This makes it difficult to consume the module.
The module dependencies are unclear. This prevents an efficient module bundling.
Example: The export value of myModule
depends on the global myProperty property. In this case, it
makes sense to split the two definitions into separate files for example into
the two variants myModuleA and myModuleB.
Another module can then make the required myProperty check and
require the variant of myModule via
sap.ui.require.
myModule.js
// BAD EXAMPLE - DON'T DO THIS
if (myProperty){
sap.ui.define([], function(){
...
});
else {
sap.ui.define([], function(){
...
});
}Using deprecated APIs is not recommended and mixing old and new loader APIs is even worse: If the synchronicity has changed between older and newer APIs, mixing them will cause timing-related issues as well as general inconsistencies.
Example: The namespace myLib.myModule is
registered through the jQuery.sap.declare call. Besides
actually defining the module export value, the subsequent
sap.ui.define call does the same registration. So, the
jQuery.sap.declare in this example is unnecessary and must
be omitted in this example.
myLib/MyModule.js
// BAD EXAMPLE - DON'T DO THIS
jQuery.sap.declare("myLib.myModule");
sap.ui.define([], function(){
...
});sap.ui.require instead of
sap.ui.define on the top levelAlthough the API signature for sap.ui.define and
sap.ui.require looks similar, you must use the
sap.ui.define API to define a reusable JavaScript object
(that is, a module). Note the following differences between
sap.ui.require and sap.ui.define:
|
Action |
sap.ui.require |
sap.ui.define |
|---|---|---|
|
Value export |
Not possible |
The callback function defines an export to provide functionality to other modules. |
|
Module name registration |
Not possible |
The module name is registered at the loader registry and can be used to address the module. |
|
Relative dependencies |
This is not possible, because no module name is registered and a reference point is missing. |
Can be used. |
|
Execution order |
Dependent modules can be executed before the
|
The dependent modules are waiting for the module callback execution to be finished. |
Example: The file for module C has one top-level
sap.ui.require instead of a top-level
sap.ui.define call. The module callback evaluation order
starts with module B, because it has no dependencies. Afterwards, the framework
can execute module A or module C, because the intended module C is not a module
from the module loader perspective. Furthermore, the undefined export value of
module C will most probably lead to errors in module A. If module C is defined
correctly via a top-level sap.ui.define call, the module
callback execution order is clear: B - C - A.
It is unclear how modules that are defined via inline scripts can by addresses by other modules. Therefore, the inline scripts must be omitted.
Example: Module A is defined after bootstrapping UI5 and before the actual app is started. As the module is not addressable, the module definition must be moved to a separate file.
startMyApp.html
<!-- BAD EXAMPLE - DON'T DO THIS -->
<html>
...
<script>
//Boot UI5
</script>
<script>
//Definition for Module A
sap.ui.define(function(){
...
});
</script>
<script>
// Start UI5 Application
</script>
...
</html>Never do a synchronous access to the export of a module definition because the module definition could be done asynchronously. Never rely on the synchronicity of a module definition, even if a module has no dependencies.
Example: The sap.ui.define call for the
myModule module is made and the export value is
synchronously used by creating a new object of that export. Although this may
work in some scenarios, never do it this way, because it is unclear whether the
module definition is already done. Instead, use the export of
myModule in a separate module with a correctly maintained
dependency to the myModule module.
myLib/MyModule.js
// BAD EXAMPLE - DON'T DO THIS
sap.ui.define([], function(){
...
});
...
var oMyModule = new myLib.MyModule();
...For more information, see the API Reference for sap.ui.define - Asynchronuous Contract.
Similar to the synchronous access of a module's export value, you also must omit the synchronous probing for modules defined in the same browser task.
Example: The sap.ui.define call for the
myModule module is made and is synchronously checked by
probing through calling sap.ui.require. Instead, the probing
for myModule must be done in a separate module with a correctly
maintained dependency to myModule.
myLib/MyModule.js
// BAD EXAMPLE - DON'T DO THIS
sap.ui.define([], function(){
...
});
var MyModule = sap.ui.require('myLib/MyModule');The following examples show how you should not address a module. To see how it is done correctly, see Best Practices for Loading Modules - How to Address Modules.
Addressing a module inconsistently can cause various side-effects. If the server
is not case sensitive, for example, the same resource can be addressed with URLs
that differ only in case sensitivity. Besides that, it is bad from a performance
perspective if the same resource is loaded twice and the same module is defined
twice. This is similar to the example for multiple definitions above: multiple
definitions of the same module can cause several issues, such as failing checks
of instanceof.
Example: If we assume a server that is not
case-sensitive, the sap.m library's Button
control is loaded and evaluated twice.
myView.xml
<!-- BAD EXAMPLE - DON'T DO THIS -->
<mvc:View xmlns:mvc="sap.ui.core.mvc" xmlns:m="sap.m">
...
<m:Button></m:Button>
<m:button></m:button>
...
</mvc:View>myModule.js
...
// BAD EXAMPLE - DON'T DO THIS
sap.ui.require(['sap/m/button'], function(){
...
});
sap.ui.require(['sap/m/Button'], function(){
...
});
...When you load modules manually, the module loader cannot know how the module shall be named. Therefore, UI5 modules must always be loaded and evaluated via the UI5 module loader APIs.
Example: The myModule module is loaded via a script tag.
Instead, use a sap.ui.require call to loading the module.
startMyApp.js
<html>
...
<script src="https://myhost/mypath/myModule.js"></script>
...
</html>When you use cyclic dependencies in the project structure, the module dependencies cannot be resolved. The UI5 module load detects the cycle and returns an undefined value instead of the correct module export.
As an exception, in specific scenarios, you may make the involved modules robust enough to handle undefined module exports at module callback execution time and use the export value via probing later. However, if you use the async variant of the loader, all modules that belong to a cycle must be able to handle undefined exports.
To see how to set up a correct project structure, see Best Practices for Loading Modules - How to Structure a Project.
Example: All modules have exactly one dependency, which cannot be resolved correctly.

Solution 1 – Resolved cycle: The following figure shows how the cycle can be resolved by moving the functionality of module A, which is used by module B, to a separate module (module A2). In general, resolving cyclic dependencies can require a larger refactoring of all involved modules, especially when multiple cycles have to be resolved.

Solution 2 – Probing modules: In the example given in the following figure, the cycle is not resolved, but the involved modules do not access the dependent modules directly when the module callback is executed. They access them later via probing.
