One app with multiple component.js: How to load sh

2019-05-26 21:42发布

We have a SAPUI5 app in where we define multiple components (i.e., multiple Component.js files) each in a respective subfolder as direct child of the application root. The following image shows the project structure:

Project layout

Component 1 is specified as com.test.component1, component 2 as com.test.component2. Shared code is located in root/shared and defined as dependencies in the controllers of each component.

shared/Utils.js:

sap.ui.define([], function () {
    "use strict";

    return {...};
};

component1/controller/Controller1.js:

sap.ui.define([
    "sap/ui/core/mvc/Controller",
    "test/shared/Utils"
], function (BaseController, Utils) {
    "use strict";
    // controller code

});

Running the index.html file locally (or in WebIDE) this all works, but the shared resources are not found when we try to integrate the different components into the Fiori Launchpad (it tries to load them from /resources/shared). We believe this has sth to do with the data-sap-ui-resourceroots='{"com.test": ""} defined for bootstrapping which is missing either in the Component.js or the manifest.json file.

What's the right way to register the resource path com/test/shared for the individual components?

标签: sapui5
2条回答
混吃等死
2楼-- · 2019-05-26 22:24

Using a Component/library for your utilities

The most obvious question I have here is: If you use the component concept anyways why is your shared code not a component as well. A Component does not necessarily have to have a UI, that's why there is a UIComponent and a simple Component to inherit from. You just load it as a dependency of component1/component2 like this:

... 
return Component.extend("com.test.Component1", {
  metadata: {
    name: "Component1",
    dependencies: {
      libs: [ "sap.m" ],
      components: [ "test.shared" ]
  },
...

If using a Component does not feel right for you, you could also package your utilities as a library. You might want to check out grunt-openui5 that helps you building one.

Loading external files without using Component/library concept

Anyways defining a resourceroot on bootstrap is similar to a call to

jQuery.sap.registerModulePath("test.shared", "/path/to/your/source");

You could register the module path of your shared modules in both of the components init. You will probably have to use an absolute path there since depending on the execution context (launchpad vs. standalone) the relative path might differ.

You could make the path 'relative' like this:

jQuery.sap.registerModulePath("test.shared", jQuery.sap.getModulePath("com.test.Component1") +"/../shared);

Furhtermore if you want the shared resources to also benefit from cache busting you might want to use this afterwards:

sap.ui.core.AppCacheBuster.register(jQuery.sap.getModulePath("test.shared"));
查看更多
混吃等死
3楼-- · 2019-05-26 22:31

One way to solve this is by defining the resourceRoots attribute in the application descriptor (manifest.json):

{
    ...
    "sap.ui5": {
        ...
        "resourceRoots" : {
            "com.test.shared": "./../shared"
        },
        ...
    }
}

This works despite what's written in the documentation:

Map of URL locations keyed by a resource name prefix; only relative paths inside the component are allowed and no ".." characters

查看更多
登录 后发表回答