Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Build DepCache info files (*-h2-preload.js) for better HTTP/2 support #22

Open
wants to merge 1 commit into
base: v2
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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