The rules explained here are useful for developing a rather complicated UI with the inclusion of multiple custom JavaScript (JS) modules from various folders in the multilayer directory structure.
In this document:
Regardless of the chosen user panel, each loaded JS module has an HTML parent
file in an isolated IFrame. In the UX1, the whole application UI is based on a single HTML file, ui/bootstrapApp.html
.
In the CP, each source file declared in metadata is an HTML file. Once loaded into an IFrame, the HTML
file can include custom JS modules, which in turn can include other custom modules and so on.
The document root for the application UI is the ui/
folder in the loaded APS package. All HTML
and JS files must be in ui/
as well as in any folder or subfolder under ui/
.
All modules included this way use the location of the HTML file when they define other modules.
To simplify a path to JS modules, an HTML file can declare namespaces for certain locations in the hierarchy of folders. If the HTML file uses a namespace when including a JS module, it assigns this namespace to the module and thus isolates the module and all modules the latter includes from the HTML file location. In this case, the modules can use their own location when defining other modules. A module location consists of the namespace location and the path from it to the folder containing the module file.
For example, the predefined ui/bootstrapApp.html
file in UX1 declares the app
namespace
that the system uses to load all JS view source modules declared in metadata:
var url = window.location.href.split('/');
var dojoConfig = {
packages: [
{name: 'app', location: url.slice(0, -1).join('/')},
...
]
};
Key points in the above code:
The window.location.href
methods returns the path to the ui
folder on the server.
The app
namespace location is the ui/
folder.
For example, if you need to declare a custom namespace myNS
with the ui/ns/
location, declare it as:
{ name: 'myNS', location: url.slice(0, -1).join('/') + "/ns" }
The following rules are applicable to both methods used to include JS modules: require
and define
.
In an HTML file, you can require modules using the following ways:
Specify a path to the required JS module relative to the location of the HTML file.
In this case, you must specify the module name including the js
extension, for example:
require([
"./modules/servers.js",
"./test/server.new-1.js",
...
],...
);
Note
Name extension js
is required.
Define a custom namespace, for example myNS
, and specify a path to the required JS module
relative to the location of the namespace, for example:
require([
"myNS/modules/servers",
"myNS/test/server.new-1",
...
],...
);
Note
Name extension js
is not allowed.
The require
or define
method can use both ways in the same list.
If a JS module and all its parent JS modules were included without using a namespace, it can define other
JS modules the same way as they are required in the parent HTML file, that is using a namespace or not.
In the latter case, they use a path starting with ./
that is the location of their parent HTML file regardless
of the module location.
Once you include a JS module through a namespace, you isolate it from the location of the parent HTML file. This also isolates all JS modules defined by the module. All these modules define other JS modules only using their own location or using a name space, as in the following example:
define([
"./servers",
"app/test/server.new-1",
...
],...
);
In this example:
The path to servers.js
is relative to the location of the current module. For example,
if the current module is located at <namespace>/modules/
, it defines the <namespace>/modules/servers.js
file.
The path to server.new-1.js
is relative to the location of the app
namespace specified
in the parent HTML file.
When you define a path relative to the current location, always start this path with ./
.
Even if you need to specify a folder one level higher, use ./../
instead of ../
.
Now you know the general rules, let us consider the specifics of module inclusions in the UX1 environment and then continue with the CP. This will help you understand how to make inclusions in the CP compatible with the UX1.
In the namespace perspective, the main idea of UX1 is that the predefined app
namespace isolates all
JS modules from the location of their parent HTML file that is bootstrapApp.html
.
Warning
Due to namespace isolation from the parent HTML file, it is not allowed to use the js
name extension
in the define
method.
The diagram illustrates the rules to follow to specify a path:
Use the module location (recommended):
./modules/module1
./test1
Use the app
namespace:
app/modules/module3
In the CP, each view source declared in metadata is an HTML file. An HTML file allows you to define custom namespaces and use two different ways to specify a path to a required JS module:
Use a path relative to the HTML file location, for example:
./modules/servers.js
Note
Name extension js
is mandatory.
Explicitly use a path relative to a namespace, that is:
app/modules/servers
Note
Name extension js
is not allowed.
The diagram below illustrates the recommended way of module inclusion based on the definition of the app
namespace as well as other allowed and not allowed ways.
The recommended way of making inclusion of JS modules compatible with UX1 is based on the following steps:
In the HTML file, define the app
name space the same way as it is defined in the bootstrapApp.html
file
used in UX1.
Warning
Although other namespaces are also allowed, their use may lead to incompatibility issues if the application is integrated with other applications.
From the HTML view source, call the top-level JS modules using the app
namespace explicitly, for example:
app/module3
This places all JS modules into the app
namespace similar to what UX1 does automatically.
In all JS modules, define other modules using their own location (implicit use of the app
namespace)
as recommended for UX1, for example:
./modules/module31
./test31
From an HTML file, it is possible to require a JS module using the path relative to the HTML file location, for example:
./module2.js
It is possible to use the same way in JS modules required by the HTML file and defined by other modules in a hierarchical manner, unless a namespace isolates them from the parent HTML file, for example:
./modules/module21.js
./test21.js