UI5 リンター(構文チェックツール)が検出するが自動修正できない疑似モジュール(実体のない架空のモジュール)とグローバル変数の問題を修正します。 **次のような場合に使用:** - リンターの `no-pseudo-modules` エラーで、非推奨の列挙型(決められた値の集合)またはデータ型の疑似モジュールへのアクセスについてのメッセージが出力される - リンターの `no-implicit-globals` エラーで、ライブラリが未公開のモジュールまたは OData(データ連携技術)のグローバル変数についてのメッセージが出力される **検出対象:** - 列挙型の直接インポート(例: sap/ui/core/BarColor) - データ型の直接インポート(例: sap/ui/core/CSSSize) - ライブラリ.列挙型名 へのアクセス - バインディング内の odata.compare / fillUriTemplate / uriEncode の使用 **機能:** 列挙型、データ型、OData 式の拡張機能に対する正しいモジュールインポート方法について、改善案を提示します。
Fix pseudo module and implicit global issues that UI5 linter reports but cannot auto-fix. Use this skill when linter outputs: - `no-pseudo-modules` with messages about deprecated enum or DataType pseudo module access - `no-implicit-globals` with messages about module not exported by library or OData globals Trigger on: direct enum imports (sap/ui/core/BarColor), direct DataType imports (sap/ui/core/CSSSize), library.EnumName access, odata.compare/fillUriTemplate/uriEncode in bindings. Provides guidance on proper module imports for enums, DataTypes, and OData expression addons.
このスキルは、UI5 linter が検出するものの、適切なモジュールインポートパターンの理解が必要なため自動修正できない、疑似モジュールアクセスおよび暗黙的グローバルの問題を修正します。
| ルール ID | メッセージパターン | このスキルの対応 |
|---|---|---|
no-pseudo-modules |
Deprecated access of enum pseudo module '...' | ライブラリモジュール経由でインポート |
no-pseudo-modules |
Deprecated access of DataType pseudo module '...' | ライブラリモジュール経由でインポート |
no-implicit-globals |
Access of module '...' not exported by library '...' | モジュールを直接インポート |
no-implicit-globals |
OData built-in global symbols must not be used implicitly | 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 では、enum や DataType は歴史的にモジュールとして扱われ(例: sap/ui/core/BarColor)、直接インポートされてきました。
これらは「疑似モジュール」と呼ばれ、実際のファイルとしては存在せず、ランタイム時にライブラリモジュールから解決されます。
モダンな UI5 では、疑似モジュールの直接インポートは非推奨となっています。
問題: enum を直接モジュールとしてインポートしている。
// 修正前 - no-pseudo-modules をトリガー
sap.ui.define([
"sap/ui/core/mvc/Controller",
"sap/ui/core/BarColor", // 疑似モジュール!
"sap/m/ListSeparators" // 疑似モジュール!
], function(Controller, BarColor, ListSeparators) {
"use strict";
return Controller.extend("my.app.controller.Main", {
onInit: function() {
var color = BarColor.Positive;
var separator = ListSeparators.All;
}
});
});
修正戦略: ライブラリモジュールからインポートし、enum をプロパティとしてアクセスする。
// 修正後 - ライブラリからインポート
sap.ui.define([
"sap/ui/core/mvc/Controller",
"sap/ui/core/library", // ライブラリをインポート
"sap/m/library" // ライブラリをインポート
], function(Controller, coreLibrary, mLibrary) {
"use strict";
// ライブラリから enum を取り出す
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;
}
});
});
よく使われる enum 疑似モジュールと対応ライブラリ:
| 疑似モジュール | ライブラリモジュール | enum アクセス |
|---|---|---|
sap/ui/core/BarColor |
sap/ui/core/library |
coreLibrary.BarColor |
sap/ui/core/ValueState |
sap/ui/core/library |
coreLibrary.ValueState |
sap/ui/core/TextDirection |
sap/ui/core/library |
coreLibrary.TextDirection |
sap/ui/core/TextAlign |
sap/ui/core/library |
coreLibrary.TextAlign |
sap/ui/core/MessageType |
sap/ui/core/library |
coreLibrary.MessageType |
sap/m/ListSeparators |
sap/m/library |
mLibrary.ListSeparators |
sap/m/ListMode |
sap/m/library |
mLibrary.ListMode |
sap/m/ListType |
sap/m/library |
mLibrary.ListType |
sap/m/ButtonType |
sap/m/library |
mLibrary.ButtonType |
sap/m/InputType |
sap/m/library |
mLibrary.InputType |
問題: DataType を直接モジュールとしてインポートしている。
// 修正前 - no-pseudo-modules をトリガー
sap.ui.define([
"sap/ui/core/mvc/Controller",
"sap/ui/core/CSSSize" // DataType 疑似モジュール!
], function(Controller, CSSSize) {
"use strict";
return Controller.extend("my.app.controller.Main", {
// CSSSize 型を使用
});
});
修正戦略: ライブラリモジュールからインポートする。
// 修正後 - ライブラリからインポート
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", {
// CSSSize 型を使用
});
});
よく使われる DataType 疑似モジュール:
| 疑似モジュール | ライブラリモジュール |
|---|---|
sap/ui/core/CSSSize |
sap/ui/core/library |
sap/ui/core/CSSColor |
sap/ui/core/library |
sap/ui/core/URI |
sap/ui/core/library |
sap/ui/core/ID |
sap/ui/core/library |
sap/ui/core/Percentage |
sap/ui/core/library |
問題: ライブラリのエクスポートを介してモジュールにアクセスしているが、そのモジュールは実際にはエクスポートされていない。
// 修正前 - no-implicit-globals をトリガー
sap.ui.define([
"sap/ui/unified/library",
"sap/ui/core/library"
], function(unifiedLibrary, coreLibrary) {
"use strict";
// これらのモジュールはライブラリからエクスポートされていない!
var DateRange = unifiedLibrary.DateRange; // エラー
var DOMAttribute = coreLibrary.tmpl.DOMAttribute; // エラー
});
修正戦略: モジュールを直接インポートする。
// 修正後 - モジュールを直接インポート
sap.ui.define([
"sap/ui/unified/DateRange", // 直接インポート
"sap/ui/core/tmpl/DOMAttribute" // 直接インポート
], function(DateRange, DOMAttribute) {
"use strict";
// そのまま使用
});
判断の基準:
library.EnumName)sap/ui/unified/DateRange)問題: expression binding で OData 組み込み関数を使用しているが、インポートしていない。
// 修正前 - 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({
// インポートなしで odata.compare を使用!
text: "{= odata.compare(${/value1}, ${/value2}) }"
});
}
});
});
修正戦略: ODataExpressionAddons モジュールをインポートする。
// 修正後 - ODataExpressionAddons をインポート
sap.ui.define([
"sap/ui/core/mvc/Controller",
"sap/m/Text",
"sap/ui/model/odata/ODataExpressionAddons" // odata.* 関数に必要
], function(Controller, Text, ODataExpressionAddons) {
"use strict";
return Controller.extend("my.app.controller.Main", {
onInit: function() {
var oText = new Text({
// ODataExpressionAddons がインポートされたので動作する
text: "{= odata.compare(${/value1}, ${/value2}) }"
});
}
});
});
インポートが必要な OData 関数:
| OData 関数 | 代替直接モジュール |
|---|---|
odata.compare |
sap/ui/model/odata/v4/ODataUtils |
odata.fillUriTemplate |
sap/ui/thirdparty/URITemplate |
odata.uriEncode |
sap/ui/model/odata/ODataUtils |
注意: sap/ui/model/odata/ODataExpressionAddons をインポートするのが最もシンプルな解決策です。
このモジュールはすべての OData expression 関数を一括で登録します。
問題: XML ビューのバインディングで OData 関数を使用しているが、インポートしていない。
<!-- 修正前 - no-implicit-globals をトリガー -->
<mvc:View
xmlns:mvc="sap.ui.core.mvc"
xmlns="sap.m">
<Text text="{= odata.compare(${/price1}, ${/price2}) }" />
</mvc:View>
修正戦略: ODataExpressionAddons に対して core:require を追加する。
<!-- 修正後 - 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>
linter メッセージから問題の種類を特定する:
enum / DataType に対応する正しいライブラリを特定する:
sap/ui/core/ → sap/ui/core/library)インポートを更新する:
コードの参照箇所を更新する:
var EnumName = library.EnumName;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; // エラー: エクスポートされていない
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}) }"; // エラー: インポートなし
}
});
});
修正後:
sap.ui.define([
"sap/ui/core/mvc/Controller",
"sap/ui/core/library", // ValueState enum 用
"sap/ui/unified/DateRange", // 直接インポ
This skill fixes pseudo module access and implicit global issues that the UI5 linter detects but cannot auto-fix because they require understanding proper module import patterns.
| Rule ID | Message Pattern | This Skill's Action |
|---|---|---|
no-pseudo-modules |
Deprecated access of enum pseudo module '...' | Import via library module |
no-pseudo-modules |
Deprecated access of DataType pseudo module '...' | Import via library module |
no-implicit-globals |
Access of module '...' not exported by library '...' | Import module directly |
no-implicit-globals |
OData built-in global symbols must not be used implicitly | Import ODataExpressionAddons |
Apply this skill when you see linter output like:
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
In UI5, enums and DataTypes were historically accessed as if they were modules (e.g., sap/ui/core/BarColor). These are "pseudo modules" - they don't exist as real files but are resolved at runtime from the library module. In modern UI5, direct pseudo module imports are deprecated.
Problem: Importing enums as direct modules.
// 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;
}
});
});
Fix Strategy: Import from the library module and access the enum as a property.
// 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;
}
});
});
Common Enum Pseudo Modules and Their Libraries:
| Pseudo Module | Library Module | Enum Access |
|---|---|---|
sap/ui/core/BarColor |
sap/ui/core/library |
coreLibrary.BarColor |
sap/ui/core/ValueState |
sap/ui/core/library |
coreLibrary.ValueState |
sap/ui/core/TextDirection |
sap/ui/core/library |
coreLibrary.TextDirection |
sap/ui/core/TextAlign |
sap/ui/core/library |
coreLibrary.TextAlign |
sap/ui/core/MessageType |
sap/ui/core/library |
coreLibrary.MessageType |
sap/m/ListSeparators |
sap/m/library |
mLibrary.ListSeparators |
sap/m/ListMode |
sap/m/library |
mLibrary.ListMode |
sap/m/ListType |
sap/m/library |
mLibrary.ListType |
sap/m/ButtonType |
sap/m/library |
mLibrary.ButtonType |
sap/m/InputType |
sap/m/library |
mLibrary.InputType |
Problem: Importing DataTypes as direct modules.
// 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
});
});
Fix Strategy: Import from the library module.
// 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
});
});
Common DataType Pseudo Modules:
| Pseudo Module | Library Module |
|---|---|
sap/ui/core/CSSSize |
sap/ui/core/library |
sap/ui/core/CSSColor |
sap/ui/core/library |
sap/ui/core/URI |
sap/ui/core/library |
sap/ui/core/ID |
sap/ui/core/library |
sap/ui/core/Percentage |
sap/ui/core/library |
Problem: Accessing modules via library exports that aren't actually exported.
// 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
});
Fix Strategy: Import the module directly.
// 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
});
Rule of Thumb:
library.EnumName)sap/ui/unified/DateRange)Problem: Using OData built-in functions in expression bindings without importing.
// 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}) }"
});
}
});
});
Fix Strategy: Import ODataExpressionAddons module.
// 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 Functions Requiring Import:
| OData Function | Alternative Direct Module |
|---|---|
odata.compare |
sap/ui/model/odata/v4/ODataUtils |
odata.fillUriTemplate |
sap/ui/thirdparty/URITemplate |
odata.uriEncode |
sap/ui/model/odata/ODataUtils |
Note: Importing sap/ui/model/odata/ODataExpressionAddons is the simplest solution as it registers all OData expression functions.
Problem: Using OData functions in XML view bindings without import.
<!-- Before - triggers no-implicit-globals -->
<mvc:View
xmlns:mvc="sap.ui.core.mvc"
xmlns="sap.m">
<Text text="{= odata.compare(${/price1}, ${/price2}) }" />
</mvc:View>
Fix Strategy: Add core:require for ODataExpressionAddons.
<!-- After - with 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>
Identify the issue type from the linter message:
Determine the correct library for enums/DataTypes:
sap/ui/core/ → sap/ui/core/library)Update imports:
Update code references:
var EnumName = library.EnumName;For XML views: Add core:require when needed
Given linter output:
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
Before:
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
}
});
});
After:
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
}
});
});
ODataExpressionAddons import is needed even though you don't use the variable directly - it registers the functions at load timeno-globals on JS files — e.g., sap.ui.getCore(), jQuery, sap.ui.controller()), use fix-js-globals原文・著作権は Anthropic および各プラグイン作者に帰属します。日本語訳は Claude API による自動翻訳です。