mcpField
F
fix-pseudo-modules

fix-pseudo-modules

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

关于 fix-pseudo-modules

面向 UI5 开发者的技能,用于处理伪模块和隐式全局变量相关的检查问题。它说明如何从库导入枚举、直接导入模块,以及加载 OData 表达式扩展。

主要功能

  1. 01从库导入枚举和数据类型
  2. 02为类和控件使用直接导入
  3. 03为 OData 函数加载 ODataExpressionAddons
  4. 04涵盖 XML 视图中的 core:require

适用场景

  1. 01修复过时的枚举伪模块导入
  2. 02解决库未导出模块的问题
  3. 03移除隐式 OData 全局变量

安装

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

$npx skills add https://github.com/ui5/plugins-coding-agents --skill fix-pseudo-modules

安装后在 Claude Code 中输入/fix-pseudo-modules确认已加载。

详细介绍

修复伪模块和隐式全局变量

此技能用于修复 UI5 linter 检测到、但无法自动修复的伪模块访问和隐式全局变量问题,因为这些问题需要理解正确的模块导入模式。

处理的 Linter 规则

规则 ID消息模式此技能的处理方式
no-pseudo-modules已弃用的枚举伪模块“...”访问通过库模块导入
no-pseudo-modules已弃用的 DataType 伪模块“...”访问通过库模块导入
no-implicit-globals访问的模块“...”未由库“...”导出直接导入模块
no-implicit-globals不得隐式使用 OData 内置全局符号导入 ODataExpressionAddons

何时使用

当你看到类似以下内容的 linter 输出时,应用此技能:

MyController.js:5:5 error Deprecated access of enum pseudo module 'sap/ui/core/BarColor'  no-pseudo-modules
MyController.js:8:5 error Deprecated access of DataType pseudo module 'sap/ui/core/CSSSize'  no-pseudo-modules
MyController.js:15:5 error Access of module 'sap/ui/unified/DateRange' not exported by library 'sap/ui/unified/library'  no-implicit-globals
MyView.view.xml:20:5 error OData built-in global symbols must not be used implicitly  no-implicit-globals

背景:伪模块

在 UI5 中,枚举和 DataType 过去会像模块一样访问(例如,sap/ui/core/BarColor)。这些是“伪模块”——它们不是实际存在的文件,而是在运行时通过库模块解析。在现代 UI5 中,直接导入伪模块已弃用。

修复策略

1. 枚举伪模块访问

问题:将枚举作为直接模块导入。

// Before - triggers no-pseudo-modules
sap.ui.define([
    "sap/ui/core/mvc/Controller",
    "sap/ui/core/BarColor",           // Pseudo module!
    "sap/m/ListSeparators"            // Pseudo module!
], function(Controller, BarColor, ListSeparators) {
    "use strict";

    return Controller.extend("my.app.controller.Main", {
        onInit: function() {
            var color = BarColor.Positive;
            var separator = ListSeparators.All;
        }
    });
});

修复策略:从库模块导入,并将枚举作为属性访问。

// After - import from library
sap.ui.define([
    "sap/ui/core/mvc/Controller",
    "sap/ui/core/library",           // Import library
    "sap/m/library"                  // Import library
], function(Controller, coreLibrary, mLibrary) {
    "use strict";

    // Extract enums from library
    var BarColor = coreLibrary.BarColor;
    var ListSeparators = mLibrary.ListSeparators;

    return Controller.extend("my.app.controller.Main", {
        onInit: function() {
            var color = BarColor.Positive;
            var separator = ListSeparators.All;
        }
    });
});

常见枚举伪模块及其所属库:

伪模块库模块枚举访问方式
sap/ui/core/BarColorsap/ui/core/librarycoreLibrary.BarColor
sap/ui/core/ValueStatesap/ui/core/librarycoreLibrary.ValueState
sap/ui/core/TextDirectionsap/ui/core/librarycoreLibrary.TextDirection
sap/ui/core/TextAlignsap/ui/core/librarycoreLibrary.TextAlign
sap/ui/core/MessageTypesap/ui/core/librarycoreLibrary.MessageType
sap/m/ListSeparatorssap/m/librarymLibrary.ListSeparators
sap/m/ListModesap/m/librarymLibrary.ListMode
sap/m/ListTypesap/m/librarymLibrary.ListType
sap/m/ButtonTypesap/m/librarymLibrary.ButtonType
sap/m/InputTypesap/m/librarymLibrary.InputType
2. DataType 伪模块访问

