mcpField
U
ui5-best-practices

ui5-best-practices

github.com/ui5开发44332 次安装1 周前更新
代码仓库

关于 ui5-best-practices

ui5-best-practices 是提供 SAP UI5 开发指导的技能,涵盖编码、工具、CAP 集成和表单规范,也说明如何使用 MCP 工具查询 API 并运行检查。

主要功能

  1. 01显式模块依赖规范
  2. 02数据绑定与 i18n 实践
  3. 03符合 CSP 的代码与样式规则
  4. 04UI5 事件类型规范
  5. 05CAP 项目集成指导
  6. 06API 查询与代码检查流程

适用场景

  1. 01检查 UI5 模块加载方式
  2. 02构建表单与数据绑定
  3. 03将 UI5 应用集成到 CAP 项目
  4. 04使用 UI5 工具检查代码

MCP 相关

该技能要求使用 `get_api_reference` 工具查询 UI5 API 信息,并使用 `run_ui5_linter` 进行验证和问题修复。

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/ui5/plugins-coding-agents --skill ui5-best-practices

安装后在 Claude Code 中输入/ui5-best-practices确认已加载。

详细介绍

UI5 最佳实践和编码标准

概述

此技能强制执行源自 SAP 官方指南的 UI5 开发标准,涵盖四个关键领域:编码指南、工具集成、CAP 集成和表单创建规则。


1. 模块加载 - 关键

切勿使用全局访问

切勿全局访问 UI5 框架对象(例如 sap.m.Button)。始终显式声明依赖项,以便异步加载。

JavaScript
// ❌ WRONG - Global access
var oButton = new sap.m.Button();

// ✅ CORRECT - Explicit dependency
sap.ui.define(["sap/m/Button"], function(Button) {
    var oButton = new Button();
});

// ✅ CORRECT - Dynamic loading with sap.ui.require
sap.ui.require(["sap/m/MessageBox"], function(MessageBox) {
    MessageBox.show("Hello");
});
TypeScript
// ❌ WRONG - Global namespace
const button: sap.m.Button;

// ✅ CORRECT - Import module
import Button from "sap/m/Button";
const button: Button;
XML 视图

<m:Button text="Click Me"/>


<ObjectListItem
    core:require="{
        Currency: 'sap/ui/model/type/Currency'
    }"
    number="{
        parts: ['invoice>Price', 'view>/currency'],
        type: 'Currency'
    }"/>

原因:确保正确进行异步加载,并提升生产构建的性能。

参考:UI5 文档页面“在 XML 视图和片段中引入模块”


2. 组件初始化

使用 sap/ui/core/ComponentSupport 以声明方式初始化**初始(根)**组件:


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

参考:UI5 文档页面“初始组件的声明式 API”

**注意:**嵌套组件应通过组件用法进行管理(在承载组件的 manifest.json 中声明)


3. 数据绑定最佳实践

始终使用内置数据类型

在视图中始终使用数据绑定,将 UI 控件连接到数据模型或 i18n 模型。

