mcpField
F
fix-library-init

fix-library-init

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

fix-library-init について

UI5 Linterが非推奨とするライブラリ初期化を修正する開発スキルです。必須の数値 `apiVersion: 2` を追加し、`DataType.registerEnum` による列挙型登録への変更を案内します。

主な機能

  1. 01Library.init()呼び出しの修正
  2. 02数値apiVersion: 2の追加
  3. 03複数の引数形式への対応
  4. 04列挙型登録の更新ガイド

活用シーン

  1. 01UI5 Linterの初期化警告の解消
  2. 02UI5ライブラリ初期化コードの更新

インストール

コマンドをコピーしてターミナルで実行します。

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

インストール後、Claude Code で/fix-library-initを入力して読み込まれたか確認します。

詳細

Library.init() の最新化

このスキルは、UI5 リンターが apiVersion: 2 の指定漏れを検出した Library.init()/Lib.init() の呼び出しを修正し、apiVersion: 2 の使用時に必要となる DataType.registerEnum を使った列挙型の定義に最新化します。

対応するリンタールール

ルール IDメッセージパターンこのスキルの対応
no-deprecated-apiDeprecated call to Library.init(). Use the {apiVersion: 2} parameter insteadinit 呼び出しに apiVersion: 2 を追加します
no-deprecated-apiDeprecated call to Lib.init(). Use the {apiVersion: 2} parameter insteadinit 呼び出しに apiVersion: 2 を追加します
no-deprecated-apiDeprecated call to init(). Use the {apiVersion: 2} parameter insteadapiVersion: 2 を追加します(分割代入された init)

使用する場面

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

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

リンターは次のパターンも検出します。

// 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 を使うように最新化する必要があります。

列挙型の見つけ方
  1. Lib.init() 呼び出しの types 配列を確認します。この配列には、ライブラリで定義されているすべての型(列挙型)の完全修飾名が含まれます
  2. グローバル名前空間への代入を検索します。例:ライブラリの名前空間が my.lib の場合の my.lib.ValueColor = { ... }
  3. 文字列のキーと値のペアを持つプレーンオブジェクトとして定義された既存の列挙型オブジェクトを探します
最新化の手順
  1. まだ行っていない場合は、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"] });
    
  2. 列挙型の定義をグローバル名前空間からライブラリオブジェクトに移します。

    // Before — global namespace
    my.lib.ValueColor = { Color1: "Color1", Color2: "Color2" };
    
    // After — on library object
    oThisLibrary.ValueColor = { Color1: "Color1", Color2: "Color2" };
    
  3. 各列挙型の定義の直後に DataType.registerEnum の呼び出しを追加します。

    oThisLibrary.ValueColor = { Color1: "Color1", Color2: "Color2" };
    DataType.registerEnum("my.lib.ValueColor", oThisLibrary.ValueColor);
    
  4. まだ追加されていない場合は、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;
});

実装手順

  1. --details を付けてリンターを実行し、追加のコンテキストを確認します。

    npx @ui5/linter --details
    
  2. library.js ファイルを読み、次の点を確認します。

    • Lib.init() / Library.init() の呼び出しと、現在の引数
    • 戻り値が変数に格納されているかどうか
    • 列挙型の定義(types 配列とグローバル名前空間への割り当てを確認)
  3. apiVersion を修正します。

    • 引数がない場合:{ apiVersion: 2 } を追加します
    • apiVersion を含まないオブジェクトの場合:最初のプロパティとして apiVersion: 2 を追加します
    • apiVersion の値または型が誤っている場合:数値の 2 に変更します
  4. 列挙型を最新の形式にします(存在する場合)。

    • まだ行われていない場合は、Lib.init() の戻り値を変数に格納します
    • 各列挙型をグローバル名前空間からライブラリオブジェクトに移動します
    • 各列挙型に対して DataType.registerEnum の呼び出しを追加します
    • 依存関係のリストに sap/ui/base/DataType を追加します
  5. モジュールがライブラリオブジェクトを返すことを確認します(return oThisLibrary;)。

  6. リンターを再実行して、修正を検証します。

注意事項

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

コメント