mcpField
F
fix-component-async

fix-component-async

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

关于 fix-component-async

fix-component-async 是用于修正 UI5 Component.js 异步加载配置的开发技能,适用于现代化改造或处理 Linter 报错。它说明接口与清单的修改方式,并提供位置检查和验证脚本。

主要功能

  1. 01添加 IAsyncContentCreation 标记接口
  2. 02在组件元数据中声明清单用法
  3. 03移除冗余的 async 清单属性
  4. 04处理内联清单和 ES6 类语法
  5. 05使用门禁脚本验证修改

适用场景

  1. 01处理 async-component-flags Linter 报错
  2. 02在 UI5 升级中现代化 Component.js
  3. 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
}

实施步骤

  1. 阅读 Component.js 文件
  2. 确定语法风格(sap.ui.define 或 ES6 class)
  3. 对于 async-component-flags 错误:
    • 检查是否已声明 IAsyncContentCreation 接口
    • 如果尚未声明,在 metadata: { } 对象中添加 interfaces: ["sap.ui.core.IAsyncContentCreation"] 作为属性(与 manifest 同级,而不是与 metadata 本身同级)
    • 检查是否已声明 manifest: "json",如果没有,则添加
  4. 验证位置:interfaces 的缩进必须比 metadata: 深一级——如果两者处于同一层级,则位置错误
  5. 检查 manifest.json(或内联 manifest)中是否有多余的 async 标志
  6. 从 rootView 和 routing/config 中移除 async 属性
  7. 写入更新后的文件
  8. 运行门禁脚本进行验证: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 将其转换为正确的模块导入

评论

支持 Markdown