diff --git a/lib/lbt/bundle/Builder.js b/lib/lbt/bundle/Builder.js
index 7a010c2b9..88e24dc03 100644
--- a/lib/lbt/bundle/Builder.js
+++ b/lib/lbt/bundle/Builder.js
@@ -52,6 +52,14 @@ const UI5BundleFormat = {
outW.writeln(`}});`);
},
+ beforeH2Preloads(outW) {
+ outW.writeln(`"unsupported"; /* Bundle format 'h2' not supported (requires ui5loader)`);
+ },
+
+ afterH2Preloads(outW) {
+ outW.writeln(`*/`);
+ },
+
requireSync(outW, moduleName) {
outW.writeln(`sap.ui.requireSync("${ModuleName.toRequireJSName(moduleName)}");`);
},
@@ -78,6 +86,14 @@ const EVOBundleFormat = {
outW.writeln(`);`);
},
+ beforeH2Preloads(outW) {
+ outW.writeln(`sap.ui.loader.config({depCacheUI5:{`);
+ },
+
+ afterH2Preloads(outW) {
+ outW.writeln(`}});`);
+ },
+
requireSync(outW, moduleName) {
outW.writeln(`sap.ui.requireSync("${ModuleName.toRequireJSName(moduleName)}");`);
},
@@ -206,6 +222,8 @@ class BundleBuilder {
return this.writeRaw(section);
case SectionType.Preload:
return this.writePreloadFunction(section);
+ case SectionType.DepCache:
+ return this.writeDepCache(section);
case SectionType.Require:
return this.writeRequires(section);
default:
@@ -449,6 +467,42 @@ class BundleBuilder {
});
}
+ async writeDepCache(section) {
+ const outW = this.outW;
+
+ outW.ensureNewLine();
+
+ const sequence = section.modules.slice().sort();
+
+ if ( sequence.length > 0 ) {
+ this.targetBundleFormat.beforeH2Preloads(outW, section);
+ let i = 0;
+ for (const module of sequence) {
+ const resource = await this.pool.findResourceWithInfo(module);
+ if ( resource != null ) {
+ const deps = resource.info.dependencies.filter( (dep) =>
+ !resource.info.isConditionalDependency(dep) && !resource.info.isImplicitDependency(dep) );
+ if ( deps.length > 0 ) {
+ if ( i > 0 ) {
+ outW.writeln(",");
+ }
+ outW.write(`"${module}": [${deps.map((dep) => "\"" + dep + "\"").join(",")}]`);
+ i++;
+ } else {
+ log.verbose(" skipped %s, no dependencies", module);
+ }
+ } else {
+ log.error(" couldn't find %s", module);
+ }
+ }
+
+ if ( i > 0 ) {
+ outW.writeln();
+ }
+ this.targetBundleFormat.afterH2Preloads(outW, section);
+ }
+ }
+
writeRequires(section) {
this.outW.ensureNewLine();
section.modules.forEach( (module) => {
diff --git a/lib/lbt/bundle/BundleDefinition.js b/lib/lbt/bundle/BundleDefinition.js
index 1e7909dd9..260a2d214 100644
--- a/lib/lbt/bundle/BundleDefinition.js
+++ b/lib/lbt/bundle/BundleDefinition.js
@@ -17,6 +17,12 @@ const SectionType = {
*/
Preload: "preload",
+ /**
+ * Only the dependencies of the modules are stored as 'depCache' configuration.
+ * Requires UI5 Evolution runtime.
+ */
+ DepCache: "depcache",
+
/**
* For each module, a jQuery.sap.require call will be created.
* Usually used as the last section in a merged module to enforce loading and
diff --git a/lib/tasks/bundlers/generateComponentPreload.js b/lib/tasks/bundlers/generateComponentPreload.js
index 226a59fcc..bdb082331 100644
--- a/lib/tasks/bundlers/generateComponentPreload.js
+++ b/lib/tasks/bundlers/generateComponentPreload.js
@@ -59,27 +59,59 @@ module.exports = function({workspace, dependencies, options}) {
}
});
- return moduleBundler({
- resources,
- options: {
- bundleDefinition: {
- name: `${namespace}/Component-preload.js`,
- defaultFileTypes: [".js", ".fragment.xml", ".view.xml", ".properties", ".json"],
- sections: [
- {
- mode: "preload",
- filters: filters,
- resolve: false,
- resolveConditional: false,
- renderer: false
- }
- ]
+ return Promise.all([
+ moduleBundler({
+ resources,
+ options: {
+ bundleDefinition: {
+ name: `${namespace}/Component-preload.js`,
+ defaultFileTypes: [".js", ".fragment.xml", ".view.xml", ".properties", ".json"],
+ sections: [
+ {
+ mode: "preload",
+ filters: filters,
+ resolve: false,
+ resolveConditional: false,
+ renderer: false
+ }
+ ]
+ }
}
- }
- });
+ }),
+ moduleBundler({
+ resources,
+ options: {
+ bundleDefinition: {
+ name: `${namespace}/Component-h2-preload.js`,
+ defaultFileTypes: [".js", ".fragment.xml", ".view.xml", ".properties", ".json"],
+ sections: [
+ {
+ mode: "preload",
+ filters: [
+ `${namespace}/library.js`,
+ `${namespace}/manifest.json`
+ ],
+ resolve: false,
+ resolveConditional: false,
+ renderer: false
+ },
+ {
+ mode: "depcache",
+ filters: filters,
+ resolve: false,
+ resolveConditional: false,
+ renderer: false
+ }
+ ]
+ }
+ }
+ })
+ ]);
}));
})
.then((processedResources) => {
+ return Array.prototype.concat.apply([], processedResources);
+ }).then((processedResources) => {
return Promise.all(processedResources.map((resource) => {
return workspace.write(resource[0]);
}));
diff --git a/lib/tasks/bundlers/generateLibraryPreload.js b/lib/tasks/bundlers/generateLibraryPreload.js
index e940617a1..a24d84724 100644
--- a/lib/tasks/bundlers/generateLibraryPreload.js
+++ b/lib/tasks/bundlers/generateLibraryPreload.js
@@ -2,11 +2,13 @@ const log = require("@ui5/logger").getLogger("builder:tasks:bundlers:generateLib
const moduleBundler = require("../../processors/bundlers/moduleBundler");
const ReaderCollectionPrioritized = require("@ui5/fs").ReaderCollectionPrioritized;
-function getBundleDefinition(namespace) {
+function getBundleDefinition(namespace, h2) {
+ const h2infix = h2 ? "h2-" : "";
+ let bundleDef;
// TODO: move to config of actual core project
if (namespace === "sap/ui/core") {
- return {
- name: `${namespace}/library-preload.js`,
+ bundleDef = {
+ name: `${namespace}/library-${h2infix}preload.js`,
defaultFileTypes: [".js", ".fragment.xml", ".view.xml", ".properties", ".json"],
sections: [
{
@@ -19,7 +21,7 @@ function getBundleDefinition(namespace) {
resolve: true
},
{
- mode: "preload",
+ mode: h2 ? "depcache" : "preload",
filters: [
`${namespace}/`,
`!${namespace}/.library`,
@@ -62,28 +64,40 @@ function getBundleDefinition(namespace) {
}
]
};
+ } else {
+ bundleDef = {
+ name: `${namespace}/library-${h2infix}preload.js`,
+ defaultFileTypes: [".js", ".fragment.xml", ".view.xml", ".properties", ".json"],
+ sections: [
+ {
+ mode: h2 ? "depcache" : "preload",
+ filters: [
+ `${namespace}/`,
+ `!${namespace}/.library`,
+ `!${namespace}/themes/`,
+ `!${namespace}/messagebundle*`
+ ],
+ resolve: false,
+ resolveConditional: false,
+ renderer: true
+ }
+ ]
+ };
}
- return {
- name: `${namespace}/library-preload.js`,
- defaultFileTypes: [".js", ".fragment.xml", ".view.xml", ".properties", ".json"],
- sections: [
- {
- mode: "preload",
- filters: [
- `${namespace}/`,
- `!${namespace}/.library`,
- `!${namespace}/designtime/`,
- `!${namespace}/**/*.designtime.js`,
- `!${namespace}/**/*.support.js`,
- `!${namespace}/themes/`,
- `!${namespace}/messagebundle*`
- ],
- resolve: false,
- resolveConditional: false,
- renderer: true
- }
- ]
- };
+
+ if ( h2 ) {
+ bundleDef.sections.unshift({
+ mode: "preload",
+ filters: [
+ `${namespace}/library.js`,
+ `${namespace}/manifest.json`
+ ],
+ resolve: false,
+ resolveConditional: false,
+ renderer: false
+ });
+ }
+ return bundleDef;
}
function getModuleBundlerOptions(config) {
@@ -249,21 +263,38 @@ module.exports = function({workspace, dependencies, options}) {
const libraryNamespaceMatch = libraryIndicatorPath.match(libraryNamespacePattern);
if (libraryNamespaceMatch && libraryNamespaceMatch[1]) {
const libraryNamespace = libraryNamespaceMatch[1];
- return moduleBundler({
- options: {
- bundleDefinition: getBundleDefinition(libraryNamespace),
- bundleOptions: {
- optimize: true,
- usePredefineCalls: true
+ return Promise.all([
+ moduleBundler({
+ options: {
+ bundleDefinition: getBundleDefinition(libraryNamespace),
+ bundleOptions: {
+ optimize: true,
+ usePredefineCalls: true
+ }
+ },
+ resources
+ }).then(([bundle]) => {
+ if (bundle) {
+ // console.log(`${libraryNamespace}/library-preload.js bundle created`);
+ return workspace.write(bundle);
+ }
+ }),
+ moduleBundler({
+ options: {
+ bundleDefinition: getBundleDefinition(libraryNamespace, /* h2 */ true),
+ bundleOptions: {
+ optimize: true,
+ usePredefineCalls: true
+ }
+ },
+ resources
+ }).then(([bundle]) => {
+ if (bundle) {
+ // console.log(`${libraryNamespace}/library-h2-preload.js bundle created`);
+ return workspace.write(bundle);
}
- },
- resources
- }).then(([bundle]) => {
- if (bundle) {
- // console.log(`${libraryNamespace}/library-preload.js bundle created`);
- return workspace.write(bundle);
- }
- });
+ })
+ ]);
} else {
log.verbose(`Could not determine library namespace from file "${libraryIndicatorPath}" for project ${options.projectName}. Skipping library preload bundling.`);
return Promise.resolve();
diff --git a/test/expected/build/application.g/cachebuster/Component-h2-preload.js b/test/expected/build/application.g/cachebuster/Component-h2-preload.js
new file mode 100644
index 000000000..bb796ab06
--- /dev/null
+++ b/test/expected/build/application.g/cachebuster/Component-h2-preload.js
@@ -0,0 +1,9 @@
+//@ui5-bundle application/g/Component-h2-preload.js
+sap.ui.require.preload({
+ "application/g/manifest.json":'{"_version":"1.1.0","sap.app":{"_version":"1.1.0","id":"application.g","type":"application","applicationVersion":{"version":"1.0.0"},"embeds":["embedded"],"title":"{{title}}"},"customCopyrightString":"Some fancy copyright"}'
+});
+sap.ui.loader.config({depCacheUI5:{
+"application/g/Component.js": ["sap/ui/core/UIComponent.js"],
+"application/g/subcomponentA/Component.js": ["sap/ui/core/UIComponent.js"],
+"application/g/subcomponentB/Component.js": ["sap/ui/core/UIComponent.js"]
+}});
diff --git a/test/expected/build/application.g/cachebuster/Component-preload.js b/test/expected/build/application.g/cachebuster/Component-preload.js
index 504dbcbe0..6bd4694ad 100644
--- a/test/expected/build/application.g/cachebuster/Component-preload.js
+++ b/test/expected/build/application.g/cachebuster/Component-preload.js
@@ -1,7 +1,5 @@
//@ui5-bundle application/g/Component-preload.js
-jQuery.sap.registerPreloadedModules({
-"version":"2.0",
-"modules":{
+sap.ui.require.preload({
"application/g/Component.js":function(){sap.ui.define(["sap/ui/core/UIComponent"],function(n){"use strict";return n.extend("application.g.Component",{metadata:{manifest:"json"}})});
},
"application/g/manifest.json":'{"_version":"1.1.0","sap.app":{"_version":"1.1.0","id":"application.g","type":"application","applicationVersion":{"version":"1.0.0"},"embeds":["embedded"],"title":"{{title}}"},"customCopyrightString":"Some fancy copyright"}',
@@ -11,4 +9,4 @@ jQuery.sap.registerPreloadedModules({
"application/g/subcomponentB/Component.js":function(){sap.ui.define(["sap/ui/core/UIComponent"],function(n){"use strict";return n.extend("application.g.subcomponentB.Component",{metadata:{manifest:"json"}})});
},
"application/g/subcomponentB/manifest.json":'{"_version":"1.1.0","sap.app":{"_version":"1.1.0","id":"application.g.subcomponentB","type":"application","applicationVersion":{"version":"1.2.2"},"embeds":["embedded"],"title":"{{title}}"}}'
-}});
+});
diff --git a/test/expected/build/application.g/cachebuster/sap-ui-cachebuster-info.json b/test/expected/build/application.g/cachebuster/sap-ui-cachebuster-info.json
index b7b2814c7..9f401e31d 100644
--- a/test/expected/build/application.g/cachebuster/sap-ui-cachebuster-info.json
+++ b/test/expected/build/application.g/cachebuster/sap-ui-cachebuster-info.json
@@ -5,6 +5,7 @@
"subcomponentB/Component.js": 1540570258000,
"subcomponentA/Component.js": 1540570258000,
"Component.js": 1540570258000,
+ "Component-h2-preload.js": 1554823987259,
"Component-preload.js": 1554823987259,
"subcomponentB/Component-dbg.js": 1540570258000,
"subcomponentA/Component-dbg.js": 1540570258000,
diff --git a/test/expected/build/application.g/dest/Component-h2-preload.js b/test/expected/build/application.g/dest/Component-h2-preload.js
new file mode 100644
index 000000000..6cdb95289
--- /dev/null
+++ b/test/expected/build/application.g/dest/Component-h2-preload.js
@@ -0,0 +1,7 @@
+//@ui5-bundle application/g/Component-h2-preload.js
+sap.ui.require.preload({
+ "application/g/manifest.json":'{"_version":"1.1.0","sap.app":{"_version":"1.1.0","id":"application.g","type":"application","applicationVersion":{"version":"1.0.0"},"embeds":["embedded"],"title":"{{title}}"},"customCopyrightString":"Some fancy copyright"}'
+});
+sap.ui.loader.config({depCacheUI5:{
+"application/g/Component.js": ["sap/ui/core/UIComponent.js"]
+}});
diff --git a/test/expected/build/application.g/dest/Component-preload.js b/test/expected/build/application.g/dest/Component-preload.js
index bb4d7436f..6d6ba91c1 100644
--- a/test/expected/build/application.g/dest/Component-preload.js
+++ b/test/expected/build/application.g/dest/Component-preload.js
@@ -1,8 +1,6 @@
//@ui5-bundle application/g/Component-preload.js
-jQuery.sap.registerPreloadedModules({
-"version":"2.0",
-"modules":{
+sap.ui.require.preload({
"application/g/Component.js":function(){sap.ui.define(["sap/ui/core/UIComponent"],function(n){"use strict";return n.extend("application.g.Component",{metadata:{manifest:"json"}})});
},
"application/g/manifest.json":'{"_version":"1.1.0","sap.app":{"_version":"1.1.0","id":"application.g","type":"application","applicationVersion":{"version":"1.0.0"},"embeds":["embedded"],"title":"{{title}}"},"customCopyrightString":"Some fancy copyright"}'
-}});
+});
diff --git a/test/expected/build/application.g/dest/subcomponentA/Component-h2-preload.js b/test/expected/build/application.g/dest/subcomponentA/Component-h2-preload.js
new file mode 100644
index 000000000..ba65e3d0f
--- /dev/null
+++ b/test/expected/build/application.g/dest/subcomponentA/Component-h2-preload.js
@@ -0,0 +1,7 @@
+//@ui5-bundle application/g/subcomponentA/Component-h2-preload.js
+sap.ui.require.preload({
+ "application/g/subcomponentA/manifest.json":'{"_version":"1.1.0","sap.app":{"_version":"1.1.0","id":"application.g.subcomponentA","type":"application","applicationVersion":{"version":"1.2.2"},"embeds":["embedded"],"title":"{{title}}"}}'
+});
+sap.ui.loader.config({depCacheUI5:{
+"application/g/subcomponentA/Component.js": ["sap/ui/core/UIComponent.js"]
+}});
diff --git a/test/expected/build/application.g/dest/subcomponentA/Component-preload.js b/test/expected/build/application.g/dest/subcomponentA/Component-preload.js
index 4c103c261..4b73c3d3b 100644
--- a/test/expected/build/application.g/dest/subcomponentA/Component-preload.js
+++ b/test/expected/build/application.g/dest/subcomponentA/Component-preload.js
@@ -1,8 +1,6 @@
//@ui5-bundle application/g/subcomponentA/Component-preload.js
-jQuery.sap.registerPreloadedModules({
-"version":"2.0",
-"modules":{
+sap.ui.require.preload({
"application/g/subcomponentA/Component.js":function(){sap.ui.define(["sap/ui/core/UIComponent"],function(n){"use strict";return n.extend("application.g.subcomponentA.Component",{metadata:{manifest:"json"}})});
},
"application/g/subcomponentA/manifest.json":'{"_version":"1.1.0","sap.app":{"_version":"1.1.0","id":"application.g.subcomponentA","type":"application","applicationVersion":{"version":"1.2.2"},"embeds":["embedded"],"title":"{{title}}"}}'
-}});
+});
diff --git a/test/expected/build/application.g/dest/subcomponentB/Component-h2-preload.js b/test/expected/build/application.g/dest/subcomponentB/Component-h2-preload.js
new file mode 100644
index 000000000..8a25d1286
--- /dev/null
+++ b/test/expected/build/application.g/dest/subcomponentB/Component-h2-preload.js
@@ -0,0 +1,7 @@
+//@ui5-bundle application/g/subcomponentB/Component-h2-preload.js
+sap.ui.require.preload({
+ "application/g/subcomponentB/manifest.json":'{"_version":"1.1.0","sap.app":{"_version":"1.1.0","id":"application.g.subcomponentB","type":"application","applicationVersion":{"version":"1.2.2"},"embeds":["embedded"],"title":"{{title}}"}}'
+});
+sap.ui.loader.config({depCacheUI5:{
+"application/g/subcomponentB/Component.js": ["sap/ui/core/UIComponent.js"]
+}});
diff --git a/test/expected/build/application.g/dest/subcomponentB/Component-preload.js b/test/expected/build/application.g/dest/subcomponentB/Component-preload.js
index 14667fe94..eae25681a 100644
--- a/test/expected/build/application.g/dest/subcomponentB/Component-preload.js
+++ b/test/expected/build/application.g/dest/subcomponentB/Component-preload.js
@@ -1,8 +1,6 @@
//@ui5-bundle application/g/subcomponentB/Component-preload.js
-jQuery.sap.registerPreloadedModules({
-"version":"2.0",
-"modules":{
+sap.ui.require.preload({
"application/g/subcomponentB/Component.js":function(){sap.ui.define(["sap/ui/core/UIComponent"],function(n){"use strict";return n.extend("application.g.subcomponentB.Component",{metadata:{manifest:"json"}})});
},
"application/g/subcomponentB/manifest.json":'{"_version":"1.1.0","sap.app":{"_version":"1.1.0","id":"application.g.subcomponentB","type":"application","applicationVersion":{"version":"1.2.2"},"embeds":["embedded"],"title":"{{title}}"}}'
-}});
+});
diff --git a/test/expected/build/application.h/dest/sectionsA/customBundle.js b/test/expected/build/application.h/dest/sectionsA/customBundle.js
index 4acc4444d..eec7db48d 100644
--- a/test/expected/build/application.h/dest/sectionsA/customBundle.js
+++ b/test/expected/build/application.h/dest/sectionsA/customBundle.js
@@ -1,9 +1,7 @@
//@ui5-bundle application/h/sectionsA/customBundle.js
-jQuery.sap.registerPreloadedModules({
-"version":"2.0",
-"modules":{
+sap.ui.require.preload({
"application/h/sectionsA/section1.js":function(){sap.ui.define(["sap/m/Button"],function(n){console.log("Section 1 included")});
},
"application/h/sectionsA/section3.js":function(){sap.ui.define(["sap/m/Button"],function(n){console.log("Section 3 included")});
}
-}});
+});
diff --git a/test/expected/build/application.h/dest/sectionsB/customBundle.js b/test/expected/build/application.h/dest/sectionsB/customBundle.js
index 0e66f011b..3d4f55316 100644
--- a/test/expected/build/application.h/dest/sectionsB/customBundle.js
+++ b/test/expected/build/application.h/dest/sectionsB/customBundle.js
@@ -1,11 +1,9 @@
//@ui5-bundle application/h/sectionsB/customBundle.js
-jQuery.sap.registerPreloadedModules({
-"version":"2.0",
-"modules":{
+sap.ui.require.preload({
"application/h/sectionsB/section1.js":function(){sap.ui.define(["sap/m/Button"],function(n){console.log("Section 1 included")});
},
"application/h/sectionsB/section2.js":function(){sap.ui.define(["sap/m/Button"],function(n){console.log("Section 2 included")});
},
"application/h/sectionsB/section3.js":function(){sap.ui.define(["sap/m/Button"],function(n){console.log("Section 3 included")});
}
-}});
+});
diff --git a/test/expected/build/application.i/dest/Component-h2-preload.js b/test/expected/build/application.i/dest/Component-h2-preload.js
new file mode 100644
index 000000000..5a46a45de
--- /dev/null
+++ b/test/expected/build/application.i/dest/Component-h2-preload.js
@@ -0,0 +1,7 @@
+//@ui5-bundle application/i/Component-h2-preload.js
+sap.ui.require.preload({
+ "application/i/manifest.json":'{"_version":"1.1.0","sap.app":{"_version":"1.1.0","id":"application.i","type":"application","applicationVersion":{"version":"1.2.2"},"embeds":["embedded"],"title":"{{title}}"},"sap.ui5":{"dependencies":{"libs":{"sap.ui.layout":{},"sap.ui.core":{},"sap.m":{},"sap.ui.fl":{}}}}}'
+});
+sap.ui.loader.config({depCacheUI5:{
+"application/i/Component.js": ["sap/ui/core/UIComponent.js","sap/ui/layout/library.js","sap/ui/core/library.js","sap/m/library.js","sap/ui/fl/library.js"]
+}});
diff --git a/test/expected/build/application.i/dest/Component-preload.js b/test/expected/build/application.i/dest/Component-preload.js
index 0c2c24167..af9fb92f0 100644
--- a/test/expected/build/application.i/dest/Component-preload.js
+++ b/test/expected/build/application.i/dest/Component-preload.js
@@ -1,7 +1,5 @@
//@ui5-bundle application/i/Component-preload.js
-jQuery.sap.registerPreloadedModules({
-"version":"2.0",
-"modules":{
+sap.ui.require.preload({
"application/i/Component.js":function(){sap.ui.define(["sap/ui/core/UIComponent"],function(n){"use strict";return n.extend("application.i.Component",{metadata:{manifest:"json"}})});
},
"application/i/changes/changes-bundle.json":'[{"fileName":"id_456_addField","fileType":"change","changeType":"hideControl","component":"application.i.Component","content":{},"selector":{"id":"control1"},"layer":"VENDOR","texts":{},"namespace":"apps/application.i.Component/changes","creation":"2023-10-30T13:52:40.4754350Z","originalLanguage":"","conditions":{},"support":{"generator":"did it","user":"Max Mustermann"}},{"fileName":"id_123_addField","fileType":"change","changeType":"hideControl","component":"application.i.Component","content":{},"selector":{"id":"control1"},"layer":"VENDOR","texts":{},"namespace":"apps/application.i.Component/changes","creation":"2025-10-30T13:52:40.4754350Z","originalLanguage":"","conditions":{},"support":{"generator":"did it","user":"Max Mustermann"}}]',
@@ -9,4 +7,4 @@ jQuery.sap.registerPreloadedModules({
},
"application/i/changes/fragments/MyFragment.fragment.xml":'',
"application/i/manifest.json":'{"_version":"1.1.0","sap.app":{"_version":"1.1.0","id":"application.i","type":"application","applicationVersion":{"version":"1.2.2"},"embeds":["embedded"],"title":"{{title}}"},"sap.ui5":{"dependencies":{"libs":{"sap.ui.layout":{},"sap.ui.core":{},"sap.m":{},"sap.ui.fl":{}}}}}'
-}});
+});
diff --git a/test/expected/build/application.j/dest/Component-h2-preload.js b/test/expected/build/application.j/dest/Component-h2-preload.js
new file mode 100644
index 000000000..6b87cf6ae
--- /dev/null
+++ b/test/expected/build/application.j/dest/Component-h2-preload.js
@@ -0,0 +1,7 @@
+//@ui5-bundle application/j/Component-h2-preload.js
+sap.ui.require.preload({
+ "application/j/manifest.json":'{"_version":"1.1.0","sap.app":{"_version":"1.1.0","id":"application.j","type":"application","applicationVersion":{"version":"1.2.2"},"embeds":["embedded"],"title":"{{title}}"},"sap.ui5":{"dependencies":{"minUI5Version":"1.73.2","libs":{"sap.ui.layout":{},"sap.ui.core":{},"sap.m":{},"sap.ui.fl":{"lazy":false}}}}}'
+});
+sap.ui.loader.config({depCacheUI5:{
+"application/j/Component.js": ["sap/ui/core/UIComponent.js","sap/ui/layout/library.js","sap/ui/core/library.js","sap/m/library.js","sap/ui/fl/library.js"]
+}});
diff --git a/test/expected/build/application.j/dest/Component-preload.js b/test/expected/build/application.j/dest/Component-preload.js
index 4e58fdf09..4d345b369 100644
--- a/test/expected/build/application.j/dest/Component-preload.js
+++ b/test/expected/build/application.j/dest/Component-preload.js
@@ -1,7 +1,5 @@
//@ui5-bundle application/j/Component-preload.js
-jQuery.sap.registerPreloadedModules({
-"version":"2.0",
-"modules":{
+sap.ui.require.preload({
"application/j/Component.js":function(){sap.ui.define(["sap/ui/core/UIComponent"],function(n){"use strict";return n.extend("application.j.Component",{metadata:{manifest:"json"}})});
},
"application/j/changes/coding/MyExtension.js":function(){sap.ui.define([],function(){return{}});
@@ -9,4 +7,4 @@ jQuery.sap.registerPreloadedModules({
"application/j/changes/flexibility-bundle.json":'{"changes":[{"fileName":"id_456_addField","fileType":"change","changeType":"hideControl","component":"application.j.Component","content":{},"selector":{"id":"control1"},"layer":"VENDOR","texts":{},"namespace":"apps/application.j.Component/changes","creation":"2023-10-30T13:52:40.4754350Z","originalLanguage":"","conditions":{},"support":{"generator":"did it","user":"Max Mustermann"}},{"fileName":"id_123_addField","fileType":"change","changeType":"hideControl","component":"application.j.Component","content":{},"selector":{"id":"control1"},"layer":"VENDOR","texts":{},"namespace":"apps/application.j.Component/changes","creation":"2025-10-30T13:52:40.4754350Z","originalLanguage":"","conditions":{},"support":{"generator":"did it","user":"Max Mustermann"}}],"compVariants":[{"fileName":"id_111_compVariants","fileType":"variant","changeType":"hideControl","component":"application.j.Component","content":{},"selector":{"id":"control1"},"layer":"VENDOR","texts":{},"namespace":"apps/application.j.Component/changes","creation":"2025-10-30T13:52:40.4754350Z","originalLanguage":"","conditions":{},"support":{"generator":"did it","user":"Max Mustermann"},"appDescriptorChange":false}],"variants":[{"fileName":"id_111_test","fileType":"ctrl_variant","changeType":"hideControl","component":"application.j.Component","content":{},"selector":{"id":"control1"},"layer":"VENDOR","texts":{},"namespace":"apps/application.j.Component/changes","creation":"2025-10-30T13:52:40.4754350Z","originalLanguage":"","conditions":{},"support":{"generator":"did it","user":"Max Mustermann"}}],"variantChanges":[{"fileName":"id_111_test","fileType":"ctrl_variant_change","changeType":"hideControl","component":"application.j.Component","content":{},"selector":{"id":"control1"},"layer":"VENDOR","texts":{},"namespace":"apps/application.j.Component/changes","creation":"2025-10-30T13:52:40.4754350Z","originalLanguage":"","conditions":{},"support":{"generator":"did it","user":"Max Mustermann"}}],"variantDependentControlChanges":[{"fileName":"id_111_variantDependentControlChange","fileType":"change","changeType":"hideControl","component":"application.j.Component","content":{},"selector":{"id":"control1"},"layer":"VENDOR","texts":{},"namespace":"apps/application.j.Component/changes","creation":"2025-10-30T13:52:40.4754350Z","originalLanguage":"","conditions":{},"support":{"generator":"did it","user":"Max Mustermann"},"variantReference":"someting here"}],"variantManagementChanges":[{"fileName":"id_111_test","fileType":"ctrl_variant_management_change","changeType":"hideControl","component":"application.j.Component","content":{},"selector":{"id":"control1"},"layer":"VENDOR","texts":{},"namespace":"apps/application.j.Component/changes","creation":"2025-10-30T13:52:40.4754350Z","originalLanguage":"","conditions":{},"support":{"generator":"did it","user":"Max Mustermann"}}]}',
"application/j/changes/fragments/MyFragment.fragment.xml":'',
"application/j/manifest.json":'{"_version":"1.1.0","sap.app":{"_version":"1.1.0","id":"application.j","type":"application","applicationVersion":{"version":"1.2.2"},"embeds":["embedded"],"title":"{{title}}"},"sap.ui5":{"dependencies":{"minUI5Version":"1.73.2","libs":{"sap.ui.layout":{},"sap.ui.core":{},"sap.m":{},"sap.ui.fl":{"lazy":false}}}}}'
-}});
+});
diff --git a/test/expected/build/library.d/preload/resources/library/d/library-h2-preload.js b/test/expected/build/library.d/preload/resources/library/d/library-h2-preload.js
new file mode 100644
index 000000000..2e4921411
--- /dev/null
+++ b/test/expected/build/library.d/preload/resources/library/d/library-h2-preload.js
@@ -0,0 +1,3 @@
+//@ui5-bundle library/d/library-h2-preload.js
+"unsupported"; /* Bundle format 'h2' not supported (requires ui5loader)
+*/
diff --git a/test/expected/build/library.h/dest/resources/library/h/components/Component-h2-preload.js b/test/expected/build/library.h/dest/resources/library/h/components/Component-h2-preload.js
new file mode 100644
index 000000000..148630f8e
--- /dev/null
+++ b/test/expected/build/library.h/dest/resources/library/h/components/Component-h2-preload.js
@@ -0,0 +1,4 @@
+//@ui5-bundle library/h/components/Component-h2-preload.js
+sap.ui.loader.config({depCacheUI5:{
+"library/h/components/Component.js": ["sap/ui/core/UIComponent.js"]
+}});
diff --git a/test/expected/build/library.h/dest/resources/library/h/components/subcomponent1/Component-h2-preload.js b/test/expected/build/library.h/dest/resources/library/h/components/subcomponent1/Component-h2-preload.js
new file mode 100644
index 000000000..92e779c82
--- /dev/null
+++ b/test/expected/build/library.h/dest/resources/library/h/components/subcomponent1/Component-h2-preload.js
@@ -0,0 +1,4 @@
+//@ui5-bundle library/h/components/subcomponent1/Component-h2-preload.js
+sap.ui.loader.config({depCacheUI5:{
+"library/h/components/subcomponent1/Component.js": ["sap/ui/core/UIComponent.js"]
+}});
diff --git a/test/expected/build/library.h/dest/resources/library/h/components/subcomponent2/Component-h2-preload.js b/test/expected/build/library.h/dest/resources/library/h/components/subcomponent2/Component-h2-preload.js
new file mode 100644
index 000000000..dded428bb
--- /dev/null
+++ b/test/expected/build/library.h/dest/resources/library/h/components/subcomponent2/Component-h2-preload.js
@@ -0,0 +1,4 @@
+//@ui5-bundle library/h/components/subcomponent2/Component-h2-preload.js
+sap.ui.loader.config({depCacheUI5:{
+"library/h/components/subcomponent2/Component.js": ["sap/ui/core/UIComponent.js"]
+}});
diff --git a/test/expected/build/library.h/dest/resources/library/h/components/subcomponent3/Component-h2-preload.js b/test/expected/build/library.h/dest/resources/library/h/components/subcomponent3/Component-h2-preload.js
new file mode 100644
index 000000000..e1f2929ab
--- /dev/null
+++ b/test/expected/build/library.h/dest/resources/library/h/components/subcomponent3/Component-h2-preload.js
@@ -0,0 +1,4 @@
+//@ui5-bundle library/h/components/subcomponent3/Component-h2-preload.js
+sap.ui.loader.config({depCacheUI5:{
+"library/h/components/subcomponent3/Component.js": ["sap/ui/core/UIComponent.js"]
+}});
diff --git a/test/expected/build/library.i/dest/resources/library/i/library.js b/test/expected/build/library.i/dest/resources/library/i/library.js
index 48a19acb7..e2764c75a 100644
--- a/test/expected/build/library.i/dest/resources/library/i/library.js
+++ b/test/expected/build/library.i/dest/resources/library/i/library.js
@@ -2,7 +2,7 @@
* Some fancy copyright
*/
sap.ui.define([
- 'sap/ui/core/Core',
+ 'sap/ui/core/Core'
], function(Core) {
"use strict";
@@ -13,10 +13,10 @@ sap.ui.define([
dependencies : ["sap.ui.core"],
types: [
"library.i.ButtonType",
- "library.i.DialogType",
+ "library.i.DialogType"
],
interfaces: [
- "library.i.IContent",
+ "library.i.IContent"
],
controls: [
"library.i.Button",
diff --git a/test/expected/build/sap.ui.core/preload/resources/sap/ui/core/library-h2-preload.js b/test/expected/build/sap.ui.core/preload/resources/sap/ui/core/library-h2-preload.js
new file mode 100644
index 000000000..ea8c6a90c
--- /dev/null
+++ b/test/expected/build/sap.ui.core/preload/resources/sap/ui/core/library-h2-preload.js
@@ -0,0 +1,3 @@
+//@ui5-bundle sap/ui/core/library-h2-preload.js
+"unsupported"; /* Bundle format 'h2' not supported (requires ui5loader)
+*/
diff --git a/test/fixtures/library.i/main/src/library/i/library.js b/test/fixtures/library.i/main/src/library/i/library.js
index e1c0e2cb0..f70247c43 100644
--- a/test/fixtures/library.i/main/src/library/i/library.js
+++ b/test/fixtures/library.i/main/src/library/i/library.js
@@ -2,7 +2,7 @@
* ${copyright}
*/
sap.ui.define([
- 'sap/ui/core/Core',
+ 'sap/ui/core/Core'
], function(Core) {
"use strict";
@@ -13,10 +13,10 @@ sap.ui.define([
dependencies : ["sap.ui.core"],
types: [
"library.i.ButtonType",
- "library.i.DialogType",
+ "library.i.DialogType"
],
interfaces: [
- "library.i.IContent",
+ "library.i.IContent"
],
controls: [
"library.i.Button",
diff --git a/test/lib/builder/builder.js b/test/lib/builder/builder.js
index 8b1bcf5d4..c4bd73b2c 100644
--- a/test/lib/builder/builder.js
+++ b/test/lib/builder/builder.js
@@ -569,35 +569,37 @@ test.serial("Cleanup", async (t) => {
});
+const coreLibraryTree = {
+ "id": "sap.ui.core-evo",
+ "version": "1.0.0",
+ "path": libraryCore,
+ "dependencies": [],
+ "_level": 0,
+ "specVersion": "0.1",
+ "type": "library",
+ "metadata": {
+ "name": "sap.ui.core",
+ "namespace": "sap/ui/core",
+ "copyright": "Some fancy copyright"
+ },
+ "resources": {
+ "configuration": {
+ "paths": {
+ "src": "main/src"
+ }
+ },
+ "pathMappings": {
+ "/resources/": "main/src"
+ }
+ }
+};
+
const libraryDTree = {
"id": "library.d",
"version": "1.0.0",
"path": libraryDPath,
"dependencies": [
- {
- "id": "sap.ui.core-evo",
- "version": "1.0.0",
- "path": libraryCore,
- "dependencies": [],
- "_level": 1,
- "specVersion": "0.1",
- "type": "library",
- "metadata": {
- "name": "sap.ui.core",
- "namespace": "sap/ui/core",
- "copyright": "Some fancy copyright"
- },
- "resources": {
- "configuration": {
- "paths": {
- "src": "main/src"
- }
- },
- "pathMappings": {
- "/resources/": "main/src"
- }
- }
- }
+ cloneProjectTree(coreLibraryTree)
],
"_level": 0,
"specVersion": "0.1",
@@ -762,7 +764,9 @@ const applicationGTree = {
"namespace": "application/g",
"copyright": "Some fancy copyright"
},
- "dependencies": [],
+ "dependencies": [
+ cloneProjectTree(coreLibraryTree)
+ ],
"resources": {
"configuration": {
"paths": {
@@ -797,7 +801,9 @@ const applicationGTreeWithExcludes = {
"namespace": "application/g",
"copyright": "Some fancy copyright"
},
- "dependencies": [],
+ "dependencies": [
+ cloneProjectTree(coreLibraryTree)
+ ],
"resources": {
"configuration": {
"paths": {
@@ -833,7 +839,9 @@ const applicationGTreeComponentPreloadPaths = {
"namespace": "application/g",
"copyright": "Some fancy copyright"
},
- "dependencies": [],
+ "dependencies": [
+ cloneProjectTree(coreLibraryTree)
+ ],
"resources": {
"configuration": {
"paths": {
@@ -865,7 +873,9 @@ const applicationHTree = {
"name": "application.h",
"namespace": "application/h"
},
- "dependencies": [],
+ "dependencies": [
+ cloneProjectTree(coreLibraryTree)
+ ],
"resources": {
"configuration": {
"paths": {
@@ -926,7 +936,9 @@ const applicationITree = {
"name": "application.i",
"namespace": "application/i"
},
- "dependencies": [],
+ "dependencies": [
+ cloneProjectTree(coreLibraryTree)
+ ],
"resources": {
"configuration": {
"paths": {
@@ -954,7 +966,9 @@ const applicationJTree = {
"name": "application.j",
"namespace": "application/j"
},
- "dependencies": [],
+ "dependencies": [
+ cloneProjectTree(coreLibraryTree)
+ ],
"resources": {
"configuration": {
"paths": {
@@ -976,30 +990,7 @@ const libraryETree = {
"version": "1.0.0",
"path": libraryEPath,
"dependencies": [
- {
- "id": "sap.ui.core-evo",
- "version": "1.0.0",
- "path": libraryCore,
- "dependencies": [],
- "_level": 1,
- "specVersion": "0.1",
- "type": "library",
- "metadata": {
- "name": "sap.ui.core",
- "namespace": "sap/ui/core",
- "copyright": "Some fancy copyright"
- },
- "resources": {
- "configuration": {
- "paths": {
- "src": "main/src"
- }
- },
- "pathMappings": {
- "/resources/": "main/src"
- }
- }
- }
+ cloneProjectTree(coreLibraryTree)
],
"_level": 0,
"specVersion": "0.1",
@@ -1029,30 +1020,7 @@ const libraryHTree = {
"version": "1.0.0",
"path": libraryHPath,
"dependencies": [
- {
- "id": "sap.ui.core-evo",
- "version": "1.0.0",
- "path": libraryCore,
- "dependencies": [],
- "_level": 1,
- "specVersion": "0.1",
- "type": "library",
- "metadata": {
- "name": "sap.ui.core",
- "namespace": "sap/ui/core",
- "copyright": "Some fancy copyright"
- },
- "resources": {
- "configuration": {
- "paths": {
- "src": "main/src"
- }
- },
- "pathMappings": {
- "/resources/": "main/src"
- }
- }
- }
+ cloneProjectTree(coreLibraryTree)
],
"_level": 0,
"specVersion": "0.1",
@@ -1114,30 +1082,7 @@ const libraryITree = {
"version": "1.0.0",
"path": libraryIPath,
"dependencies": [
- {
- "id": "sap.ui.core-evo",
- "version": "1.0.0",
- "path": libraryCore,
- "dependencies": [],
- "_level": 1,
- "specVersion": "0.1",
- "type": "library",
- "metadata": {
- "name": "sap.ui.core",
- "namespace": "sap/ui/core",
- "copyright": "Some fancy copyright"
- },
- "resources": {
- "configuration": {
- "paths": {
- "src": "main/src"
- }
- },
- "pathMappings": {
- "/resources/": "main/src"
- }
- }
- },
+ cloneProjectTree(coreLibraryTree),
cloneProjectTree(libraryDTree)
],
"_level": 0,
@@ -1166,7 +1111,9 @@ const libraryJTree = {
"id": "library.j",
"version": "1.0.0",
"path": libraryJPath,
- "dependencies": [],
+ "dependencies": [
+ cloneProjectTree(coreLibraryTree)
+ ],
"_level": 0,
"specVersion": "0.1",
"type": "library",
diff --git a/test/lib/tasks/bundlers/generateLibraryPreload.js b/test/lib/tasks/bundlers/generateLibraryPreload.js
index 11790e88d..c0e890d91 100644
--- a/test/lib/tasks/bundlers/generateLibraryPreload.js
+++ b/test/lib/tasks/bundlers/generateLibraryPreload.js
@@ -42,7 +42,7 @@ test("integration: build library.d with library preload", async (t) => {
assert.directoryDeepEqual(destPath, expectedPath);
// Check for all file contents
- t.deepEqual(expectedFiles.length, 4, "4 files are expected");
+ t.deepEqual(expectedFiles.length, 5, "5 files are expected");
expectedFiles.forEach((expectedFile) => {
const relativeFile = path.relative(expectedPath, expectedFile);
const destFile = path.join(destPath, relativeFile);
@@ -95,7 +95,7 @@ test("integration: build sap.ui.core with library preload", async (t) => {
assert.directoryDeepEqual(destPath, expectedPath);
// Check for all file contents
- t.deepEqual(expectedFiles.length, 9, "9 files are expected");
+ t.deepEqual(expectedFiles.length, 10, "10 files are expected");
expectedFiles.forEach((expectedFile) => {
const relativeFile = path.relative(expectedPath, expectedFile);
const destFile = path.join(destPath, relativeFile);
diff --git a/test/lib/tasks/generateCachebusterInfo.js b/test/lib/tasks/generateCachebusterInfo.js
index d577641dc..9a0d3b0fe 100644
--- a/test/lib/tasks/generateCachebusterInfo.js
+++ b/test/lib/tasks/generateCachebusterInfo.js
@@ -9,6 +9,7 @@ const assert = chai.assert;
const ui5Builder = require("../../../");
const builder = ui5Builder.builder;
const applicationGPath = path.join(__dirname, "..", "..", "fixtures", "application.g");
+const libraryCore = path.join(__dirname, "..", "..", "fixtures", "sap.ui.core-evo");
const recursive = require("recursive-readdir");
@@ -24,6 +25,20 @@ const findFiles = (folder) => {
});
};
+function cloneProjectTree(tree) {
+ const clone = JSON.parse(JSON.stringify(tree));
+
+ function increaseDepth(node) {
+ node._level++;
+ if (Array.isArray(node.dependencies)) {
+ node.dependencies.forEach(increaseDepth);
+ }
+ }
+
+ increaseDepth(clone);
+ return clone;
+}
+
test("integration: Build application.g with manifestBundler", (t) => {
const destPath = path.join("test", "tmp", "build", "application.g", "cachebuster");
const expectedPath = path.join("test", "expected", "build", "application.g", "cachebuster");
@@ -90,11 +105,37 @@ test("integration: Build application.g with manifestBundler and cachebuster usin
});
});
+const coreLibraryTree = {
+ "id": "sap.ui.core-evo",
+ "version": "1.0.0",
+ "path": libraryCore,
+ "dependencies": [],
+ "_level": 0,
+ "specVersion": "0.1",
+ "type": "library",
+ "metadata": {
+ "name": "sap.ui.core",
+ "copyright": "Some fancy copyright"
+ },
+ "resources": {
+ "configuration": {
+ "paths": {
+ "src": "main/src"
+ }
+ },
+ "pathMappings": {
+ "/resources/": "main/src"
+ }
+ }
+};
+
const applicationGTree = {
"id": "application.g",
"version": "1.0.0",
"path": applicationGPath,
- "dependencies": [],
+ "dependencies": [
+ cloneProjectTree(coreLibraryTree)
+ ],
"builder": {},
"_level": 0,
"specVersion": "0.1",
@@ -120,7 +161,9 @@ const applicationGTreeWithCachebusterHash = {
"id": "application.g",
"version": "1.0.0",
"path": applicationGPath,
- "dependencies": [],
+ "dependencies": [
+ cloneProjectTree(coreLibraryTree)
+ ],
"builder": {
"cachebuster": {
"signatureType": "hash"