关于 ui5-best-practices
ui5-best-practices 是提供 SAP UI5 开发指导的技能,涵盖编码、工具、CAP 集成和表单规范,也说明如何使用 MCP 工具查询 API 并运行检查。
主要功能
- 01显式模块依赖规范
- 02数据绑定与 i18n 实践
- 03符合 CSP 的代码与样式规则
- 04UI5 事件类型规范
- 05CAP 项目集成指导
- 06API 查询与代码检查流程
适用场景
- 01检查 UI5 模块加载方式
- 02构建表单与数据绑定
- 03将 UI5 应用集成到 CAP 项目
- 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 模型。
优先级顺序:
- OData 类型(
sap/ui/model/odata/type/*)- 首选 - 简单类型(
sap/ui/model/type/*)- 仅在没有对应的 OData 类型时使用 - 自定义类型 - 用于特殊的双向绑定场景或复杂验证
- 自定义格式化器 - 仅用于独特的业务逻辑(单向绑定)
<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、无障碍问题、缺陷)。
代码修复
- 始终先征得用户同意
- 使用
run_ui5_linter工具的fix参数 - 根据提供的上下文信息,手动修复剩余问题
本地服务行为
重要: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工具)