Ui5 Best Practices

作者 UI5a99b882ce364無授權條款收錄於 2026年10月8日更新於 2026年10月8日

UI5 development best practices and coding standards derived exclusively from official SAP UI5 guidelines. Use when writing UI5 applications to ensure modern, maintainable code following SAP standards. Covers: async module loading (sap.ui.define, ES6 imports, core:require), ComponentSupport initialization, data binding with OData types, i18n management, CSP compliance (no inline scripts), TypeScript event types (UI5 >= 1.115.0), MCP tooling (get_api_reference, run_ui5_linter), CAP integration patterns, and form creation rules (never SimpleForm, always Form with ColumnLayout). Keywords: ui5 coding standards, async loading, sap.ui.define, data binding, odata types, i18n translation, CSP no inline scripts, TypeScript event handlers, Button$PressEvent, ui5 linter, API reference, ComponentSupport, form layout, ColumnLayout, CAP integration, cds watch

AI 產生的概覽

強制執行 SAP UI5 編碼標準,涵蓋模組載入、資料繫結、i18n、CSP、TypeScript 事件、CAP 整合與表單。

功能
此技能提供源自 SAP 官方指南的 UI5 開發最佳實務與編碼標準。它針對非同步模組載入、元件初始化、使用 OData 類型的資料繫結、i18n 翻譯流程、CSP 合規、TypeScript 事件類型、MCP 工具使用、CAP 整合以及表單版面配置,提供規則與程式碼範例。它產出的是指引與範例片段,而非檔案或指令碼。
適用情境
在撰寫或審查 SAP UI5 應用程式,並希望程式碼遵循現代且易於維護的 SAP 標準時使用。它也適用於將 UI5 應用程式整合至 CAP 專案,或檢查表單、繫結與 i18n 處理時。
執行需求
僅為說明性內容,未附帶指令碼。部分提及的工作流程假定具備 UI5 工具鏈,例如 UI5 CLI、UI5 linter、MCP 工具(get_api_reference、run_ui5_linter)、Node/npm,以及 CAP 專案所需的 CDS 工具。

UI5 Best Practices and Coding Standards

Overview

This skill enforces UI5 development standards derived from official SAP guidelines. It covers the four critical areas: coding guidelines, tooling integration, CAP integration, and form creation rules.


1. Module Loading - CRITICAL

Never Use Global Access

NEVER access UI5 framework objects globally (e.g., sap.m.Button). Always declare dependencies explicitly for asynchronous loading.

JavaScript
javascript
// ❌ WRONG - Global accessvar oButton = new sap.m.Button();
// ✅ CORRECT - Explicit dependencysap.ui.define(["sap/m/Button"], function(Button) {    var oButton = new Button();});
// ✅ CORRECT - Dynamic loading with sap.ui.requiresap.ui.require(["sap/m/MessageBox"], function(MessageBox) {    MessageBox.show("Hello");});
TypeScript
ts
// ❌ WRONG - Global namespaceconst button: sap.m.Button;
// ✅ CORRECT - Import moduleimport Button from "sap/m/Button";const button: Button;
XML Views
xml
<!-- ✅ Controls are auto-loaded by tag --><m:Button text="Click Me"/>
<!-- ✅ For formatters/types, use core:require --><ObjectListItem    core:require="{        Currency: 'sap/ui/model/type/Currency'    }"    number="{        parts: ['invoice>Price', 'view>/currency'],        type: 'Currency'    }"/>

Why: Ensures proper async loading, improves performance in production builds.

Reference: UI5 documentation page "Require Modules in XML View and Fragment"


2. Component Initialization

Use sap/ui/core/ComponentSupport for declarative initialization of the initial (root) component:

html
<!-- index.html --><script id="sap-ui-bootstrap"    src="resources/sap-ui-core.js"    data-sap-ui-on-init="module:sap/ui/core/ComponentSupport"    data-sap-ui-async="true"    data-sap-ui-resource-roots='{ "my.app": "./" }'></script>
<body class="sapUiBody">    <div data-sap-ui-component          data-name="my.app"          data-id="container">    </div></body>

Reference: UI5 documentation page "Declarative API for Initial Components"

Note: Nested components should be managed via component usages (declared in the manifest.json of the containing component)


3. Data Binding Best Practices

Always Use Built-in Data Types

ALWAYS use data binding in views to connect UI controls to data or i18n models.

