mcpField
M
modernize-flp-sandbox

modernize-flp-sandbox

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

modernize-flp-sandbox について

旧 FLP sandbox から New Sandbox へ移行する UI5 開発者向けのスキルです。中核の変換を自動化し、テスト基盤を確認して、関連する問題は別途報告します。

主な機能

  1. 01旧 sandbox ファイルの分析
  2. 02HTML と設定の変換
  3. 03フックモジュールの作成・書き換え
  4. 04OPA テスト配線の更新
  5. 05移行上の不足事項の報告

活用シーン

  1. 01UI5 アプリの New Sandbox への移行
  2. 02複数 sandbox シナリオの統合
  3. 03OPA テスト配線の復旧
  4. 04非推奨 ushell サービス利用の検出

インストール

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

$npx skills add https://github.com/ui5/plugins-coding-agents --skill modernize-flp-sandbox

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

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

references/
native-replacements.md
operations.md
sandbox-config-surface.md

詳細

新しいサンドボックスへの移行スキル

UI5 アプリケーションをレガシー FLP サンドボックスから New Sandbox に移行します。 分析、変換、検証を行い、結果を報告します。このスキルはコア移行を完全に自動で実行しますが、関連する懸念事項(下記のスコープを参照)については、実行前に利用者に確認します。

今すぐ references/operations.md を読み込んでください。これは、すべての HTML/JSON/フックモジュール変換に関する運用リファレンスです。

今すぐ references/sandbox-config-surface.md を読み込んでください。これは、New Sandbox が許可、ブロック、または無言で上書きする内容についての信頼できる説明です。 §6 のすべてのルールでは、制約を本文中で繰り返す代わりに、このファイルを参照します。

スコープ — 3 つのレイヤー

  1. コア移行 — アプリを New Sandbox で起動するために必要な操作です。無条件に実行し、実行できない場合は移行に失敗します。トリガー:§6a、§6b、§6c、§6f。

  2. テストインフラストラクチャ — テストのセマンティクスを変更せずに、テストスイートを再び実行できるようにします。安全な書き換え(リソースルートの再バインド、OPA のブートストラップ抽出)は無条件に適用します。テストロジックに関わる変更は、検出して報告し、要望があった場合に提案します。トリガー:§6d、§6e、§6g、§6h、§6j、§6l。

  3. 関連する移行と注意事項 — 移行によって明らかになったものの、移行そのものには含まれない懸念事項です。検出して報告するだけで、書き換えは適用しません。

    • QUnit 1.x → 2.x のパターン(§6i)— 注意事項。
    • シェル機能のテスト(§6j、§6l)— 注意事項。
    • 非推奨の ushell サービス(§6k)— コアのパスで検出し、「手動での対応が必要」として報告します(実行時の重大なブロック要因)。

1. アプリのルートを検出する

ユーザーがパス引数を指定した場合は、そのパスを使用します。それ以外の場合は、CWD から検出します。

  • CWD および親ディレクトリで package.json と webapp/ を検索します。
  • 見つからない場合は、ユーザーに次のように伝えます:"UI5 アプリのルートを検出できませんでした。アプリのディレクトリ内で実行するか、パスを指定してください:/modernize-flp-sandbox ~/path/to/app"

APP_ROOT に解決済みの絶対パスを設定します。

2. クリーンな状態を確保する(移行前)

ファイルに触れる前に、ロールバックできる状態を確保します。

git リポジトリが検出された場合:

cd $APP_ROOT
git stash push -m "modernize-flp-sandbox: pre-migration backup $(date +%Y%m%d-%H%M%S)"

ロールバック用に stash の参照を保存します。stash するものがなければ、すでに作業ツリーはクリーンです。

git リポジトリがない場合:

mkdir -p $APP_ROOT/webapp/test/.migration-backup
cp $APP_ROOT/webapp/test/flpSandbox*.html $APP_ROOT/webapp/test/.migration-backup/ 2>/dev/null
cp $APP_ROOT/webapp/test/fioriSandboxAppConfig.json $APP_ROOT/webapp/test/.migration-backup/ 2>/dev/null

