cancel
Showing results for 
Search instead for 
Did you mean: 

HowTo use 3rd party lib with content-security-policy omitting eval()

The problem ist described here: https://stackoverflow.com/questions/74959323/how-to-make-ui5-content-compatible-with-the-flp-setting...

We have developed some UI5 components, that use 3rd party libs (e.g. Excel File handling or jsrasign). During build we see the Warning: lbt:bundle:Builder Module ..../lib/xlsx.full.min.js requires top level scope and can only be embedded as a string (requires 'eval')

This is normally no problem but when using this component in a Fiori Launchpad setting "Asynchronous Module Loading" the component is not loaded because of the content security policy

Is there a setting for a UI5 component that allows using such 3rd party libs even with CSP unsave-eval switched off?

Or is there another way to embed a 3rd party lib other than we do currently?

sap.ui.define([ ...., "../lib/xlsx.full.min", ...], function (.....) {...var encodedCol = XLSX.utils.encode_col(col); // XLSX comes from the lib
.......}Regards Michael
boghyon
Product and Topic Expert
Product and Topic Expert
0 Kudos

Hi, I'm the author of the linked Q&A on Stack Overflow. Does the 2nd column " Making UI5 content more CSP-compliant" not help? Let me know if something is not clear.

0 Kudos

Unfortunately, the 2nd column doesn't help in that case (or I don't quite understand). Because the 3rd party libs are as they are I need a way to either include them differently or define somewhere that eval() is allowed for this module.

Whenever a controller is loaded that includes one of the libs with sap.ui.define the runtime error comes up that eval() is not allowed.

View Entire Topic
boghyon
Product and Topic Expert
Product and Topic Expert

The answer in the linked Q&A mentions the SheetJS (xlsx):

> "Some third party libraries (e.g. SheetJS) have to define a variable globally [...]. In this case, exclude such third party libraries from the bundle."

I.e. in the UI5 Tooling project configuration file (typically in `ui5.yaml`, `ui5-deploy.yaml`, etc.):

builder:
  componentPreload:
    excludes:
    - "my/app/libs/xlsx.full.min.js"

Additionally, in general, a `shim` with `amd: true` must be defined prior to requiring the third party module that exports its global name and supports AMD at the same time (here: "my/app/libs/xlsx.full.min"). This can be done with the API `sap.ui.loader.config` e.g. in Component.js before `sap.ui.define`:

sap.ui.loader.config({
  shim: {
    "my/app/libs/xlsx.full.min": {
      amd: true, // When being required, UI5 temporarily disables the global `define` to allow the third party lib register its global name to `globalThis` or `window`.
      exports: "XLSX", // name of the global variable under which SheetJS exports its module value
    },
  },
});

Then finally in the module that requires "my/app/libs/xlsx.full.min":

sap.ui.define([
  // ...,
  "my/app/libs/xlsx.full.min", // <-- require the third party
], (/*...,*/XLSX) => { // <-- use the required module value instead of the global name.
  "use strict";
  // ...
});

This is documented in the sap.ui.define section "Third Party Modules":

> "[...] Although third party modules don't use UI5 APIs, they still can be listed as dependencies in a sap.ui.define call. They will be requested and executed like UI5 modules, but to make their exports available, so called shims have to be defined. [...]"

While it's not directly related to the "Asynchronous Module Loading" topic, declaring the dependency properly and using the required module value instead of global names safeguards the application from other AMD loaders in the same global scope. E.g. the "sap.viz" lib currently loads the standard AMD loader with which the current AMD-like loader from SAPUI5 is not compatible. If the "sap.viz" lib loads prior to SheetJS, the global variable XLSX will be undefined. As shown above with `sap.ui.loader.config`, applications should not rely on global variables but include third parties in the dependency list, and use the required module values instead.