问题:将 DataType 作为直接模块导入。

// Before - triggers no-pseudo-modules
sap.ui.define([
    "sap/ui/core/mvc/Controller",
    "sap/ui/core/CSSSize"            // DataType pseudo module!
], function(Controller, CSSSize) {
    "use strict";

    return Controller.extend("my.app.controller.Main", {
        // Using CSSSize type
    });
});

修复策略:从库模块导入。

// After - import from library
sap.ui.define([
    "sap/ui/core/mvc/Controller",
    "sap/ui/core/library"
], function(Controller, coreLibrary) {
    "use strict";

    var CSSSize = coreLibrary.CSSSize;

    return Controller.extend("my.app.controller.Main", {
        // Using CSSSize type
    });
});

常见 DataType 伪模块:

伪模块库模块
sap/ui/core/CSSSizesap/ui/core/library
sap/ui/core/CSSColorsap/ui/core/library
sap/ui/core/URIsap/ui/core/library
sap/ui/core/IDsap/ui/core/library
sap/ui/core/Percentagesap/ui/core/library
3. 通过库访问隐式全局变量

问题:通过库导出访问实际上并未导出的模块。

// Before - triggers no-implicit-globals
sap.ui.define([
    "sap/ui/unified/library",
    "sap/ui/core/library"
], function(unifiedLibrary, coreLibrary) {
    "use strict";

    // These modules are NOT exported by the library!
    var DateRange = unifiedLibrary.DateRange;              // Error
    var DOMAttribute = coreLibrary.tmpl.DOMAttribute;      // Error
});

修复策略:直接导入模块。

// After - import modules directly
sap.ui.define([
    "sap/ui/unified/DateRange",           // Direct import
    "sap/ui/core/tmpl/DOMAttribute"       // Direct import
], function(DateRange, DOMAttribute) {
    "use strict";

    // Use directly
});

经验法则:

  • 枚举和 DataType:通过库模块访问(例如,library.EnumName)
  • 类/控件:直接导入(例如,sap/ui/unified/DateRange)
4. OData 表达式附加项

问题:在表达式绑定中使用 OData 内置函数,却未导入。

// Before - triggers no-implicit-globals
sap.ui.define([
    "sap/ui/core/mvc/Controller",
    "sap/m/Text"
], function(Controller, Text) {
    "use strict";

    return Controller.extend("my.app.controller.Main", {
        onInit: function() {
            var oText = new Text({
                // Using odata.compare without import!
                text: "{= odata.compare(${/value1}, ${/value2}) }"
            });
        }
    });
});

修复策略:导入 ODataExpressionAddons 模块。

// After - import ODataExpressionAddons
sap.ui.define([
    "sap/ui/core/mvc/Controller",
    "sap/m/Text",
    "sap/ui/model/odata/ODataExpressionAddons"  // Required for odata.* functions
], function(Controller, Text, ODataExpressionAddons) {
    "use strict";

    return Controller.extend("my.app.controller.Main", {
        onInit: function() {
            var oText = new Text({
                // Now works - ODataExpressionAddons is imported
                text: "{= odata.compare(${/value1}, ${/value2}) }"
            });
        }
    });
});

需要导入的 OData 函数:

OData 函数可替代的直接模块
odata.comparesap/ui/model/odata/v4/ODataUtils
odata.fillUriTemplatesap/ui/thirdparty/URITemplate
odata.uriEncodesap/ui/model/odata/ODataUtils

注意:导入 sap/ui/model/odata/ODataExpressionAddons 是最简单的解决方案,因为它会注册所有 OData 表达式函数。

5. XML 视图中的 OData 函数

