@ui5/builder 4.1.0 → 4.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -2,10 +2,13 @@
2
2
  All notable changes to this project will be documented in this file.
3
3
  This project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
4
4
 
5
- A list of unreleased changes can be found [here](https://github.com/SAP/ui5-builder/compare/v4.1.0...HEAD).
5
+ A list of unreleased changes can be found [here](https://github.com/SAP/ui5-builder/compare/v4.1.1...HEAD).
6
+
7
+ <a name="v4.1.1"></a>
8
+ ## [v4.1.1] - 2025-10-30
6
9
 
7
10
  <a name="v4.1.0"></a>
8
- ## [v4.1.0] - 2025-10-21
11
+ ## [v4.1.0] - 2025-10-23
9
12
  ### Features
10
13
  - Enhance generateFlexChangeBundle task to add new 'flexBundle' property to the manifest.json ([#1164](https://github.com/SAP/ui5-builder/issues/1164)) [`a48e474`](https://github.com/SAP/ui5-builder/commit/a48e474b1bfb9f2f11da44e908341af370711309)
11
14
 
@@ -998,6 +1001,7 @@ to load the custom bundle file instead.
998
1001
 
999
1002
  ### Features
1000
1003
  - Add ability to configure component preloads and custom bundles [`2241e5f`](https://github.com/SAP/ui5-builder/commit/2241e5ff98fd95f1f80cc74959655ae7a9c660e7)
1004
+ [v4.1.1]: https://github.com/SAP/ui5-builder/compare/v4.1.0...v4.1.1
1001
1005
  [v4.1.0]: https://github.com/SAP/ui5-builder/compare/v4.0.13...v4.1.0
1002
1006
  [v4.0.13]: https://github.com/SAP/ui5-builder/compare/v4.0.11...v4.0.13
1003
1007
  [v4.0.11]: https://github.com/SAP/ui5-builder/compare/v4.0.10...v4.0.11
package/CONTRIBUTING.md CHANGED
@@ -1,3 +1,3 @@
1
1
  # Contributing to the UI5 CLI
2
2
 
3
- See CONTRIBUTING.md in the [UI5/cli](https://github.com/UI5/cli/blob/main/CONTRIBUTING.md) repository.
3
+ See CONTRIBUTING.md in the [UI5/cli](https://github.com/UI5/cli/blob/v4/CONTRIBUTING.md) repository.
package/README.md CHANGED
@@ -24,10 +24,10 @@ UI5 Builder documentation can be found here: [ui5.github.io/cli](https://ui5.git
24
24
  The UI5 Builder API Reference can be found here: [`@ui5/builder`](https://ui5.github.io/cli/v4/api/)
25
25
 
26
26
  ## Contributing
27
- Please check our [Contribution Guidelines](https://github.com/UI5/cli/blob/main/CONTRIBUTING.md).
27
+ Please check our [Contribution Guidelines](https://github.com/UI5/cli/blob/v4/CONTRIBUTING.md).
28
28
 
29
29
  ## Support
30
- Please follow our [Contribution Guidelines](https://github.com/UI5/cli/blob/main/CONTRIBUTING.md#report-an-issue) on how to report an issue.
30
+ Please follow our [Contribution Guidelines](https://github.com/UI5/cli/blob/v4/CONTRIBUTING.md#report-an-issue) on how to report an issue.
31
31
 
32
32
  Please report issues in the main [UI5 CLI](https://github.com/UI5/cli) repository.
33
33
 
@@ -56,6 +56,7 @@ class BundleResolver {
56
56
  * in the resource pool.
57
57
  */
58
58
  const missingModules = Object.create(null);
59
+ const ignoreMissingModules = pool.getIgnoreMissingModules();
59
60
  /**
60
61
  * Names of modules that are included in non-decomposable bundles.
61
62
  * If they occur in the missingModules, then this is not an error.
@@ -123,7 +124,7 @@ class BundleResolver {
123
124
  done = pool.findResourceWithInfo(resourceName)
124
125
  .catch( (err) => {
125
126
  // if the caller provided an error message, log it
126
- if ( msg ) {
127
+ if ( msg && !ignoreMissingModules ) {
127
128
  missingModules[resourceName] ??= [];
128
129
  missingModules[resourceName].push(msg);
129
130
  }
@@ -1,3 +1,4 @@
1
+ import semver from "semver";
1
2
  import {getLogger} from "@ui5/logger";
2
3
  const log = getLogger("builder:tasks:bundlers:generateLibraryPreload");
3
4
  import moduleBundler from "../../processors/bundlers/moduleBundler.js";
@@ -32,6 +33,32 @@ function getDefaultLibraryPreloadFilters(namespace, excludes) {
32
33
  return filters;
33
34
  }
34
35
 
36
+ function getExperimentalDefaultLibraryPreloadFilters(namespace, excludes) {
37
+ const filters = [
38
+ `${namespace}/library.js`,
39
+ `!${namespace}/**/*-preload.js`, // exclude all bundles
40
+ `!${namespace}/designtime/`,
41
+ `!${namespace}/**/*.designtime.js`,
42
+ `!${namespace}/**/*.support.js`
43
+ ];
44
+
45
+ if (Array.isArray(excludes)) {
46
+ const allFilterExcludes = negateFilters(excludes);
47
+ // Add configured excludes at the end of filter list
48
+ allFilterExcludes.forEach((filterExclude) => {
49
+ // Allow all excludes (!) and limit re-includes (+) to the library namespace
50
+ if (filterExclude.startsWith("!") || filterExclude.startsWith(`+${namespace}/`)) {
51
+ filters.push(filterExclude);
52
+ } else {
53
+ log.warn(`Configured preload exclude contains invalid re-include: !${filterExclude.substr(1)}. ` +
54
+ `Re-includes must start with the library's namespace ${namespace}`);
55
+ }
56
+ });
57
+ }
58
+
59
+ return filters;
60
+ }
61
+
35
62
  function getBundleDefinition(namespace, excludes) {
36
63
  // Note: This configuration is only used when no bundle definition in ui5.yaml exists (see "skipBundles" parameter)
37
64
 
@@ -106,6 +133,69 @@ function getBundleDefinition(namespace, excludes) {
106
133
  };
107
134
  }
108
135
 
136
+ function getBundleInfoPreloadDefinition(namespace, excludes, coreVersion) {
137
+ const sections = [{
138
+ mode: "preload",
139
+ filters: getExperimentalDefaultLibraryPreloadFilters(namespace, excludes),
140
+ resolve: true
141
+ },
142
+ {
143
+ mode: "bundleInfo",
144
+ name: `${namespace}/library-content.js`,
145
+ filters: getDefaultLibraryPreloadFilters(namespace, excludes),
146
+ resolve: false,
147
+ resolveConditional: false,
148
+ renderer: true
149
+ }];
150
+
151
+ if (coreVersion) {
152
+ const parsedVersion = semver.parse(coreVersion);
153
+ let targetUi5CoreVersionMajor = parsedVersion.major;
154
+
155
+ // legacy-free versions include changes of the upcoming major version
156
+ // so we should treat them the same as the next major version
157
+ if (
158
+ parsedVersion.prerelease.includes("legacy-free") ||
159
+ parsedVersion.prerelease.includes("legacy-free-SNAPSHOT") // Maven snapshot version
160
+ ) {
161
+ targetUi5CoreVersionMajor += 1;
162
+ }
163
+ if (parsedVersion) {
164
+ if (targetUi5CoreVersionMajor >= 2) {
165
+ // Do not include manifest.json in UI5 2.x and higher to allow for loading it upfront for all libraries
166
+ sections.unshift({
167
+ mode: "provided",
168
+ filters: [
169
+ `${namespace}/manifest.json`,
170
+ ]
171
+ });
172
+ }
173
+ }
174
+ }
175
+
176
+ return {
177
+ name: `${namespace}/library-preload.js`,
178
+ sections,
179
+ };
180
+ }
181
+
182
+ function getContentBundleDefinition(namespace, excludes) {
183
+ return {
184
+ name: `${namespace}/library-content.js`,
185
+ sections: [{
186
+ mode: "provided",
187
+ filters: getExperimentalDefaultLibraryPreloadFilters(namespace, excludes),
188
+ resolve: true
189
+ }, {
190
+ mode: "preload",
191
+ filters: getDefaultLibraryPreloadFilters(namespace, excludes),
192
+ resolve: false,
193
+ resolveConditional: false,
194
+ renderer: true
195
+ }]
196
+ };
197
+ }
198
+
109
199
  function getDesigntimeBundleDefinition(namespace) {
110
200
  return {
111
201
  name: `${namespace}/designtime/library-preload.designtime.js`,
@@ -258,6 +348,7 @@ export default async function({workspace, taskUtil, options: {skipBundles = [],
258
348
  }
259
349
  const coreVersion = taskUtil?.getProject("sap.ui.core")?.getVersion();
260
350
  const allowStringBundling = taskUtil?.getProject().getSpecVersion().lt("4.0");
351
+ const createBundleInfoPreload = !!process.env.UI5_CLI_EXPERIMENTAL_BUNDLE_INFO_PRELOAD;
261
352
  const execModuleBundlerIfNeeded = ({options, resources}) => {
262
353
  if (skipBundles.includes(options.bundleDefinition.name)) {
263
354
  log.verbose(`Skipping generation of bundle ${options.bundleDefinition.name}`);
@@ -390,42 +481,99 @@ export default async function({workspace, taskUtil, options: {skipBundles = [],
390
481
  const libraryNamespaceMatch = libraryIndicatorPath.match(libraryNamespacePattern);
391
482
  if (libraryNamespaceMatch && libraryNamespaceMatch[1]) {
392
483
  const libraryNamespace = libraryNamespaceMatch[1];
393
- const results = await Promise.all([
394
- execModuleBundlerIfNeeded({
395
- options: {
396
- bundleDefinition: getBundleDefinition(libraryNamespace, excludes),
397
- bundleOptions: {
398
- optimize: true,
399
- ignoreMissingModules: true
400
- }
401
- },
402
- resources
403
- }),
404
- execModuleBundlerIfNeeded({
405
- options: {
406
- bundleDefinition: getDesigntimeBundleDefinition(libraryNamespace),
407
- bundleOptions: {
408
- optimize: true,
409
- ignoreMissingModules: true,
410
- skipIfEmpty: true
411
- }
412
- },
413
- resources
414
- }),
415
- execModuleBundlerIfNeeded({
416
- options: {
417
- bundleDefinition: getSupportFilesBundleDefinition(libraryNamespace),
418
- bundleOptions: {
419
- optimize: false,
420
- ignoreMissingModules: true,
421
- skipIfEmpty: true
422
- }
423
- // Note: Although the bundle uses optimize=false, there is
424
- // no moduleNameMapping needed, as support files are excluded from minification.
425
- },
426
- resources
427
- })
428
- ]);
484
+ let results;
485
+ if (!createBundleInfoPreload) {
486
+ // Regular bundling
487
+ results = await Promise.all([
488
+ execModuleBundlerIfNeeded({
489
+ options: {
490
+ bundleDefinition: getBundleDefinition(libraryNamespace, excludes),
491
+ bundleOptions: {
492
+ optimize: true,
493
+ ignoreMissingModules: true
494
+ }
495
+ },
496
+ resources
497
+ }),
498
+ execModuleBundlerIfNeeded({
499
+ options: {
500
+ bundleDefinition: getDesigntimeBundleDefinition(libraryNamespace),
501
+ bundleOptions: {
502
+ optimize: true,
503
+ ignoreMissingModules: true,
504
+ skipIfEmpty: true
505
+ }
506
+ },
507
+ resources
508
+ }),
509
+ execModuleBundlerIfNeeded({
510
+ options: {
511
+ bundleDefinition: getSupportFilesBundleDefinition(libraryNamespace),
512
+ bundleOptions: {
513
+ optimize: false,
514
+ ignoreMissingModules: true,
515
+ skipIfEmpty: true
516
+ }
517
+ // Note: Although the bundle uses optimize=false, there is
518
+ // no moduleNameMapping needed, as support files are excluded from minification.
519
+ },
520
+ resources
521
+ })
522
+ ]);
523
+ } else {
524
+ log.info(
525
+ `Using experimental bundling with bundle info preload ` +
526
+ `for library ${libraryNamespace} in project ${projectName}`);
527
+ log.info(`Detected sap.ui.core version is ${coreVersion || "unknown"}`);
528
+ // Experimental bundling with bundle info preload
529
+ results = await Promise.all([
530
+ execModuleBundlerIfNeeded({
531
+ options: {
532
+ bundleDefinition:
533
+ getBundleInfoPreloadDefinition(libraryNamespace, excludes, coreVersion),
534
+ bundleOptions: {
535
+ optimize: true,
536
+ ignoreMissingModules: true
537
+ }
538
+ },
539
+ resources
540
+ }),
541
+ execModuleBundlerIfNeeded({
542
+ options: {
543
+ bundleDefinition: getContentBundleDefinition(libraryNamespace, excludes),
544
+ bundleOptions: {
545
+ optimize: true,
546
+ ignoreMissingModules: true
547
+ }
548
+ },
549
+ resources
550
+ }),
551
+ execModuleBundlerIfNeeded({
552
+ options: {
553
+ bundleDefinition: getDesigntimeBundleDefinition(libraryNamespace),
554
+ bundleOptions: {
555
+ optimize: true,
556
+ ignoreMissingModules: true,
557
+ skipIfEmpty: true
558
+ }
559
+ },
560
+ resources
561
+ }),
562
+ execModuleBundlerIfNeeded({
563
+ options: {
564
+ bundleDefinition: getSupportFilesBundleDefinition(libraryNamespace),
565
+ bundleOptions: {
566
+ optimize: false,
567
+ ignoreMissingModules: true,
568
+ skipIfEmpty: true
569
+ }
570
+ // Note: Although the bundle uses optimize=false, there is
571
+ // no moduleNameMapping needed, as support files are excluded from minification.
572
+ },
573
+ resources
574
+ })
575
+ ]);
576
+ }
429
577
  const bundles = Array.prototype.concat.apply([], results).filter(Boolean);
430
578
  return Promise.all(bundles.map(({bundle, sourceMap} = {}) => {
431
579
  if (bundle) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ui5/builder",
3
- "version": "4.1.0",
3
+ "version": "4.1.1",
4
4
  "description": "UI5 CLI - Builder",
5
5
  "author": {
6
6
  "name": "SAP SE",
@@ -141,7 +141,7 @@
141
141
  "@eslint/js": "^9.14.0",
142
142
  "@istanbuljs/esm-loader-hook": "^0.3.0",
143
143
  "@jridgewell/trace-mapping": "^0.3.31",
144
- "@ui5/project": "^4.0.6",
144
+ "@ui5/project": "^4.0.8",
145
145
  "ava": "^6.4.1",
146
146
  "chokidar-cli": "^3.0.0",
147
147
  "cross-env": "^7.0.3",