Priority order:

  1. OData types (sap/ui/model/odata/type/*) - Preferred
  2. Simple types (sap/ui/model/type/*) - Only when no OData equivalent
  3. Custom types - For special two-way binding scenarios or complex validation
  4. Custom formatters - Only for unique business logic (one-way binding)
xml
<!-- ❌ WRONG - Custom formatter for standard formatting --><Text text="{path: 'price', formatter: '.formatCurrency'}"/>
<!-- ✅ CORRECT - Use OData type with format options --><Text text="{    path: 'price',    type: 'sap.ui.model.odata.type.Decimal',    formatOptions: {        style: 'currency',        currencyCode: 'EUR'    }}"/>
<!-- ✅ CORRECT - Use grouping for thousands separator --><Text text="{    path: 'quantity',    type: 'sap.ui.model.odata.type.Decimal',    formatOptions: {        groupingEnabled: true    }}"/>

Common OData Types:

  • sap.ui.model.odata.type.Decimal - Numbers with decimals
  • sap.ui.model.odata.type.String - Text with length constraints
  • sap.ui.model.odata.type.DateTime - Date and time

Common Simple Types (use only when no OData equivalent):

  • sap.ui.model.type.DateInterval - Date ranges
  • sap.ui.model.type.FileSize - File size formatting

Example: For number formatting with thousands separator, prefer sap.ui.model.odata.type.Decimal with formatOptions: {groupingEnabled: true} over sap.ui.model.type.Integer or a custom formatter.

When to Use Custom Types

Custom types are needed for special two-way binding scenarios where built-in types don't provide the required validation or conversion logic.

Example: Custom Type for Email Validation with Two-Way Binding

javascript
// controller/EmailType.jssap.ui.define(["sap/ui/model/SimpleType"], function(SimpleType) {    return SimpleType.extend("my.app.type.EmailType", {        formatValue: function(oValue) {            return oValue;        },        parseValue: function(oValue) {            return oValue;        },        validateValue: function(oValue) {            const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;            if (oValue && !emailRegex.test(oValue)) {                throw new sap.ui.model.ValidateException("Invalid email format");            }        }    });});

Usage in View:

xml
<!-- ❌ WRONG - Formatter doesn't work for two-way binding validation --><Input value="{path: 'email', formatter: '.validateEmail'}"/>
<!-- ✅ CORRECT - Custom type enables two-way binding with validation --><Input     core:require="{EmailType: 'my/app/type/EmailType'}"    value="{        path: 'email',        type: 'EmailType'    }"/>

Why Custom Types:

  • ✅ Two-way binding support (formatValue + parseValue + validateValue)
  • ✅ Real-time validation as user types
  • ✅ Model updates immediately on valid input
  • ❌ Custom formatters only work for one-way (display) binding

Data Binding in Views

ALWAYS use data binding to connect controls to models:

xml
<!-- Property binding --><Input value="{/customer/name}"/>
<!-- Aggregation binding --><List items="{/products}">    <StandardListItem title="{name}" description="{price}"/></List>
<!-- Expression binding --><Text text="{= ${quantity} * ${price} }" visible="{= ${stock} > 0 }"/>

4. Internationalization (i18n)

Translation Workflow Guidelines

When modifying .properties files, follow the appropriate workflow based on your project type:

For development and testing:

  • Update i18n.properties (base file) only
  • Changes will be reflected immediately for development

Production translation workflows:

  • SAP S/4HANA apps: NEVER manually edit localized files (i18n_de.properties, i18n_fr.properties, etc.)
    • Translation is handled through SAP's internal translation process
  • Apps using SAP Translation Hub or Translation Export/Import (TEW): DO NOT touch localized files
    • Translations are generated automatically from the base file
  • Manually translated apps only: Apply changes to all locale files to maintain consistency

Why: Professional translation workflows generate localized files from the base i18n.properties file. Manual edits to localized files will be overwritten during the translation process.


5. Security - Content Security Policy

Never Use Inline Scripts or Styles

NEVER use inline scripts or inline styles in HTML. They violate the recommended CSP settings for UI5 applications.

html
<!-- ❌ WRONG - Violates CSP --><script>    alert("Hello");</script>
<style>    .error { color: red; }</style>
<div style="color: red;">Styled text</div>
<!-- ✅ CORRECT - External files --><script src="controller/Main.controller.js"></script><link rel="stylesheet" href="css/style.css">
<!-- ✅ CORRECT - CSS classes --><div class="errorText">Styled text</div>

Requirements:

  • All application logic must reside in dedicated JS or TS files
  • All styling must reside in dedicated CSS files
  • Inline <script> tags violate CSP
  • Inline <style> tags violate CSP
  • Inline style attributes violate CSP

Reference: UI5 documentation page "Content Security Policy"


6. TypeScript Event Handling (UI5 >= 1.115.0)

Use Control-Specific Event Types

For UI5 1.115.0 and above, import and use the specific event type from the control's module.

Pattern: <ControlName>$<EventName>Event (notice the "Event" suffix)

ts
// ✅ CORRECT - Import specific event typeimport { Button$PressEvent } from "sap/m/Button";import { Table$RowSelectionChangeEvent } from "sap/ui/table/Table";import Controller from "sap/ui/core/mvc/Controller";
export default class MainController extends Controller {    public onPress(event: Button$PressEvent): void {        const button = event.getSource();  // Correctly typed as Button        // ...    }        public onRowSelectionChange(event: Table$RowSelectionChangeEvent): void {        // Correctly typed: getParameter is known and return value inferred        const selectedContext = event.getParameter("rowContext");        // ...    }}

Fallback for Older Versions

UI5 < 1.115.0: Control-specific event types are NOT available. Use the generic Event type:

ts
import Event from "sap/ui/base/Event";import Controller from "sap/ui/core/mvc/Controller";
export default class MainController extends Controller {    public onPress(event: Event): void {        // Generic Event type for UI5 < 1.115.0        // ...    }}

Benefits: Static type checking and autocompletion for event parameters without manual casting.


7. MCP Tooling Integration

API Lookup

ALWAYS use the get_api_reference tool to get information on UI5 controls and APIs. Returns official API documentation for controls, classes, and namespaces for the UI5 version in use.

Code Validation

ALWAYS use the run_ui5_linter tool to identify issues (deprecated APIs, accessibility issues, bugs).

Code Fixes

  1. ALWAYS confirm with the user first
  2. Use the fix parameter of the run_ui5_linter tool
  3. Manually fix remaining issues using the context information provided

Local Server Behavior

CRITICAL: The UI5 CLI dev server does NOT serve a default index file. Use full paths: http://localhost:8080/index.html

Code Quality Checks

After making changes, run the project's linter (npm run lint, eslint ., or ui5lint .). Fix all errors before committing.


8. CAP Integration

When creating a UI5 project within a CAP (Cloud Application Programming Model) project:

Project Location

ALWAYS create UI5 projects within the app/ directory of the CAP project root.

cap-project/├── app/                    # ← UI5 apps go here│   └── my-ui5-app/├── srv/                    # CAP services├── db/                     # Database models└── package.json

Service Information

Get service information:

  • If CDS tools are available: Use them to get definitions, services, and endpoints
  • If no CDS tools: Run these commands:
    bash
    cds compile '*'                        # Get definitionscds compile '*' --to serviceinfo       # Get services and endpoints

Service Integration

When creating the UI5 project, ALWAYS provide:

  • Absolute OData V4 service URL
  • Target entity set

Plugin Installation

ALWAYS run in CAP project root:

bash
npm i -D cds-plugin-ui5

This plugin automatically handles serving the UI5 applications.

Running the Server

bash
# ❌ WRONG - Never run separate UI5 servercd app/my-ui5-appui5 serve                    # Don't do this!npm start                    # Don't do this!
# ✅ CORRECT - Run from CAP project rootcds watch                    # Serves both backend and UI5 apps# orcds run                      # Alternative command

Why: Single command serves both backend services and all UI5 applications from the same origin (http://localhost:4004).

Data Connection

NEVER configure ui5-middleware-simpleproxy in ui5.yaml:

yaml
# ❌ WRONG - No proxy neededserver:  customMiddleware:    - name: ui5-middleware-simpleproxy    # Don't add this!

Why: cds watch ensures UI and service are served from the same origin, making a proxy unnecessary.

Accessing the App

Check the CAP launch page (typically http://localhost:4004) for:

  • List of available services
  • Links to UI5 applications

9. Form Creation Rules

Never Use SimpleForm (Unless Explicitly Requested)

xml
<!-- ❌ AVOID - SimpleForm --><form:SimpleForm>    <Label text="Name"/>    <Input value="{name}"/></form:SimpleForm>
<!-- ✅ CORRECT - Use Form with ColumnLayout --><form:Form editable="true">    <form:layout>        <form:ColumnLayout            columnsM="2"            columnsL="3"            columnsXL="4"/>    </form:layout>    <form:formContainers>        <form:FormContainer title="Personal Data">            <form:formElements>                <form:FormElement label="Name">                    <form:fields>                        <Input value="{name}"/>                    </form:fields>                </form:FormElement>            </form:formElements>        </form:FormContainer>    </form:formContainers></form:Form>

Default Column Configuration

ALWAYS use these defaults unless requested differently:

  • M-size: 2 columns
  • L-size: 3 columns
  • XL-size: 4 columns

Documentation References

For additional information, consult these UI5 documentation pages:

  • "Require Modules in XML View and Fragment"
  • "Declarative API for Initial Components"
  • "Content Security Policy"
  • Official UI5 API Reference (use get_api_reference tool)

來源與署名

來源:UI5/plugins-coding-agents位於plugins/ui5/skills/ui5-best-practices提交a99b882

授權條款: 無授權條款

內容歸原作者所有。SourceWeft 從公開儲存庫中收錄這些內容。

檢舉或申請下架