如何将ES模块导入UI5控制器
How to import ES Module into UI5 controller
给定一个 ES 模块 dictionaryAPI.mjs
:
export const DICTIONARY_API = Object.freeze({
someKey: "someValue"
});
我想将它导入我的 UI5 控制器。据我了解,UI5 不支持 .mjs
扩展名,因此我将扩展名从 .mjs
更改为 .js
。然后,我尝试将它添加到 UI5 控制器中,准确地说,是实用程序控制器 ControllerUtilities.js
:
sap.ui.define([
"com/myApp/dictionaryAPI"
],
(dictionaryAPI) => ({…}));
当我 运行 应用程序时,出现错误:
'com/myApp/controller/ControllerUtilities.js': Unexpected token 'export'
sap-ui-core.js:53 Uncaught (in promise) ModuleError: Failed to resolve dependencies of 'com/myApp/controller/Login.controller.js'
-> 'com/myApp/controller/BaseController.js'
-> 'com/myApp/controller/ControllerUtilities.js': Unexpected token 'export'
at p1 (https://openui5nightly.hana.ondemand.com/resources/sap-ui-core.js:53:213)
at j1.failWith (https://openui5nightly.hana.ondemand.com/resources/sap-ui-core.js:40:43)
at https://openui5nightly.hana.ondemand.com/resources/sap-ui-core.js:65:1556
Caused by: SyntaxError: Unexpected token 'export'
看来,UI5 无法识别来自 ES 模块的 export
statemen。
是否有将 ES 模块导入 UI5 控制器的选项?
使用版本:OpenUI5 1.96.0
UI5 默认使用 UMD 导入语法 (sap.ui.define
, sap.ui.require
)。要使其理解其他模块类型,您必须 'trick' 认为该模块是 UMD。
这可以通过使用 ui5 cli 来完成。
你必须建立一个合适的文件夹结构(package.json、ui5.yaml、webapp文件夹)并且在ui5.yaml文件中你可以为相应的ES定义project shims模块。
一个便宜又笨拙的替代方案是通过 ES 模块包含
<script src="path/to/module" type="module">
个标签,但我不知道有谁会推荐这个,因为它不允许捆绑。
最好的解决方案是创建一个新模块,如 fmi21 所述。
您的 API 可能看起来像这样,它只返回一个带有 DICTIONARY_API
的对象。因此,您还可以向 API.
添加更多属性
sap.ui.define([], function () {
"use strict";
return {
DICTIONARY_API : Object.freeze({
someKey: "someValue"
})
}
});
然后您可以像在 ControllerUtilities.js
中一样导入它
您还可以通过 manifest.json
将 JSON 文件直接加载到模型中
{
"sap.ui5": {
"models": {
"YOURMODELNAME": {
"type": "sap.ui.model.json.JSONModel",
"uri": "PATH TO JSON"
}
}
}
}
如果它是一个模型,需要在系统范围内访问,最简单的方法是在 sap.ui5
/models
下的 manifest.json
中声明它:
"dictionaryAPI": {
"type": "sap.ui.model.json.JSONModel",
"uri": "model/dictionaries/api.json"
},
或者,可以从根视图的控制器加载模型(rootView
in manifest.json
),这使得模型在整个应用程序期间可用于每个视图 运行:
async loadDictionaryData(dataSource, modelName) {
const dictionaryModel = new JSONModel();
await dictionaryModel.loadData(dataSource);
this.getView().setModel(dictionaryModel, modelName);
}
无需关心数据sync/async加载、重用、ESM/UMD等
给定一个 ES 模块 dictionaryAPI.mjs
:
export const DICTIONARY_API = Object.freeze({
someKey: "someValue"
});
我想将它导入我的 UI5 控制器。据我了解,UI5 不支持 .mjs
扩展名,因此我将扩展名从 .mjs
更改为 .js
。然后,我尝试将它添加到 UI5 控制器中,准确地说,是实用程序控制器 ControllerUtilities.js
:
sap.ui.define([
"com/myApp/dictionaryAPI"
],
(dictionaryAPI) => ({…}));
当我 运行 应用程序时,出现错误:
'com/myApp/controller/ControllerUtilities.js': Unexpected token 'export'
sap-ui-core.js:53 Uncaught (in promise) ModuleError: Failed to resolve dependencies of 'com/myApp/controller/Login.controller.js'
-> 'com/myApp/controller/BaseController.js'
-> 'com/myApp/controller/ControllerUtilities.js': Unexpected token 'export'
at p1 (https://openui5nightly.hana.ondemand.com/resources/sap-ui-core.js:53:213)
at j1.failWith (https://openui5nightly.hana.ondemand.com/resources/sap-ui-core.js:40:43)
at https://openui5nightly.hana.ondemand.com/resources/sap-ui-core.js:65:1556
Caused by: SyntaxError: Unexpected token 'export'
看来,UI5 无法识别来自 ES 模块的 export
statemen。
是否有将 ES 模块导入 UI5 控制器的选项?
使用版本:OpenUI5 1.96.0
UI5 默认使用 UMD 导入语法 (sap.ui.define
, sap.ui.require
)。要使其理解其他模块类型,您必须 'trick' 认为该模块是 UMD。
这可以通过使用 ui5 cli 来完成。
你必须建立一个合适的文件夹结构(package.json、ui5.yaml、webapp文件夹)并且在ui5.yaml文件中你可以为相应的ES定义project shims模块。
一个便宜又笨拙的替代方案是通过 ES 模块包含
<script src="path/to/module" type="module">
个标签,但我不知道有谁会推荐这个,因为它不允许捆绑。
最好的解决方案是创建一个新模块,如 fmi21 所述。
您的 API 可能看起来像这样,它只返回一个带有 DICTIONARY_API
的对象。因此,您还可以向 API.
sap.ui.define([], function () {
"use strict";
return {
DICTIONARY_API : Object.freeze({
someKey: "someValue"
})
}
});
然后您可以像在 ControllerUtilities.js
您还可以通过 manifest.json
{
"sap.ui5": {
"models": {
"YOURMODELNAME": {
"type": "sap.ui.model.json.JSONModel",
"uri": "PATH TO JSON"
}
}
}
}
如果它是一个模型,需要在系统范围内访问,最简单的方法是在 sap.ui5
/models
下的 manifest.json
中声明它:
"dictionaryAPI": {
"type": "sap.ui.model.json.JSONModel",
"uri": "model/dictionaries/api.json"
},
或者,可以从根视图的控制器加载模型(rootView
in manifest.json
),这使得模型在整个应用程序期间可用于每个视图 运行:
async loadDictionaryData(dataSource, modelName) {
const dictionaryModel = new JSONModel();
await dictionaryModel.loadData(dataSource);
this.getView().setModel(dictionaryModel, modelName);
}
无需关心数据sync/async加载、重用、ESM/UMD等