Skip to content

Commit

Permalink
[FEATURE] Build DepCache files (*-h2-preload.js) for HTTP/2 support
Browse files Browse the repository at this point in the history
- implement a new bundle section type 'depcache' in the lbt builder
- ignore pseudo-dependencies 'require', 'module' and 'exports' in
  the dependency analyzer (so that they don't appear in the dependency
  cache)
- add configuration in the library and component preload bundlers
  to create bundles with the new section types in parallel to the
  existing preload bundles (using an '-h2-preload' suffix)
- configure fixture applications g,h,i,j and fixture libraries e,h,i,j
  to use evo bundle format by adding a dependency to the sap.ui.core
  substitute fixture (sap.ui.core-evo)
- add the newly introduced h2-preload bundles to the set of expected
  files in all fixtures that are used with one of the module bundling
  tasks
  • Loading branch information
codeworrior committed Jan 1, 2020
1 parent 53908c8 commit 00ee973
Show file tree
Hide file tree
Showing 30 changed files with 365 additions and 201 deletions.
54 changes: 54 additions & 0 deletions lib/lbt/bundle/Builder.js
Original file line number Diff line number Diff line change
Expand Up @@ -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)}");`);
},
Expand All @@ -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)}");`);
},
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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) => {
Expand Down
6 changes: 6 additions & 0 deletions lib/lbt/bundle/BundleDefinition.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
66 changes: 49 additions & 17 deletions lib/tasks/bundlers/generateComponentPreload.js
Original file line number Diff line number Diff line change
Expand Up @@ -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]);
}));
Expand Down
109 changes: 70 additions & 39 deletions lib/tasks/bundlers/generateLibraryPreload.js
Original file line number Diff line number Diff line change
Expand Up @@ -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: [
{
Expand All @@ -19,7 +21,7 @@ function getBundleDefinition(namespace) {
resolve: true
},
{
mode: "preload",
mode: h2 ? "depcache" : "preload",
filters: [
`${namespace}/`,
`!${namespace}/.library`,
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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();
Expand Down
Original file line number Diff line number Diff line change
@@ -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"]
}});
Original file line number Diff line number Diff line change
@@ -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"}',
Expand All @@ -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}}"}}'
}});
});
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
Original file line number Diff line number Diff line change
@@ -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"]
}});
6 changes: 2 additions & 4 deletions test/expected/build/application.g/dest/Component-preload.js
Original file line number Diff line number Diff line change
@@ -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"}'
}});
});
Original file line number Diff line number Diff line change
@@ -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"]
}});
Original file line number Diff line number Diff line change
@@ -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}}"}}'
}});
});
Original file line number Diff line number Diff line change
@@ -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"]
}});
Loading

0 comments on commit 00ee973

Please sign in to comment.