Skip to content

Commit 1394787

Browse files
matz3codeworriorRandomByte
authored
[ui5-builder][FIX] Avoid redundant bundle creation (#741)
When a custom bundle has the same name as a built-in bundle (e.g. foo/bar/library-preload.js), then the creation of the built-in bundle can be skipped. Co-authored-by: Frank Weigel <[email protected]> Co-authored-by: Merlin Beutlberger <[email protected]>
1 parent 639b20e commit 1394787

File tree

4 files changed

+99
-79
lines changed

4 files changed

+99
-79
lines changed

packages/builder/lib/tasks/bundlers/generateComponentPreload.js

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,11 @@ const {negateFilters} = require("../../lbt/resources/ResourceFilterList");
2121
* inclusion overrides an earlier exclusion, and vice versa.
2222
* @param {string[]} [parameters.options.paths] Array of paths (or glob patterns) for component files
2323
* @param {string[]} [parameters.options.namespaces] Array of component namespaces
24+
* @param {string[]} [parameters.options.skipBundles] Names of bundles that should not be created
2425
* @returns {Promise<undefined>} Promise resolving with <code>undefined</code> once data has been written
2526
*/
2627
module.exports = function({
27-
workspace, taskUtil, options: {projectName, paths, namespaces, excludes = []}
28+
workspace, taskUtil, options: {projectName, paths, namespaces, skipBundles = [], excludes = []}
2829
}) {
2930
let nonDbgWorkspace = workspace;
3031
if (taskUtil) {
@@ -65,6 +66,12 @@ module.exports = function({
6566
const unusedFilterExcludes = new Set(allFilterExcludes);
6667

6768
const bundleDefinitions = allNamespaces.map((namespace) => {
69+
const bundleName = `${namespace}/Component-preload.js`;
70+
if (skipBundles.includes(bundleName)) {
71+
log.verbose(`Skipping generation of bundle ${bundleName}`);
72+
return null;
73+
}
74+
6875
const filters = [
6976
`${namespace}/`,
7077
`${namespace}/**/manifest.json`,
@@ -94,7 +101,7 @@ module.exports = function({
94101
});
95102

96103
return {
97-
name: `${namespace}/Component-preload.js`,
104+
name: bundleName,
98105
defaultFileTypes: [
99106
".js",
100107
".control.xml",
@@ -127,7 +134,7 @@ module.exports = function({
127134
});
128135
}
129136

130-
return Promise.all(bundleDefinitions.map((bundleDefinition) => {
137+
return Promise.all(bundleDefinitions.filter(Boolean).map((bundleDefinition) => {
131138
log.verbose(`Generating ${bundleDefinition.name}...`);
132139
return moduleBundler({
133140
resources,

packages/builder/lib/tasks/bundlers/generateLibraryPreload.js

Lines changed: 73 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -142,48 +142,6 @@ function getSupportFilesBundleDefinition(namespace) {
142142
};
143143
}
144144

145-
function createLibraryBundles(libraryNamespace, resources, excludes) {
146-
return Promise.all([
147-
moduleBundler({
148-
options: {
149-
bundleDefinition: getBundleDefinition(libraryNamespace, excludes),
150-
bundleOptions: {
151-
optimize: true,
152-
usePredefineCalls: true,
153-
ignoreMissingModules: true
154-
}
155-
},
156-
resources
157-
}),
158-
moduleBundler({
159-
options: {
160-
bundleDefinition: getDesigntimeBundleDefinition(libraryNamespace),
161-
bundleOptions: {
162-
optimize: true,
163-
usePredefineCalls: true,
164-
ignoreMissingModules: true,
165-
skipIfEmpty: true
166-
}
167-
},
168-
resources
169-
}),
170-
moduleBundler({
171-
options: {
172-
bundleDefinition: getSupportFilesBundleDefinition(libraryNamespace),
173-
bundleOptions: {
174-
optimize: false,
175-
usePredefineCalls: true,
176-
ignoreMissingModules: true,
177-
skipIfEmpty: true
178-
}
179-
// Note: Although the bundle uses optimize=false, there is
180-
// no moduleNameMapping needed, as support files are excluded from minification.
181-
},
182-
resources
183-
})
184-
]);
185-
}
186-
187145
function getModuleBundlerOptions(config) {
188146
const moduleBundlerOptions = {};
189147

@@ -274,9 +232,10 @@ function getSapUiCoreBunDef(name, filters, preload) {
274232
* inclusion overrides an earlier exclusion, and vice versa.
275233
* @param {object} parameters.options Options
276234
* @param {string} parameters.options.projectName Project name
235+
* @param {string[]} [parameters.options.skipBundles] Names of bundles that should not be created
277236
* @returns {Promise<undefined>} Promise resolving with <code>undefined</code> once data has been written
278237
*/
279-
module.exports = function({workspace, taskUtil, options: {projectName, excludes = []}}) {
238+
module.exports = function({workspace, taskUtil, options: {projectName, skipBundles = [], excludes = []}}) {
280239
let nonDbgWorkspace = workspace;
281240
if (taskUtil) {
282241
nonDbgWorkspace = workspace.filter(function(resource) {
@@ -285,6 +244,14 @@ module.exports = function({workspace, taskUtil, options: {projectName, excludes
285244
});
286245
}
287246

247+
const execModuleBundlerIfNeeded = ({options, resources}) => {
248+
if (skipBundles.includes(options.bundleDefinition.name)) {
249+
log.verbose(`Skipping generation of bundle ${options.bundleDefinition.name}`);
250+
return null;
251+
}
252+
return moduleBundler({options, resources});
253+
};
254+
288255
return nonDbgWorkspace.byGlob("/**/*.{js,json,xml,html,properties,library,js.map}").then(async (resources) => {
289256
// Find all libraries and create a library-preload.js bundle
290257

@@ -326,32 +293,32 @@ module.exports = function({workspace, taskUtil, options: {projectName, excludes
326293
filters = ["jquery.sap.global.js"];
327294
}
328295
p = Promise.all([
329-
moduleBundler({
296+
execModuleBundlerIfNeeded({
330297
options: getModuleBundlerOptions({name: "sap-ui-core.js", filters, preload: true}),
331298
resources
332299
}),
333-
moduleBundler({
300+
execModuleBundlerIfNeeded({
334301
options: getModuleBundlerOptions({
335302
name: "sap-ui-core-dbg.js", filters, preload: false,
336303
moduleNameMapping: unoptimizedModuleNameMapping
337304
}),
338305
resources: unoptimizedResources
339306
}),
340-
moduleBundler({
307+
execModuleBundlerIfNeeded({
341308
options: getModuleBundlerOptions({
342309
name: "sap-ui-core-nojQuery.js", filters, preload: true, provided: true
343310
}),
344311
resources
345312
}),
346-
moduleBundler({
313+
execModuleBundlerIfNeeded({
347314
options: getModuleBundlerOptions({
348315
name: "sap-ui-core-nojQuery-dbg.js", filters, preload: false, provided: true,
349316
moduleNameMapping: unoptimizedModuleNameMapping
350317
}),
351318
resources: unoptimizedResources
352319
}),
353320
]).then((results) => {
354-
const bundles = Array.prototype.concat.apply([], results);
321+
const bundles = Array.prototype.concat.apply([], results).filter(Boolean);
355322
return Promise.all(bundles.map(({bundle, sourceMap}) => {
356323
if (taskUtil) {
357324
taskUtil.setTag(bundle, taskUtil.STANDARD_TAGS.IsBundle);
@@ -390,7 +357,7 @@ module.exports = function({workspace, taskUtil, options: {projectName, excludes
390357
return;
391358
}
392359

393-
return Promise.all(libraryIndicatorResources.map((libraryIndicatorResource) => {
360+
return Promise.all(libraryIndicatorResources.map(async (libraryIndicatorResource) => {
394361
// Determine library namespace from library indicator file path
395362
// ending with either ".library" or "library.js" (see fallback logic above)
396363
// e.g. /resources/sap/foo/.library => sap/foo
@@ -400,28 +367,64 @@ module.exports = function({workspace, taskUtil, options: {projectName, excludes
400367
const libraryNamespaceMatch = libraryIndicatorPath.match(libraryNamespacePattern);
401368
if (libraryNamespaceMatch && libraryNamespaceMatch[1]) {
402369
const libraryNamespace = libraryNamespaceMatch[1];
403-
return createLibraryBundles(libraryNamespace, resources, excludes)
404-
.then((results) => {
405-
const bundles = Array.prototype.concat.apply([], results);
406-
return Promise.all(bundles.map(({bundle, sourceMap} = {}) => {
407-
if (bundle) {
408-
if (taskUtil) {
409-
taskUtil.setTag(bundle, taskUtil.STANDARD_TAGS.IsBundle);
410-
if (sourceMap) {
411-
// Clear tag that might have been set by the minify task, in cases where
412-
// the bundle name is identical to a source file
413-
taskUtil.clearTag(sourceMap,
414-
taskUtil.STANDARD_TAGS.OmitFromBuildResult);
415-
}
416-
}
417-
const writes = [workspace.write(bundle)];
418-
if (sourceMap) {
419-
writes.push(workspace.write(sourceMap));
420-
}
421-
return Promise.all(writes);
370+
const results = await Promise.all([
371+
execModuleBundlerIfNeeded({
372+
options: {
373+
bundleDefinition: getBundleDefinition(libraryNamespace, excludes),
374+
bundleOptions: {
375+
optimize: true,
376+
usePredefineCalls: true,
377+
ignoreMissingModules: true
378+
}
379+
},
380+
resources
381+
}),
382+
execModuleBundlerIfNeeded({
383+
options: {
384+
bundleDefinition: getDesigntimeBundleDefinition(libraryNamespace),
385+
bundleOptions: {
386+
optimize: true,
387+
usePredefineCalls: true,
388+
ignoreMissingModules: true,
389+
skipIfEmpty: true
422390
}
423-
}));
424-
});
391+
},
392+
resources
393+
}),
394+
execModuleBundlerIfNeeded({
395+
options: {
396+
bundleDefinition: getSupportFilesBundleDefinition(libraryNamespace),
397+
bundleOptions: {
398+
optimize: false,
399+
usePredefineCalls: true,
400+
ignoreMissingModules: true,
401+
skipIfEmpty: true
402+
}
403+
// Note: Although the bundle uses optimize=false, there is
404+
// no moduleNameMapping needed, as support files are excluded from minification.
405+
},
406+
resources
407+
})
408+
]);
409+
const bundles = Array.prototype.concat.apply([], results).filter(Boolean);
410+
return Promise.all(bundles.map(({bundle, sourceMap} = {}) => {
411+
if (bundle) {
412+
if (taskUtil) {
413+
taskUtil.setTag(bundle, taskUtil.STANDARD_TAGS.IsBundle);
414+
if (sourceMap) {
415+
// Clear tag that might have been set by the minify task, in cases where
416+
// the bundle name is identical to a source file
417+
taskUtil.clearTag(sourceMap,
418+
taskUtil.STANDARD_TAGS.OmitFromBuildResult);
419+
}
420+
}
421+
const writes = [workspace.write(bundle)];
422+
if (sourceMap) {
423+
writes.push(workspace.write(sourceMap));
424+
}
425+
return Promise.all(writes);
426+
}
427+
}));
425428
} else {
426429
log.verbose(
427430
`Could not determine library namespace from file "${libraryIndicatorPath}" ` +

packages/builder/lib/types/application/ApplicationBuilder.js

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,10 @@ class ApplicationBuilder extends AbstractBuilder {
8888
});
8989
}
9090

91+
const bundles = project.builder?.bundles;
92+
const existingBundleDefinitionNames =
93+
bundles?.map(({bundleDefinition}) => bundleDefinition.name).filter(Boolean) || [];
94+
9195
const componentPreload = project.builder && project.builder.componentPreload;
9296
if (componentPreload && (componentPreload.namespaces || componentPreload.paths)) {
9397
this.addTask("generateComponentPreload", async () => {
@@ -98,7 +102,8 @@ class ApplicationBuilder extends AbstractBuilder {
98102
projectName: project.metadata.name,
99103
paths: componentPreload.paths,
100104
namespaces: componentPreload.namespaces,
101-
excludes: componentPreload.excludes
105+
excludes: componentPreload.excludes,
106+
skipBundles: existingBundleDefinitionNames
102107
}
103108
});
104109
});
@@ -111,7 +116,8 @@ class ApplicationBuilder extends AbstractBuilder {
111116
options: {
112117
projectName: project.metadata.name,
113118
namespaces: [project.metadata.namespace],
114-
excludes: componentPreload && componentPreload.excludes
119+
excludes: componentPreload && componentPreload.excludes,
120+
skipBundles: existingBundleDefinitionNames
115121
}
116122
});
117123
});
@@ -139,7 +145,6 @@ class ApplicationBuilder extends AbstractBuilder {
139145
});
140146
});
141147

142-
const bundles = project.builder && project.builder.bundles;
143148
if (bundles) {
144149
this.addTask("generateBundle", async () => {
145150
return Promise.all(bundles.map((bundle) => {

packages/builder/lib/types/library/LibraryBuilder.js

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,10 @@ class LibraryBuilder extends AbstractBuilder {
132132
});
133133
}
134134

135+
const bundles = project.builder?.bundles;
136+
const existingBundleDefinitionNames =
137+
bundles?.map(({bundleDefinition}) => bundleDefinition.name).filter(Boolean) || [];
138+
135139
const componentPreload = project.builder && project.builder.componentPreload;
136140
if (componentPreload) {
137141
this.addTask("generateComponentPreload", async () => {
@@ -142,7 +146,8 @@ class LibraryBuilder extends AbstractBuilder {
142146
projectName: project.metadata.name,
143147
paths: componentPreload.paths,
144148
namespaces: componentPreload.namespaces,
145-
excludes: componentPreload.excludes
149+
excludes: componentPreload.excludes,
150+
skipBundles: existingBundleDefinitionNames
146151
}
147152
});
148153
});
@@ -157,12 +162,12 @@ class LibraryBuilder extends AbstractBuilder {
157162
excludes:
158163
project.builder &&
159164
project.builder.libraryPreload &&
160-
project.builder.libraryPreload.excludes
165+
project.builder.libraryPreload.excludes,
166+
skipBundles: existingBundleDefinitionNames
161167
}
162168
});
163169
});
164170

165-
const bundles = project.builder && project.builder.bundles;
166171
if (bundles) {
167172
this.addTask("generateBundle", async () => {
168173
return bundles.reduce(function(sequence, bundle) {

0 commit comments

Comments
 (0)