#SAPUI5#Fiori#Async#CSP

sap.ui.define y carga asíncrona: el fin de las variables globales en UI5

AMD, dependencias explícitas, async:true y ComponentSupport en lugar de scripts inline. Por qué sap.ui.require sustituye a los globales y cómo esto encaja con la CSP. Con código real de bootstrap.

Por Logali Tech 2 min de lectura

Si abres una app UI5 antigua verás sap.ui.getCore() colgando de una variable global, scripts que se cargan en orden frágil y un onInit que asume que todo ya está en memoria. El modelo moderno de UI5 es asíncrono y modular: cada fichero declara sus dependencias con sap.ui.define, el framework las resuelve y solo entonces ejecuta tu código. Nada de globales, nada de orden implícito.

sap.ui.define: AMD para UI5

sap.ui.define es la implementación AMD de UI5. Recibe un array de rutas de módulos y una función factoría cuyos argumentos son esos módulos ya cargados, en orden. Ese es el contrato.

sap.ui.define([
    "sap/ui/core/mvc/Controller",
    "sap/m/MessageToast",
    "sap/ui/model/json/JSONModel"
],
function (Controller, MessageToast, JSONModel) {
    "use strict";
    return Controller.extend("logaligroup.SAPUI5.controller.App", {
        onInit: function () {
            this.getView().setModel(new JSONModel({ recipient: { name: "World" } }));
        }
    });
});

Tres cosas que este patrón te garantiza:

  1. Dependencias explícitas: lees el array y sabes exactamente de qué depende el fichero. No hay imports ocultos.
  2. Sin globales: Controller, MessageToast y JSONModel son parámetros locales. No contaminan window.
  3. Orden garantizado: la factoría no corre hasta que los tres módulos están cargados. Se acabaron los “undefined is not a function” por carga fuera de orden.
flowchart TB
 D["sap.ui.define lista de dependencias"] --> L["Loader async resuelve módulos"]
 L --> F["Factory function recibe módulos cargados"]
 F --> R["return del módulo listo para usarse"]
 BS["Bootstrap async:true"] --> D

El bootstrap: async de verdad

Todo empieza en el index.html. La bandera que marca la diferencia es data-sap-ui-async="true": sin ella, UI5 carga en modo síncrono legacy, bloqueante y desaconsejado.

<script id="sap-ui-bootstrap"
    src="resources/sap-ui-core.js"
    data-sap-ui-theme="sap_horizon"
    data-sap-ui-resourceroots='{"logaligroup.SAPUI5": "./"}'
    data-sap-ui-async="true"
    data-sap-ui-compatVersion="edge"
    data-sap-ui-oninit="module:sap/ui/core/ComponentSupport">
</script>

Fíjate en data-sap-ui-oninit="module:sap/ui/core/ComponentSupport". En lugar de un <script> inline que arranca el componente a mano, delegas el arranque en ComponentSupport. El componente se declara con un atributo en el <body>:

<body class="sapUiBody" id="content">
    <div data-sap-ui-component
         data-name="logaligroup.SAPUI5"
         data-id="container"
         data-settings='{"id": "SAPUI5"}'></div>
</body>

Por qué esto es también seguridad

Aquí está el corolario que muchos pasan por alto: la carga sin scripts inline es lo que hace tu app compatible con Content Security Policy (CSP). Una CSP estricta bloquea todo JavaScript embebido en el HTML. Si tu arranque depende de un <script>onInit()</script>, la CSP lo mata; si depende de ComponentSupport y sap.ui.define, no hay código inline que bloquear.

El async no es solo rendimiento. Es lo que permite que la misma app pase un audit de seguridad con CSP estricta sin reescribir el arranque.

Reglas prácticas que aplicamos siempre:

  • Todo fichero JS empieza por sap.ui.define. Nunca sap.ui.getCore() global, nunca jQuery.sap.
  • Bootstrap con data-sap-ui-async="true" y arranque vía ComponentSupport, no scripts inline.
  • Si necesitas un módulo dentro de una función (no en la cabecera), usa sap.ui.require, la variante asíncrona, no la carga síncrona.

El código moderno de UI5 es asíncrono por defecto. No es una opción avanzada: es el mínimo para que tu app sea mantenible y auditable.

¿Te ha resultado útil?

Comentarios

    Deja un comentario

    Responsable: Logali Tech. Finalidad: moderar y publicar tu comentario y, si dejas tu correo, avisarte. Derechos: acceso, rectificación y supresión en [email protected].