问题:在 XML 视图绑定中使用 OData 函数,却未导入。


<mvc:View
    xmlns:mvc="sap.ui.core.mvc"
    xmlns="sap.m">
    <Text text="{= odata.compare(${/price1}, ${/price2}) }" />
</mvc:View>

修复策略:为 ODataExpressionAddons 添加 core:require。


<mvc:View
    xmlns:mvc="sap.ui.core.mvc"
    xmlns="sap.m"
    xmlns:core="sap.ui.core"
    core:require="{
        ODataAddons: 'sap/ui/model/odata/ODataExpressionAddons'
    }">
    <Text text="{= odata.compare(${/price1}, ${/price2}) }" />
</mvc:View>

实施步骤

  1. 识别问题类型,查看 linter 消息:

    • “enum pseudo module” → 从库中导入
    • “DataType pseudo module” → 从库中导入
    • “not exported by library” → 直接导入模块
    • “OData built-in global” → 导入 ODataExpressionAddons
  2. 确定枚举/DataType 对应的库:

    • 检查模块路径前缀(例如,sap/ui/core/ → sap/ui/core/library)
  3. 更新导入:

    • 为枚举/DataType 添加库导入
    • 为类添加直接模块导入
    • 为 OData 函数添加 ODataExpressionAddons
  4. 更新代码引用:

    • 从库中提取枚举/DataType:var EnumName = library.EnumName;
    • 直接使用导入的模块
  5. 对于 XML 视图:在需要时添加 core:require

修复示例

以下面的 linter 输出为例:

MyController.js:3:5 error Deprecated access of enum pseudo module 'sap/ui/core/ValueState'  no-pseudo-modules
MyController.js:4:5 error Access of module 'sap/ui/unified/DateRange' not exported by library 'sap/ui/unified/library'  no-implicit-globals
MyController.js:25:5 error OData built-in global symbols must not be used implicitly  no-implicit-globals

之前:

sap.ui.define([
    "sap/ui/core/mvc/Controller",
    "sap/ui/core/ValueState",
    "sap/ui/unified/library"
], function(Controller, ValueState, unifiedLibrary) {
    "use strict";

    var DateRange = unifiedLibrary.DateRange;  // Error: not exported

    return Controller.extend("my.app.controller.Main", {
        onInit: function() {
            var state = ValueState.Error;

            var oDateRange = new DateRange({
                startDate: new Date()
            });
        },

        formatComparison: function() {
            return "{= odata.compare(${/val1}, ${/val2}) }";  // Error: no import
        }
    });
});

之后:

sap.ui.define([
    "sap/ui/core/mvc/Controller",
    "sap/ui/core/library",                          // For ValueState enum
    "sap/ui/unified/DateRange",                     // Direct import
    "sap/ui/model/odata/ODataExpressionAddons"      // For odata.* functions
], function(Controller, coreLibrary, DateRange, ODataExpressionAddons) {
    "use strict";

    var ValueState = coreLibrary.ValueState;  // Extract from library

    return Controller.extend("my.app.controller.Main", {
        onInit: function() {
            var state = ValueState.Error;

            var oDateRange = new DateRange({
                startDate: new Date()
            });
        },

        formatComparison: function() {
            return "{= odata.compare(${/val1}, ${/val2}) }";  // Now works
        }
    });
});

备注

  • 库模块只导出枚举和 DataType,不导出类/控件
  • 始终通过完整模块路径直接导入控件和类
  • 即使不直接使用变量,也需要导入 ODataExpressionAddons——它会在加载时注册函数
  • 弃用伪模块有助于识别不恰当的依赖项,并改进加载时间优化

相关技能

  • fix-js-globals:对于其他 JavaScript 全局访问模式(JS 文件上的 no-globals——例如,sap.ui.getCore()、jQuery、sap.ui.controller()),请使用 fix-js-globals
  • fix-control-renderer:如果渲染器代码中出现伪模块错误,并伴有渲染器特有的问题,请使用 fix-control-renderer 进行渲染器现代化处理

评论

支持 Markdown