Application Packaging Standard

Last updated 18-Mar-2019

Inclusion Rules

The rules explained here are mostly helpful when developing a rather complicated UI with inclusion of multiple custom JavaScript (JS) modules from various folders in the multilayer directory structure.

Folders and Namespaces

Regardless of the chosen user panel, each loaded JS module has an HTML parent file in an isolated IFrame. In UX1, the whole application UI is based on a single HTML file, ui/bootstrapApp.html. In 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 contained in the loaded APS package. All HTML and JS files must be in ui/ as well as in any folder or subfolder below 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" }

Path Definition Rules

The following rules are applicable to both methods used to include JS modules, require and define.

  1. 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 of the ways in the same list.

  2. 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 without it. In the latter case, they use a path started with ./ that is the location of their parent HTML file regardless of the module location.

  3. 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.
  4. 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 ../.

Once you know the general rules, let us consider the specifics of module inclusions in the UX1 environment and then continue with CP. This will help you understand the way to make inclusions in CP compatible with UX1.

UX1

In the namespace perspective, the main specific 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.

../../../../_images/path-markup2.png

The diagram illustrates the following rules you should follow to specify a path:

  • Use the module location (recommended):
    • ./modules/module1
    • ./test1
  • Use the app namespace:
    • app/modules/module3

CP

In 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:

  • Using a path relative to the HTML file location, for example:

    • ./modules/servers.js

    Note

    Name extension js is mandatory

  • Using explicitly 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 definition of the app namespace as well as other allowed and not allowed ways.

../../../../_images/path-markup1.png

The recommended way that makes inclusion of JS modules compatible with UX1 is based on the following steps:

  1. 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.

  2. 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.

  3. 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