关于 fix-library-init
用于修复 UI5 库初始化代码的开发技能,面向处理 UI5 Linter 弃用提示的开发者。它补充正确的 apiVersion: 2,并指导将枚举改为 DataType.registerEnum。
主要功能
- 01修正 Library.init() 调用
- 02补充数值型 apiVersion: 2
- 03处理多种初始化参数形式
- 04指导枚举注册现代化
适用场景
- 01修复 UI5 Linter 初始化错误
- 02现代化 UI5 库的初始化代码
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ ui5/ plugins-coding-agents --skill fix-library-init安装后在 Claude Code 中输入/fix-library-init确认已加载。
详细介绍
Library.init() 现代化改造
此技能用于修复 UI5 linter 检测到的缺少 apiVersion: 2 的 Library.init() / Lib.init() 调用,并将枚举定义现代化为使用 DataType.registerEnum——使用 apiVersion: 2 时必须这样做。
处理的 Linter 规则
| 规则 ID | 消息模式 | 此技能的操作 |
|---|---|---|
no-deprecated-api | 对 Library.init() 的调用已弃用。请改用 {apiVersion: 2} 参数 | 在 init 调用中添加 apiVersion: 2 |
no-deprecated-api | 对 Lib.init() 的调用已弃用。请改用 {apiVersion: 2} 参数 | 在 init 调用中添加 apiVersion: 2 |
no-deprecated-api | 对 init() 的调用已弃用。请改用 {apiVersion: 2} 参数 | 添加 apiVersion: 2(解构的 init) |
适用场景
当你看到类似以下的 linter 输出时,请应用此技能:
library.js:9:2 error Deprecated call to Library.init(). Use the {apiVersion: 2} parameter instead no-deprecated-api
library.js:11:2 error Deprecated call to Lib.init(). Use the {apiVersion: 2} parameter instead no-deprecated-api
library.js:51:2 error Deprecated call to init(). Use the {apiVersion: 2} parameter instead no-deprecated-api
背景:Library.init() 的作用
sap/ui/core/Lib.init() 会向框架注册一个 UI5 库,并声明其元数据:名称、依赖项、控件、元素、类型(枚举)和接口。apiVersion: 2 参数表示该库采用现代初始化模式。
重要:Lib.init() 只接受 apiVersion: 2。与也接受 apiVersion: 4 的控件渲染器不同,库初始化只接受 2。
修复策略
1. 无参数
问题:调用 Lib.init() 时完全没有传入参数。
// Before — triggers no-deprecated-api
sap.ui.define([
"sap/ui/core/Lib"
], function(Library) {
"use strict";
Library.init();
});
修复:添加一个包含 apiVersion: 2 的对象参数。
// After
sap.ui.define([
"sap/ui/core/Lib"
], function(Library) {
"use strict";
Library.init({
apiVersion: 2
});
});
2. 对象参数中没有 apiVersion
问题:Lib.init() 接收了一个对象,但其中没有 apiVersion 属性。
// Before — triggers no-deprecated-api
Library.init({
name: "my.lib",
dependencies: ["sap.ui.core", "sap.m"]
});
修复:将 apiVersion: 2 作为对象的第一个属性添加。
// After
Library.init({
apiVersion: 2,
name: "my.lib",
dependencies: ["sap.ui.core", "sap.m"]
});
3. apiVersion 不是数字
问题:apiVersion 是字符串,而不是数字字面量。
// Before — triggers no-deprecated-api
Library.init({
apiVersion: "2"
});
修复:改为数字字面量 2。
// After
Library.init({
apiVersion: 2
});
4. apiVersion 数字错误
问题:apiVersion 是数字,但不是 2。
// Before — triggers no-deprecated-api
Library.init({
apiVersion: 1
});
修复:改为 2。
// After
Library.init({
apiVersion: 2
});
5. 元素访问语法
通过方括号表示法调用 init 时,也适用相同的模式:
// Before
Library["init"]({
apiVersion: 1,
dependencies: ["sap.ui.core"]
});
// After
Library["init"]({
apiVersion: 2,
dependencies: ["sap.ui.core"]
});
6. 解构或赋值的 init
Linter 也会检测以下模式:
// Assignment
const LibInit = Library.init;
LibInit({ apiVersion: 1 });
// Destructuring
const {init} = Library;
init({ apiVersion: 1 });
// Destructuring with rename
const {init: libInit} = Library;
libInit({ apiVersion: 1 });
修复:同样,将每次调用中的 apiVersion 改为 2。
将枚举现代化为 DataType.registerEnum
将 Lib.init() 升级为 apiVersion: 2 时,在全局命名空间中定义枚举的旧方法将不再有效。若未显式注册,框架就无法解析控件元数据中使用的类型字符串,这可能导致 XSS 漏洞,因为类型检查会被静默跳过。
此技能必须在 library.js 中查找现有的枚举定义,并将其现代化为使用 DataType.registerEnum。
如何查找枚举
- 检查
Lib.init()调用中的types数组——其中列出了该库定义的所有类型(枚举)的完全限定名称 - 搜索全局命名空间赋值——例如
my.lib.ValueColor = { ... },其中my.lib是库命名空间 - 查找现有的枚举对象——以包含字符串键值对的普通对象形式定义
现代化步骤
-
捕获
Lib.init()的返回值并赋给变量(如果尚未这样做):// Before Library.init({ name: "my.lib", apiVersion: 2, types: ["my.lib.ValueColor"] }); // After var oThisLibrary = Library.init({ name: "my.lib", apiVersion: 2, types: ["my.lib.ValueColor"] }); -
将枚举定义从全局命名空间移至库对象:
// Before — global namespace my.lib.ValueColor = { Color1: "Color1", Color2: "Color2" }; // After — on library object oThisLibrary.ValueColor = { Color1: "Color1", Color2: "Color2" }; -
在每个枚举定义后立即添加
DataType.registerEnum调用:oThisLibrary.ValueColor = { Color1: "Color1", Color2: "Color2" }; DataType.registerEnum("my.lib.ValueColor", oThisLibrary.ValueColor); -
将
sap/ui/base/DataType添加到sap.ui.define依赖列表中(如果尚未添加):sap.ui.define([ "sap/ui/base/DataType", // Add this "sap/ui/core/Lib" ], function(DataType, Library) {
关键规则
registerEnum的第一个参数必须与控件元数据中用作type的字符串完全一致(例如"my.lib.ValueColor")- 为确保库预加载兼容性,所有枚举定义都应保留在
library.js中 types数组中列出的每个枚举都需要各自的registerEnum调用
完整示例
修改前
/*!
* ${copyright}
*/
sap.ui.define([
"sap/ui/core/Lib"
], function(Library) {
"use strict";
Library.init({
name: "my.lib",
dependencies: ["sap.ui.core", "sap.m"],
types: [
"my.lib.ValueColor",
"my.lib.StatusType"
],
controls: [
"my.lib.MyControl"
]
});
// Enums defined on global namespace
my.lib.ValueColor = {
Good: "Good",
Critical: "Critical",
Error: "Error",
Neutral: "Neutral"
};
my.lib.StatusType = {
Active: "Active",
Inactive: "Inactive"
};
});
修改后
/*!
* ${copyright}
*/
sap.ui.define([
"sap/ui/base/DataType",
"sap/ui/core/Lib"
], function(DataType, Library) {
"use strict";
var oThisLibrary = Library.init({
apiVersion: 2,
name: "my.lib",
dependencies: ["sap.ui.core", "sap.m"],
types: [
"my.lib.ValueColor",
"my.lib.StatusType"
],
controls: [
"my.lib.MyControl"
]
});
oThisLibrary.ValueColor = {
Good: "Good",
Critical: "Critical",
Error: "Error",
Neutral: "Neutral"
};
DataType.registerEnum("my.lib.ValueColor", oThisLibrary.ValueColor);
oThisLibrary.StatusType = {
Active: "Active",
Inactive: "Inactive"
};
DataType.registerEnum("my.lib.StatusType", oThisLibrary.StatusType);
return oThisLibrary;
});
实施步骤
-
使用 --details 运行 linter,以获取更多上下文:
npx @ui5/linter --details -
阅读 library.js 文件并确认:
Lib.init()/Library.init()调用及其当前参数- 是否将返回值赋给变量
- 是否存在枚举定义(检查
types数组和全局命名空间赋值)
-
修复 apiVersion:
- 如果没有参数:添加
{ apiVersion: 2 } - 如果参数是没有 apiVersion 的对象:将
apiVersion: 2添加为第一个属性 - 如果 apiVersion 的值或类型错误:将其改为数值
2
- 如果没有参数:添加
-
更新枚举(如果存在):
- 如果尚未完成,将
Lib.init()的返回值赋给变量 - 将每个枚举从全局命名空间移至库对象
- 为每个枚举添加
DataType.registerEnum调用 - 将
sap/ui/base/DataType添加到依赖项列表
- 如果尚未完成,将
-
确保模块返回库对象(
return oThisLibrary;) -
重新运行 linter,验证修复结果
说明
- 对于
Lib.init(),只有apiVersion: 2有效;apiVersion: 4无效(该值仅适用于渲染器) apiVersion必须是数值字面量,不能是字符串- 没有枚举的库只需修复
apiVersion: 2(无需调用DataType.registerEnum) - 如果库已返回 init 结果,且没有全局枚举定义,则只需修复 apiVersion
- init 调用中的
types数组可用于判断哪些枚举需要调用registerEnum
相关技能
- fix-control-renderer:用于修复渲染器
apiVersion问题(渲染器对象中缺少apiVersion: 2或4)——这与库 init apiVersion 不同 - fix-pseudo-modules:如果使用方代码通过伪模块导入枚举(例如
sap.ui.require(["my/lib/ValueColor"])),请使用 fix-pseudo-modules 将其转换为库模块导入 - fix-js-globals:如果 library.js 中除了枚举定义之外还存在全局访问模式(例如
sap.ui.getCore()),请使用 fix-js-globals 处理