3. 分析する

$APP_ROOT/webapp/test/ 以下のすべての HTML ファイルを(再帰的に)読み込み、パターンの一覧を作成します。

レガシーサンドボックスの HTML ファイルを検出する — 次のいずれかが含まれているファイルはレガシーです。

  • id="sap-ushell-bootstrap"(サンドボックスのブートストラップスクリプトタグ)
  • window["sap-ushell-config"] の代入
  • sandbox2.js を参照する src=(中間形式の New Sandbox における旧形式のブートストラップ。SandboxBootTask.js より前の形式です。他のレガシーパターンと同様に扱います)

OPA テストページ(SandboxBootTask/boot-manifest を受け取りません): レガシー検出に該当し、さらに次のすべてを含むファイルです。

  • QUnit.config または QUnit.config.autostart の代入、あるいは window.QUnit = {
  • sap/ui/qunit/、sap/ui/test/、または sap/ui/thirdparty/qunit のエントリーを含む sap.ui.require(

これらのファイルはサンドボックス HTML として移行しません。代わりに、次の処理を行います。(a)§6g に従ってブートストラップを兄弟 JS ファイルに抽出します。(b)§6i で QUnit 1.x を検出し、同意が得られた場合はサブスキルに引き継ぎます。§6g の HTML 編集では、次の処理を行います。

  • <script src="../ushellConfig.js"> と <script src="...sandbox.js" id="sap-ushell-bootstrap"> を削除します。
  • インラインの QUnit/OPA ブートストラップを、スクリプトタグによる直接読み込み(qunit-2.css、qunit-2.js、qunit-junit.js)と <script src="AllJourneys.js"> に置き換えます。
  • インラインコンテンツから AllJourneys.js を作成します(§6g を参照)。
  • data-sap-ui-preload="async" を data-sap-ui-async="true" に、data-sap-ui-compatVersion を data-sap-ui-compat-version に、data-sap-ui-resourceroots を data-sap-ui-resource-roots に更新します。
  • SandboxBootTask.js、boot-manifest、または <div id="canvas"> は追加しません。 外部化された ushell 設定の検出: webapp/test/ 配下のすべての HTML にある各 <script src="..."> について、参照先ファイルに ushell 設定オブジェクトへの 代入 が含まれているか確認します。
  • window["sap-ushell-config"] = … / globalThis[…] / self[…]
  • Object.assign(<global>["sap-ushell-config"], …)
  • <global>["sap-ushell-config"].<prop> = …(初期化後のプロパティ書き込み)

設定を 読み取る だけのファイルは該当しません。該当する各ファイルを externalUshellConfigFile として記録します。移行時はインラインの場合と同じ方法で設定を解析し、参照しているすべての HTML から <script> の読み込みを削除し、Step 9 でファイルを削除します。

各レガシー HTML ファイルについて記録する項目:

  • ファイル名、モックサーバーの有無、RTA/LREP の有無、カスタムプラグインの有無、非推奨サービスの有無
  • locate-reuse-libs.js の有無(Gap-Report 用のフラグ)
  • 既存の data-sap-ui-libs、data-sap-ui-resourceroots/data-sap-ui-resource-roots、data-sap-ui-theme、data-sap-ui-language の値(引き継ぎ、ケバブケースに変更)

既存の New Sandbox アーティファクトを確認する:

  • fioriSandboxAppConfig.json — 存在するか(作成または上書きします)
  • sandbox/ ディレクトリ — 各 *.js ファイルを次のように分類します。
    • legacy:Container.createRendererInternal または attachRendererCreatedEvent を含む、または execute: を含まないファイル。インプレースで書き換えるための情報を取得します(§6c)。トップレベルの名前空間宣言を preservedDeclarations[] として取得します(正規表現:^\s*sap(\.[a-zA-Z0-9_]+)+\s*\?\?=\s*\{\} および globalThis.sap/window.sap チェーン。見つからない場合は、最初の sap.ui.define( または IIFE までをそのままコピーします)。
    • modern:{ execute: ... } をエクスポートするファイル。そのまま再利用します。
    • **複数のレガシーファイル:**すべて書き換えます。beforeFlpStart に接続するのは 1 つだけです。Init を含む名前を優先し(Mock は除外)、Gap-Report に注記します。
  • FakeLREP ファイル(webapp/test/ 配下の *Lrep*.json / *LRep*.json)— rta 参照用に正確なファイル名を記録します。

OPA テストの接続を確認する:

  • OPA テストランナー HTML(既定値は webapp/test/integration/opaTests.qunit.html。見つからない場合は、レガシーのモックサーバー HTML を参照する webapp/test/integration/ 配下の *qunit.html)— "../flpSandboxMockServer" に一致する値を記録します。§6d のトリガーになります。
  • OPA Common ヘルパーファイル(既定値は webapp/test/integration/pages/Common.js。見つからない場合は、iStartMyAppInAFrame(/getFrameUrl( と sap.ui.require.toUrl( の両方を含む webapp/test/integration/ 配下の *.js)— §6e のトリガーになります。

非推奨の ushell サービス使用状況をスキャンする: webapp/ 配下(test/、resources/、*.min.js を除く)の *.js から、references/sandbox-config-surface.md §5 に記載された 12 個の非推奨サービスのいずれかを <name> とする getService(<name>) / getServiceAsync(<name>) を検索します。ファイル、行、サービス名、バインドされた変数を記録します。Gap-Report(§8)に記載し、§6k でフォローアップします。

UI5 フレームワークのバージョンを確認する: ui5.yaml と ui5-local.yaml から framework.version を読み取ります。New Sandbox には 1.147 以上が必要です。それより低い場合は、自動で更新します。

  1. 1.147 以上の最新の安定版 SAPUI5 バージョンを検索します。
  2. ui5.yaml をその場で更新します。
  3. 次のようにログに記録します。"Auto-bumped ui5.yaml framework version from <old> to <new> (New Sandbox requires >= 1.147)."
  4. Gap-Report に注記します。

3a. フックの依存関係グラフのスキャン

beforeFlpStart フックから到達可能な推移的 AMD グラフ内の eager な sap/ushell/* インポートを特定します(ハード制約 H2 — references/sandbox-config-surface.md §1 を参照)。詳細と書き換え手順は references/operations.md §6f にあります。

この手順ではインベントリのみを作成します。 実際の処理は §6c でフックを生成した後、§6f で行います。

次の項目を記録します。

  1. hookEntryModule — 既存の fioriSandboxAppConfig.json の beforeFlpStart から解決するか、§3 のレガシーフックから検出します(通常は webapp/test/sandbox/fioriSandboxInit.js)。
  2. hookGraphRoots[] — フック本体を調べ、フックが直接必要とする追加モジュールを記録します。

4. シナリオウィザード(複数の flp*.html が見つかった場合のみ)

レガシーサンドボックス HTML が 1 つだけ見つかった場合は、スキップします。

新しいサンドボックスでは fioriSandboxAppConfig.json を 1 つだけ使用するため、複数の HTML ファイルに独立した設定を持たせることはできません。解決策として、実行時にシナリオを選択する URL パラメーターを使い、1 つの HTML に統合します。

非対話モード: $APP_ROOT/webapp/test/wizard-answers.json を確認します。存在する場合は、その値を直接使用します(CI/スクリプトによる移行向け)。形式:

{
    "scenarios": [
        { "file": "flpSandbox.html", "id": "default", "description": "Live backend" },
        { "file": "flpSandboxMockServer.html", "id": "mockserver", "description": "Mock server" }
    ],
    "defaultScenario": "mockserver",
    "targetHtml": "flpSandbox.html",
    "paramName": "scenario"
}

ユーザーに質問します:

  1. 「各ファイルはどのシナリオを表していますか?」(例:「mockserver」、「cdm」、「default/no-mock」)
  2. 「どのシナリオをデフォルトにしますか?」(推奨:オフラインで動作する mockserver)
  3. 「どの HTML ファイル名を残しますか?」
  4. 「URL パラメーター名は何にしますか?」(デフォルト:scenario。プロジェクト固有の名前にすると競合を避けられます)

記録: 対象 HTML、シナリオ一覧、デフォルトのシナリオ ID、パラメーター名、不要な HTML ファイル。

URL の規則: flpSandbox.html?scenario=mockserver。パラメーターがない場合は、デフォルトのシナリオを使用します。選択した名前を README に記載します。

5. 移行前チェックリスト

ファイルを書き込む前に、APP_ROOT が設定されている(§1)、ロールバックが確保されている(§2)、インベントリが作成されている(§3)、必要な場合はウィザードの回答が用意されている(§4)ことを確認します。すべて問題なければ、§6 に進みます。

6. 移行

すべての変換を実行します。書き込みに失敗した場合は、ロールバック(§10)に進みます。

対象範囲 — 変更するファイル:

  • §3 で検出されたすべての flp*.html → 完全な変換(§6a–§6c)
  • OPA テストページの HTML → ブートストラップの抽出(§6g)
  • OPA テストランナーの HTML → リソースルートの再割り当て(§6d)
  • QUnit テストスイートのインデックス → journey URL の書き換え(§6g)
  • OPA Common-helper → URL パラメーターの注入(§6e)
  • webapp/test/fioriSandboxAppConfig.json → 作成/上書き(§6b)
  • webapp/test/sandbox/*.js のレガシーフック → インプレースで書き換え(§6c)
  • beforeFlpStart AMD グラフ内のファイル → references/native-replacements.md を自動適用(§6f)
  • webapp/test/integration/ 内の OPA テストコードとアプリコード → 機械的な書き換え(§6h–§6l)

対象外: unitTests.qunit.html、unit/、*.qunit.js。

opaTests.qunit.html が flpSandboxMockServer.html を参照している場合は、移行(§6a)と OPA 参照の再割り当て(§6d)をまとめて行います。

各サブセクションでは、対象/実施条件/対象レイヤーを説明します。完全なアルゴリズムは references/operations.md に記載されています。

6a. レガシー HTML ファイルをインプレースで変換する

レイヤー: コア。すべてのレガシーサンドボックス HTML に対して無条件に実行します。

レガシーの ushell-config 書き込み、sap-ushell-bootstrap スクリプトタグ、不要なブートストラップ属性を削除します。SandboxBootTask.js(または CDN 版)、ブートマニフェスト属性、<div id="canvas"> を追加します。バリアント間でリソースルートを統合し、常に sandbox ルートを追加します。

→ references/operations.md §6a

6b. fioriSandboxAppConfig.json を作成または更新する

レイヤー: コア。references/sandbox-config-surface.md §2 に記載されたキーのみを対象とします。

解析したレガシー設定から JSON を作成します。アプリケーションキーを最初の - で分割し、semanticObject と action にします。rootPath からクエリー文字列を削除し、末尾にスラッシュを付けます。ウィザードを実行した場合は、バリアント間でタイルを集約します。必要な場合に限り、beforeFlpStart、rta、plugins を追加します。

→ references/operations.md §6b

6c. フックモジュールを作成または書き換える

レイヤー: コア。beforeFlpStart をサポートし、applyUshellConfig の前に実行します。契約:globalThis["sap-ushell-config"] に触れないこと、sap/ushell/* を先行して require しないこと(references/sandbox-config-surface.md §8 を参照)。

単一シナリオのフック(モックサーバーのみ)または複数シナリオのフック(URL パラメーターによる切り替え)を生成します。名前空間宣言を保持したまま、レガシーフックをインプレースで書き換えます。モックサーバーが不要な場合は、最小限の何もしないフックにフォールバックします。

→ references/operations.md §6c

6d. OPA リソースルートの再バインド

レイヤー: テストインフラ。無条件(セマンティクスの変更なし)。

OPA テストランナーの HTML 内で、旧モックサーバーの HTML を指している data-sap-ui-resource-roots を移行先を指すように書き換えます。

→ references/operations.md §6d

6e. Common.js へのシナリオ URL パラメーターの挿入

レイヤー: テストインフラ。Wizard によって複数の HTML が統合された場合のみ。

iframe の URL の # ハッシュより前にシナリオパラメーターを挿入します(これにより、window.location.search で取得できます)。

→ references/operations.md §6e

6f. フックグラフの ushell 依存関係の解決

レイヤー: コア。ハードランタイムブロック H2 — フックの推移的な AMD グラフから sap/ushell/* を先行して require することはできません。

hookEntryModule(§3a)から AMD のクロージャーをたどります。各 sap/ushell/* の該当箇所を、簡単に置き換え可能/アーキテクチャ上の移設が必要/手動対応が必要に分類します。references/native-replacements.md のレシピを自動適用するか、Gap-Report の項目を出力します。

→ references/operations.md §6f

6g. OPA ブートストラップの兄弟 JS ファイルへの抽出

レイヤー: テストインフラ。機械的な抽出。

インラインの <script> ブロックを兄弟 .js ファイル(デフォルトでは AllJourneys.js)に抽出します。QUnit 1.x のグローバル変数と jQuery.sap.getUriParameters を最新の同等機能に変換します。テストスイートのインデックスを、URLSearchParams 形式のジャーニー URL に更新します。

→ references/operations.md §6g

6h. 旧 ushell-config の値へのバインディングの検出

レイヤー: テストインフラ(機械的に自動修正できる場合は自動修正し、それ以外は報告)。

旧設定では自由形式だったものの、New Sandbox では別の方法で導出される値をコード内にハードコードしている箇所を特定します。カテゴリは、A タイルから導出(自動修正)、B ユーザープロファイル(自動修正)、C パーソナライズ(自動修正)、D デフォルトで固定(報告のみ)です。references/sandbox-config-surface.md §3+§4 を参照してください。

→ references/operations.md §6h

6i. QUnit 1.x → 2.x パターン(引き継ぎ)

レイヤー: アドバイザリー。実際の書き換えは modernize-flp-sandbox-qunit サブスキルで行います。

検出して報告し、サブスキルの実行を提案します。これを表面化する理由:§6a で data-sap-ui-async="true" を追加すると、このモードでは QUnit 1.x のグローバル変数(module、ok、equal)が ReferenceError をスローします。根本原因はサンドボックスの移行とは独立しており、移行によって顕在化するだけです。

→ references/operations.md §6i

6j. FLP シェルコントロールへの対応(報告)

レイヤー: テストインフラ(報告のみ)。FLP シェルコントロールを直接対象とする OPA テストを検出します。新しい UI5 ではシェルが Web Components 経由でレンダリングされるため、sap.m.* シェルコントロールに一致するテストは、エラーを示さずに失敗します。

パターン:S1 = sap.m コントロールとシェル専用 ID、S2 = type:"Back" マッチャー、S3 = Web Component ではないシェルヘッダー呼び出し。

→ references/operations.md §6j

6k. アプリコード内の非推奨 ushell サービス(検出)

レイヤー: コア検出。非推奨のサービスはすべて、getService()/getServiceAsync() の実行時にハードランタイムブロックになります(references/sandbox-config-surface.md §5 を参照)。アプリは起動しません。

アプリコードをスキャンし、該当箇所を記録して、「手動対応が必要」として Gap-Report に表示します。書き換えは行いません。

→ references/operations.md §6k

6l. FLP シェル機能を利用する OPA テスト(検出+確認)

レイヤー: test-infra(検出+確認)。FLP シェルに依存するジャーニーテストを検出します。認識可能な iframe 切り替えパターンが存在する場合にのみ、修正の適用を提案します。同意なしに変更することはありません。

シグナル:シェル制御セレクター(§6j)、非推奨のサービス呼び出し(§6k)、慣例に基づく名前のページオブジェクトメソッド。 プローブ:P1 = startMyAppInAFrame フラグ、P2 = iStartMyAppInAFrame ヘルパー、P3 = 独自の iframe URL ビルダー。

→ references/operations.md §6l

8. レポート

必ず Gap-Report を出力してください。

== New Sandbox Migration Report ==

App:    <app name from package.json>
Path:   <APP_ROOT>
Status: ✓ SUCCESSFUL  |  ✗ FAILED

── Automatically applied ──────────────────────────────────────────────
  ✓/✗  webapp/test/<filename>.html              (HTML transformed)
  ✓/✗  webapp/test/fioriSandboxAppConfig.json   (created)
  ✓/—  webapp/test/sandbox/<hookModule>.js      (created / reused / rewrote-legacy)
  ✓/—  rta: "<fakeLRep filename>"               (written to config)
  ✓/—  opaTests.qunit.html                      (resource root rebound)
  ✓/—  Common.js                                (scenario URL param injected)
  ✓/—  Hook-graph: <N> trivial replacement(s) auto-applied

── Manual action required ─────────────────────────────────────────────
  ✗  <ServiceName> (deprecated — hard runtime error): <file>:<line>
     → <successor from sandbox-config-surface.md §5>

  ✗  Custom FakeLrep connector at <path>
     → May have sap/ushell dependencies incompatible with beforeFlpStart.

  ✗  Hook-graph — architectural-relocatable: <module> uses <sap/ushell/X>
     → [diff sketch]

  ✗  Hook-graph — manual-required: <module> uses <sap/ushell/X> at load time
     → [textual sketch]

  ✗  <Layer-2 step> — pattern not recognised
     → [description]

── Advisory (no migration blocker) ───────────────────────────────────
  ℹ  <N> QUnit 1.x pattern(s) in <M> file(s)
  ℹ  Shell-control test patterns: <N> in <M> files (S1: ?, S2: ?, S3: ?)
  ℹ  locate-reuse-libs.js: script tag removed — deprecated pattern, safe.
  ℹ  <other non-standard patterns>

[On failure: "Rolled back. Partial attempt saved to webapp/test/.migration-attempt/"]

検出結果のないセクションはレポートから省略されます。

9. レガシーファイルのクリーンアップ(必須 — 省略禁止)

  • ウィザードを使用しない場合: レガシー HTML はその場で変換されるため、削除する追加ファイルはありません。
  • ウィザードを使用した場合: 古い HTML ファイルをすべて削除します(対象ファイルを除く)。
  • 常に: 各 externalUshellConfigFile[] を削除します。
rm <obsolete-file-1> <obsolete-file-2> ...

確認: ls webapp/test/flp*.html — 移行済みの対象ファイルだけが残っていることを確認します。

10. ロールバック

§6 の実行中に失敗した場合:

途中までの作業を保存:

mkdir -p $APP_ROOT/webapp/test/.migration-attempt
cp $APP_ROOT/webapp/test/*.html $APP_ROOT/webapp/test/.migration-attempt/ 2>/dev/null
cp $APP_ROOT/webapp/test/fioriSandboxAppConfig.json $APP_ROOT/webapp/test/.migration-attempt/ 2>/dev/null

復元:

  • Git の場合:git checkout -- webapp/test/ && git stash pop
  • Git を使用していない場合:cp $APP_ROOT/webapp/test/.migration-backup/* $APP_ROOT/webapp/test/

ステータスを FAILED として Gap-Report を出力します。

コメント