优先级顺序:

  1. OData 类型(sap/ui/model/odata/type/*)- 首选
  2. 简单类型(sap/ui/model/type/*)- 仅在没有对应的 OData 类型时使用
  3. 自定义类型 - 用于特殊的双向绑定场景或复杂验证
  4. 自定义格式化器 - 仅用于独特的业务逻辑(单向绑定)

<Text text="{path: 'price', formatter: '.formatCurrency'}"/>


<Text text="{
    path: 'price',
    type: 'sap.ui.model.odata.type.Decimal',
    formatOptions: {
        style: 'currency',
        currencyCode: 'EUR'
    }
}"/>


<Text text="{
    path: 'quantity',
    type: 'sap.ui.model.odata.type.Decimal',
    formatOptions: {
        groupingEnabled: true
    }
}"/>

常见 OData 类型:

  • sap.ui.model.odata.type.Decimal - 带小数的数字
  • sap.ui.model.odata.type.String - 带长度限制的文本
  • sap.ui.model.odata.type.DateTime - 日期和时间

常见简单类型(仅在没有对应的 OData 类型时使用):

  • sap.ui.model.type.DateInterval - 日期范围
  • sap.ui.model.type.FileSize - 文件大小格式化

示例:需要使用千位分隔符格式化数字时,优先使用带有 formatOptions: {groupingEnabled: true} 的 sap.ui.model.odata.type.Decimal,而不是 sap.ui.model.type.Integer 或自定义格式化器。

何时使用自定义类型

当内置类型无法提供所需的验证或转换逻辑时,特殊的双向绑定场景需要使用自定义类型。

示例:用于双向绑定的电子邮件验证自定义类型

// controller/EmailType.js
sap.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");
            }
        }
    });
});

在视图中使用:


<Input value="{path: 'email', formatter: '.validateEmail'}"/>


<Input 
    core:require="{EmailType: 'my/app/type/EmailType'}"
    value="{
        path: 'email',
        type: 'EmailType'
    }"/>

使用自定义类型的原因:

  • ✅ 支持双向绑定(formatValue + parseValue + validateValue)
  • ✅ 用户输入时实时验证
  • ✅ 有效输入会立即更新模型
  • ❌ 自定义格式化器仅适用于单向(显示)绑定
视图中的数据绑定

始终使用数据绑定将控件连接到模型:


<Input value="{/customer/name}"/>


<List items="{/products}">
    <StandardListItem title="{name}" description="{price}"/>
</List>


<Text text="{= ${quantity} * ${price} }" visible="{= ${stock} > 0 }"/>

4. 国际化(i18n)

翻译工作流指南

修改 .properties 文件时,请根据项目类型遵循相应的工作流:

用于开发和测试:

  • 仅更新 i18n.properties(基础文件)
  • 更改会立即反映在开发环境中

生产环境翻译工作流:

  • SAP S/4HANA 应用:切勿手动编辑本地化文件(i18n_de.properties、i18n_fr.properties 等)
    • 翻译通过 SAP 内部翻译流程处理
  • 使用 SAP Translation Hub 或 Translation Export/Import (TEW) 的应用:不要修改本地化文件
    • 翻译会根据基础文件自动生成
  • 仅手动翻译的应用:对所有区域设置文件应用更改,以保持一致性

原因:专业翻译工作流会根据基础 i18n.properties 文件生成本地化文件。手动编辑本地化文件会在翻译过程中被覆盖。


5. 安全性 - 内容安全策略

切勿使用内联脚本或样式

在 HTML 中切勿使用内联脚本或内联样式。它们违反了 UI5 应用的推荐 CSP 设置。


<script>
    alert("Hello");
</script>

<style>
    .error { color: red; }
</style>

<div style="color: red;">Styled text</div>


<script src="controller/Main.controller.js"></script>
<link rel="stylesheet" href="css/style.css">


<div class="errorText">Styled text</div>

要求:

  • 所有应用逻辑都必须放在专用的 JS 或 TS 文件中
  • 所有样式都必须放在专用的 CSS 文件中
  • 内联 <script> 标签违反 CSP
  • 内联 <style> 标签违反 CSP
  • 内联 style 属性违反 CSP

参考:UI5 文档页面“内容安全策略”


6. TypeScript 事件处理(UI5 >= 1.115.0)

使用控件专用的事件类型

对于 UI5 1.115.0 及更高版本,请从控件的模块中导入并使用对应的事件类型。

模式:<ControlName>$<EventName>Event(注意“Event”后缀)

// ✅ CORRECT - Import specific event type
import { 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");
        // ...
    }
}
较旧版本的备用方案

UI5 < 1.115.0:不提供控件专用的事件类型。请使用通用的 Event 类型:

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
        // ...
    }
}

优点:无需手动转换类型,即可对事件参数进行静态类型检查和自动补全。


7. MCP 工具集成

API 查询

始终使用 get_api_reference 工具获取有关 UI5 控件和 API 的信息。该工具会返回当前使用的 UI5 版本对应的控件、类和命名空间的官方 API 文档。

代码验证

始终使用 run_ui5_linter 工具查找问题(已弃用的 API、无障碍问题、缺陷)。

代码修复
  1. 始终先征得用户同意
  2. 使用 run_ui5_linter 工具的 fix 参数
  3. 根据提供的上下文信息,手动修复剩余问题
本地服务行为

重要:UI5 CLI 开发服务不会提供默认的索引文件。请使用完整路径:http://localhost:8080/index.html

代码质量检查

完成更改后,运行项目的代码检查工具(npm run lint、eslint . 或 ui5lint .)。提交前修复所有错误。


8. CAP 集成

在 CAP(Cloud Application Programming Model)项目中创建 UI5 项目时:

项目位置

始终在 CAP 项目根目录的 app/ 目录中创建 UI5 项目。

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

获取服务信息:

  • 如果 CDS 工具可用:使用这些工具获取定义、服务和端点
  • 如果没有 CDS 工具:运行以下命令:
    cds compile '*'                        # Get definitions
    cds compile '*' --to serviceinfo       # Get services and endpoints
    
服务集成

创建 UI5 项目时,始终提供:

  • 绝对 OData V4 服务 URL
  • 目标实体集
插件安装

始终在 CAP 项目根目录中运行:

npm i -D cds-plugin-ui5

此插件会自动处理 UI5 应用的服务。

运行服务
# ❌ WRONG - Never run separate UI5 server
cd app/my-ui5-app
ui5 serve                    # Don't do this!
npm start                    # Don't do this!

# ✅ CORRECT - Run from CAP project root
cds watch                    # Serves both backend and UI5 apps
# or
cds run                      # Alternative command

原因:一条命令即可从同一来源(http://localhost:4004)提供后端服务和所有 UI5 应用。

数据连接

切勿在 ui5.yaml 中配置 ui5-middleware-simpleproxy:

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

原因:cds watch 可确保 UI 和服务由同一来源提供,因此无需代理。

访问应用

查看 CAP 启动页面(通常为 http://localhost:4004),以获取:

  • 可用服务列表
  • UI5 应用链接

9. 表单创建规则

切勿使用 SimpleForm(除非明确要求)

<form:SimpleForm>
    <Label text="Name"/>
    <Input value="{name}"/>
</form:SimpleForm>


<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>
默认列配置

除非另有要求,始终使用以下默认值:

  • M 尺寸:2 列
  • L 尺寸:3 列
  • XL 尺寸:4 列

文档参考

如需更多信息,请参阅以下 UI5 文档页面:

  • “在 XML 视图和片段中引入模块”
  • “初始组件声明式 API”
  • “内容安全策略”
  • 官方 UI5 API 参考(使用 get_api_reference 工具)

评论

支持 Markdown