mcpField
F
fix-pseudo-modules

fix-pseudo-modules

github.com/ui5開発44140 回インストール1 週間前に更新
リポジトリ

fix-pseudo-modules について

疑似モジュールや暗黙のグローバルに関するリンター指摘を解決する、UI5 開発者向けのスキルです。列挙型のライブラリインポート、直接インポート、OData 式アドオンの使い方を説明します。

主な機能

  1. 01列挙型とデータ型をライブラリからインポート
  2. 02クラスとコントロールを直接インポート
  3. 03OData 関数用に ODataExpressionAddons を追加
  4. 04XML ビューの 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 リンターが検出するものの、適切なモジュールのインポートパターンを理解する必要があるため自動修正できない、疑似モジュールへのアクセスと暗黙的なグローバルの問題を修正します。

対応するリンタールール

ルール IDメッセージパターンこのスキルでの対応
no-pseudo-modules列挙型の疑似モジュール '...' への非推奨のアクセスライブラリモジュール経由でインポート
no-pseudo-modulesDataType 疑似モジュール '...' への非推奨のアクセスライブラリモジュール経由でインポート
no-implicit-globalsモジュール '...' へのアクセスが、ライブラリ '...' からエクスポートされていないモジュールを直接インポート
no-implicit-globalsOData の組み込みグローバルシンボルを暗黙的に使用してはならないODataExpressionAddons をインポート

使用するタイミング

次のようなリンターの出力が表示された場合に、このスキルを適用してください。

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. リンターのメッセージから問題の種類を特定します。

    • 「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 を追加します

修正セッションの例

次のリンター出力がある場合:

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 を使用します

コメント