关于 fix-component-async
fix-component-async 是用于修正 UI5 Component.js 异步加载配置的开发技能,适用于现代化改造或处理 Linter 报错。它说明接口与清单的修改方式,并提供位置检查和验证脚本。
主要功能
- 01添加 IAsyncContentCreation 标记接口
- 02在组件元数据中声明清单用法
- 03移除冗余的 async 清单属性
- 04处理内联清单和 ES6 类语法
- 05使用门禁脚本验证修改
适用场景
- 01处理 async-component-flags Linter 报错
- 02在 UI5 升级中现代化 Component.js
- 03修正内联清单中的异步设置
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ ui5/ plugins-coding-agents --skill fix-component-async安装后在 Claude Code 中输入/fix-component-async确认已加载。
附带文件scripts/verify-component.js
详细介绍
修复 Component.js 异步配置
此技能用于修复 UI5 linter 检测到、但无法自动修复的 Component.js 异步配置问题,因为修复可能需要了解组件的加载行为。
处理的 Linter 规则
| 规则 ID | 消息模式 | 此技能的操作 |
|---|---|---|
async-component-flags | 组件未配置为异步加载 | 添加 IAsyncContentCreation 接口 |
async-component-flags | 组件未声明通过 manifest.json 文件使用描述符 | 添加 manifest: "json" |
async-component-flags | 组件实现了 sap.ui.core.IAsyncContentCreation 接口。多余的 'async' 标记……应予以移除 | 从 manifest 中移除 async 标记 |
async-component-flags | 必须移除 '...' 处的 'async' 属性 | 移除 async: false |
no-removed-manifest-property | 属性 '...' 已在 Manifest Version 2 中移除 | 移除 async 属性 |
适用场景
看到如下 linter 输出时,请使用此技能:
Component.js:5:1 error Component is not configured for asynchronous loading. async-component-flags
Component.js:5:1 warning Component does not specify that it uses the descriptor via the manifest.json file async-component-flags
Component.js:10:5 warning Component implements the sap.ui.core.IAsyncContentCreation interface. The redundant 'async' flag at '/sap.ui5/rootView/async' should be removed async-component-flags
manifest.json:25:9 error The 'async' property at '/sap.ui5/rootView/async' must be removed async-component-flags
完整现代化工作流中的重要事项: 即使 linter 未标记 async-component-flags,也要无条件地将此技能应用于每个 Component.js。只有在从 manifest.json 中移除多余的 async: true 标记后,linter 才能检测到缺失的接口。因此,在现代化早期阶段,错误可能尚未出现。请始终主动添加 IAsyncContentCreation。
关键规则
切勿导入 IAsyncContentCreation
IAsyncContentCreation 是一个标记接口——UI5 运行时会在 interfaces 数组中按字符串名称检查它。切勿将其作为模块依赖导入。将它添加到 sap.ui.define 依赖数组会导致运行时错误,因为 sap/ui/core/IAsyncContentCreation 不是可加载的模块。
// WRONG — do NOT import it
sap.ui.define([
"sap/ui/core/UIComponent",
"sap/ui/core/IAsyncContentCreation" // ← WRONG: will fail at runtime
], function(UIComponent, IAsyncContentCreation) {
...
});
// CORRECT — only reference it as a string in interfaces
sap.ui.define([
"sap/ui/core/UIComponent"
], function(UIComponent) {
return UIComponent.extend("my.app.Component", {
metadata: {
manifest: "json",
interfaces: ["sap.ui.core.IAsyncContentCreation"] // ← string reference only
}
});
});
如果在现有依赖数组中看到 "sap/ui/core/IAsyncContentCreation",请将其移除,并删除对应的函数参数。
正确放置 interfaces
interfaces 是 metadata 对象的属性,必须嵌套在 metadata: { } 内部。UIComponent.extend() 配置对象有两个层级:
UIComponent.extend("name", {
metadata: { ← level 1: component config
manifest: "json", ← level 2: metadata properties
interfaces: [...] ← level 2: THIS IS WHERE interfaces GOES
},
init: function() {} ← level 1: component config
});
UI5 运行时只会从 metadata 对象中读取 interfaces。将它放在第 1 层(与 metadata 并列)会静默失败,组件将无法被识别为异步组件。
编辑后请确认:interfaces 的缩进是否比 metadata: 多一级?如果不是,就说明放错了位置。
修复策略
1. async-component-flags - 添加 IAsyncContentCreation 接口
IAsyncContentCreation 接口是声明组件异步加载内容的现代方式。
正确——interfaces 嵌套在 metadata 内部:
// Before
sap.ui.define([
"sap/ui/core/UIComponent"
], function(UIComponent) {
"use strict";
return UIComponent.extend("my.app.Component", {
metadata: {
manifest: "json"
}
});
});
// After
sap.ui.define([
"sap/ui/core/UIComponent"
], function(UIComponent) {
"use strict";
return UIComponent.extend("my.app.Component", {
metadata: {
manifest: "json",
interfaces: ["sap.ui.core.IAsyncContentCreation"]
}
});
});
错误——interfaces 嵌套层级不正确:
// WRONG — interfaces as a sibling of metadata (level 1 instead of level 2)
return UIComponent.extend("my.app.Component", {
interfaces: ["sap.ui.core.IAsyncContentCreation"], // ← WRONG: outside metadata
metadata: {
manifest: "json"
}
});
2. async-component-flags - 添加 Manifest 声明
如果组件未声明使用 manifest,请在 metadata 中添加 manifest: "json"。
// Before
metadata: {
// no manifest declaration
}
// After
metadata: {
manifest: "json"
}
3. async-component-flags - 移除多余的 Async 标记
实现 IAsyncContentCreation 接口后,manifest.json 中的 async 标记就变得多余,应予以移除。
在 manifest.json 中:
// Before
{
"sap.ui5": {
"rootView": {
"viewName": "my.app.view.Main",
"type": "XML",
"async": true
},
"routing": {
"config": {
"async": true,
...
}
}
}
}
// After
{
"sap.ui5": {
"rootView": {
"viewName": "my.app.view.Main",
"type": "XML"
},
"routing": {
"config": {
...
}
}
}
}
4. async-component-flags - 移除 async: false
如果显式设置了 async: false,必须将其移除,因为它会阻止异步加载。
5. 处理 Component.js 中的内联 Manifest
如果 manifest 是在 Component.js 中内联定义的(而不是单独放在 manifest.json 中),请对内联 manifest 对象应用相同的修复。请注意,interfaces 仍应放在 metadata 内部——它与内联的 manifest 属性并列,二者都嵌套在 metadata 下:
// Before
metadata: {
manifest: {
"sap.ui5": {
"rootView": {
"async": true,
...
}
}
}
}
// After
metadata: {
manifest: {
"sap.ui5": {
"rootView": {
...
}
}
},
interfaces: ["sap.ui.core.IAsyncContentCreation"] // ← still INSIDE metadata
}
实施步骤
- 阅读 Component.js 文件
- 确定语法风格(sap.ui.define 或 ES6 class)
- 对于
async-component-flags错误:- 检查是否已声明
IAsyncContentCreation接口 - 如果尚未声明,在
metadata: { }对象中添加interfaces: ["sap.ui.core.IAsyncContentCreation"]作为属性(与manifest同级,而不是与metadata本身同级) - 检查是否已声明
manifest: "json",如果没有,则添加
- 检查是否已声明
- 验证位置:
interfaces的缩进必须比metadata:深一级——如果两者处于同一层级,则位置错误 - 检查 manifest.json(或内联 manifest)中是否有多余的 async 标志
- 从 rootView 和 routing/config 中移除
async属性 - 写入更新后的文件
- 运行门禁脚本进行验证:
node <skill-dir>/scripts/verify-component.js <project-root>— 必须以状态码 0 退出
修复示例
给定以下 linter 输出:
Component.js:5:1 error Component is not configured for asynchronous loading. async-component-flags
Component.js 转换:
// Before
sap.ui.define([
"sap/ui/core/UIComponent",
"sap/ui/model/json/JSONModel"
], function(UIComponent, JSONModel) {
"use strict";
return UIComponent.extend("my.app.Component", {
metadata: {
manifest: "json"
},
init: function() {
UIComponent.prototype.init.apply(this, arguments);
// ...
}
});
});
// After — interfaces goes INSIDE metadata, not next to init/metadata
sap.ui.define([
"sap/ui/core/UIComponent",
"sap/ui/model/json/JSONModel"
], function(UIComponent, JSONModel) {
"use strict";
return UIComponent.extend("my.app.Component", {
metadata: {
manifest: "json",
interfaces: ["sap.ui.core.IAsyncContentCreation"]
},
init: function() {
UIComponent.prototype.init.apply(this, arguments);
// ...
}
});
});
注意事项
IAsyncContentCreation接口是在 UI5 1.89 中引入的——确保 minUI5Version 与之兼容- 添加该接口时,还要确保存在
manifest: "json",以便正确进行异步加载 - 该接口会使
async: true标志变得多余——可以安全移除 - 继承自 UIComponent(而不仅仅是 Component)的组件可以使用 IAsyncContentCreation
- 如果组件继承自已实现 IAsyncContentCreation 的自定义基类,则无需更改
IAsyncContentCreation与 manifest v2:二者相互独立。将 manifest_version更新为"2.0.0"并不会自动启用异步内容创建——仍必须在 Component.js 中显式实现IAsyncContentCreation。反之,添加IAsyncContentCreation并不要求使用 manifest v2。
相关技能
- fix-manifest-json:添加
IAsyncContentCreation后,manifest.json 中的async标志会变得多余——使用 fix-manifest-json 更新_version、移除 async 属性并重命名 routing 配置 - fix-js-globals:如果 Component.js 使用全局访问模式(例如
sap.ui.getCore()),请使用 fix-js-globals 将其转换为正确的模块导入