@ui5/builder 3.0.0-rc.2 → 3.0.0-rc.4

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.
Files changed (45) hide show
  1. package/CHANGELOG.md +13 -2
  2. package/lib/lbt/analyzer/ComponentAnalyzer.js +2 -2
  3. package/lib/lbt/analyzer/FioriElementsAnalyzer.js +2 -2
  4. package/lib/lbt/analyzer/JSModuleAnalyzer.js +2 -2
  5. package/lib/lbt/analyzer/SmartTemplateAnalyzer.js +2 -2
  6. package/lib/lbt/analyzer/XMLCompositeAnalyzer.js +2 -2
  7. package/lib/lbt/analyzer/XMLTemplateAnalyzer.js +2 -2
  8. package/lib/lbt/analyzer/analyzeLibraryJS.js +2 -2
  9. package/lib/lbt/bundle/AutoSplitter.js +2 -2
  10. package/lib/lbt/bundle/Builder.js +2 -2
  11. package/lib/lbt/bundle/Resolver.js +2 -2
  12. package/lib/lbt/graph/dependencyGraph.js +2 -2
  13. package/lib/lbt/graph/dominatorTree.js +2 -2
  14. package/lib/lbt/graph/topologicalSort.js +2 -2
  15. package/lib/lbt/resources/LibraryFileAnalyzer.js +2 -2
  16. package/lib/lbt/resources/ResourceCollector.js +2 -2
  17. package/lib/lbt/resources/ResourceFilterList.js +2 -2
  18. package/lib/lbt/resources/ResourcePool.js +2 -2
  19. package/lib/processors/bootstrapHtmlTransformer.js +2 -2
  20. package/lib/processors/bundlers/flexChangesBundler.js +2 -2
  21. package/lib/processors/bundlers/moduleBundler.js +2 -2
  22. package/lib/processors/jsdoc/lib/createIndexFiles.cjs +1 -1
  23. package/lib/processors/jsdoc/lib/transformApiJson.cjs +1 -1
  24. package/lib/processors/jsdoc/lib/ui5/plugin.cjs +22 -3
  25. package/lib/processors/jsdoc/lib/ui5/template/publish.cjs +12 -1
  26. package/lib/processors/libraryLessGenerator.js +2 -2
  27. package/lib/processors/manifestCreator.js +2 -2
  28. package/lib/processors/minifier.js +74 -53
  29. package/lib/processors/minifierWorker.js +77 -0
  30. package/lib/processors/resourceListCreator.js +2 -2
  31. package/lib/processors/themeBuilder.js +2 -2
  32. package/lib/processors/versionInfoGenerator.js +2 -2
  33. package/lib/tasks/buildThemes.js +2 -2
  34. package/lib/tasks/bundlers/generateComponentPreload.js +2 -2
  35. package/lib/tasks/bundlers/generateFlexChangesBundle.js +2 -2
  36. package/lib/tasks/bundlers/generateLibraryPreload.js +2 -2
  37. package/lib/tasks/bundlers/generateStandaloneAppBundle.js +2 -2
  38. package/lib/tasks/generateCachebusterInfo.js +2 -2
  39. package/lib/tasks/generateLibraryManifest.js +2 -2
  40. package/lib/tasks/generateThemeDesignerResources.js +2 -2
  41. package/lib/tasks/jsdoc/executeJsdocSdkTransformation.js +2 -2
  42. package/lib/tasks/jsdoc/generateJsdoc.js +2 -2
  43. package/lib/tasks/minify.js +3 -1
  44. package/lib/tasks/transformBootstrapHtml.js +2 -2
  45. package/package.json +9 -8
package/CHANGELOG.md CHANGED
@@ -2,10 +2,19 @@
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/v3.0.0-rc.2...HEAD).
5
+ A list of unreleased changes can be found [here](https://github.com/SAP/ui5-builder/compare/v3.0.0-rc.4...HEAD).
6
+
7
+ <a name="v3.0.0-rc.4"></a>
8
+ ## [v3.0.0-rc.4] - 2023-02-03
9
+ ### Features
10
+ - **minify task:** Use workerpool for terser ([#875](https://github.com/SAP/ui5-builder/issues/875)) [`ff4c6fb`](https://github.com/SAP/ui5-builder/commit/ff4c6fbd81c912239cd578fdcd452364ac4ae859)
11
+
12
+
13
+ <a name="v3.0.0-rc.3"></a>
14
+ ## [v3.0.0-rc.3] - 2023-01-24
6
15
 
7
16
  <a name="v3.0.0-rc.2"></a>
8
- ## [v3.0.0-rc.2] - 2023-01-22
17
+ ## [v3.0.0-rc.2] - 2023-01-23
9
18
  ### Dependency Updates
10
19
  - Bump rimraf from 3.0.2 to 4.1.1 ([#873](https://github.com/SAP/ui5-builder/issues/873)) [`ddb9660`](https://github.com/SAP/ui5-builder/commit/ddb96602fea5b96ba37afdebda0993d847462f52)
11
20
 
@@ -843,6 +852,8 @@ to load the custom bundle file instead.
843
852
  - Add ability to configure component preloads and custom bundles [`2241e5f`](https://github.com/SAP/ui5-builder/commit/2241e5ff98fd95f1f80cc74959655ae7a9c660e7)
844
853
 
845
854
 
855
+ [v3.0.0-rc.4]: https://github.com/SAP/ui5-builder/compare/v3.0.0-rc.3...v3.0.0-rc.4
856
+ [v3.0.0-rc.3]: https://github.com/SAP/ui5-builder/compare/v3.0.0-rc.2...v3.0.0-rc.3
846
857
  [v3.0.0-rc.2]: https://github.com/SAP/ui5-builder/compare/v3.0.0-rc.1...v3.0.0-rc.2
847
858
  [v3.0.0-rc.1]: https://github.com/SAP/ui5-builder/compare/v3.0.0-rc.0...v3.0.0-rc.1
848
859
  [v3.0.0-rc.0]: https://github.com/SAP/ui5-builder/compare/v3.0.0-beta.6...v3.0.0-rc.0
@@ -20,8 +20,8 @@
20
20
  */
21
21
 
22
22
  import {fromUI5LegacyName} from "../utils/ModuleName.js";
23
- import logger from "@ui5/logger";
24
- const log = logger.getLogger("lbt:analyzer:ComponentAnalyzer");
23
+ import {getLogger} from "@ui5/logger";
24
+ const log = getLogger("lbt:analyzer:ComponentAnalyzer");
25
25
 
26
26
  // ---------------------------------------------------------------------------------------------------------
27
27
 
@@ -61,8 +61,8 @@ import {fromUI5LegacyName} from "../utils/ModuleName.js";
61
61
  import SapUiDefine from "../calls/SapUiDefine.js";
62
62
  import {parseJS, Syntax} from "../utils/parseUtils.js";
63
63
  import {getValue, isMethodCall, getStringValue} from "../utils/ASTUtils.js";
64
- import logger from "@ui5/logger";
65
- const log = logger.getLogger("lbt:analyzer:FioriElementAnalyzer");
64
+ import {getLogger} from "@ui5/logger";
65
+ const log = getLogger("lbt:analyzer:FioriElementAnalyzer");
66
66
 
67
67
  // ---------------------------------------------------------------------------------------------------------
68
68
 
@@ -13,9 +13,9 @@ import {
13
13
  getStringValue,
14
14
  } from "../utils/ASTUtils.js";
15
15
 
16
- import logger from "@ui5/logger";
16
+ import {getLogger} from "@ui5/logger";
17
17
 
18
- const log = logger.getLogger("lbt:analyzer:JSModuleAnalyzer");
18
+ const log = getLogger("lbt:analyzer:JSModuleAnalyzer");
19
19
 
20
20
  // ------------------------------------------------------------------------------------------------------------------
21
21
 
@@ -28,8 +28,8 @@ import {fromUI5LegacyName} from "../utils/ModuleName.js";
28
28
  import SapUiDefine from "../calls/SapUiDefine.js";
29
29
  import {parseJS, Syntax} from "../utils/parseUtils.js";
30
30
  import {getValue, isMethodCall, getStringValue} from "../utils/ASTUtils.js";
31
- import logger from "@ui5/logger";
32
- const log = logger.getLogger("lbt:analyzer:SmartTemplateAnalyzer");
31
+ import {getLogger} from "@ui5/logger";
32
+ const log = getLogger("lbt:analyzer:SmartTemplateAnalyzer");
33
33
 
34
34
  // ---------------------------------------------------------------------------------------------------------
35
35
 
@@ -3,8 +3,8 @@ import {Syntax} from "../utils/parseUtils.js";
3
3
  import SapUiDefine from "../calls/SapUiDefine.js";
4
4
  import {getValue, isMethodCall, getStringValue} from "../utils/ASTUtils.js";
5
5
  import {fromUI5LegacyName} from "../utils/ModuleName.js";
6
- import logger from "@ui5/logger";
7
- const log = logger.getLogger("lbt:analyzer:XMLCompositeAnalyzer");
6
+ import {getLogger} from "@ui5/logger";
7
+ const log = getLogger("lbt:analyzer:XMLCompositeAnalyzer");
8
8
 
9
9
  const CALL_DEFINE = ["define"];
10
10
  const CALL_SAP_UI_DEFINE = ["sap", "ui", "define"];
@@ -2,8 +2,8 @@
2
2
  import xml2js from "xml2js";
3
3
  import {fromUI5LegacyName, fromRequireJSName} from "../utils/ModuleName.js";
4
4
  import JSTokenizer from "../utils/JSTokenizer.js";
5
- import logger from "@ui5/logger";
6
- const log = logger.getLogger("lbt:analyzer:XMLTemplateAnalyzer");
5
+ import {getLogger} from "@ui5/logger";
6
+ const log = getLogger("lbt:analyzer:XMLTemplateAnalyzer");
7
7
 
8
8
  // ---------------------------------------------------------------------------------------------------------
9
9
 
@@ -1,8 +1,8 @@
1
1
 
2
2
  import {parseJS, Syntax, VisitorKeys} from "../utils/parseUtils.js";
3
3
  import {getPropertyKey, isMethodCall, isIdentifier, getStringArray} from "../utils/ASTUtils.js";
4
- import logger from "@ui5/logger";
5
- const log = logger.getLogger("lbt:analyzer:LibraryJS");
4
+ import {getLogger} from "@ui5/logger";
5
+ const log = getLogger("lbt:analyzer:LibraryJS");
6
6
 
7
7
  const CALL__SAP_UI_GETCORE = ["sap", "ui", "getCore"];
8
8
 
@@ -3,8 +3,8 @@ import {pd} from "pretty-data";
3
3
  import {toRequireJSName} from "../utils/ModuleName.js";
4
4
  import {SectionType} from "./BundleDefinition.js";
5
5
  import escapePropertiesFile from "../utils/escapePropertiesFile.js";
6
- import logger from "@ui5/logger";
7
- const log = logger.getLogger("lbt:bundle:AutoSplitter");
6
+ import {getLogger} from "@ui5/logger";
7
+ const log = getLogger("lbt:bundle:AutoSplitter");
8
8
 
9
9
  const xmlHtmlPrePattern = /<(?:\w+:)?pre\b/;
10
10
 
@@ -15,8 +15,8 @@ import BundleResolver from "./Resolver.js";
15
15
  import BundleSplitter from "./AutoSplitter.js";
16
16
  import {SectionType} from "./BundleDefinition.js";
17
17
  import BundleWriter from "./BundleWriter.js";
18
- import logger from "@ui5/logger";
19
- const log = logger.getLogger("lbt:bundle:Builder");
18
+ import {getLogger} from "@ui5/logger";
19
+ const log = getLogger("lbt:bundle:Builder");
20
20
 
21
21
  const sourceMappingUrlPattern = /\/\/# sourceMappingURL=(.+)\s*$/;
22
22
  const httpPattern = /^https?:\/\//i;
@@ -7,8 +7,8 @@ import {getRendererName} from "../UI5ClientConstants.js";
7
7
  import ResourceFilterList from "../resources/ResourceFilterList.js";
8
8
  import {SectionType} from "./BundleDefinition.js";
9
9
  import ResolvedBundleDefinition from "./ResolvedBundleDefinition.js";
10
- import logger from "@ui5/logger";
11
- const log = logger.getLogger("lbt:bundle:Resolver");
10
+ import {getLogger} from "@ui5/logger";
11
+ const log = getLogger("lbt:bundle:Resolver");
12
12
 
13
13
  let dependencyTracker;
14
14
 
@@ -1,5 +1,5 @@
1
- import logger from "@ui5/logger";
2
- const log = logger.getLogger("lbt:graph:dependencyGraph");
1
+ import {getLogger} from "@ui5/logger";
2
+ const log = getLogger("lbt:graph:dependencyGraph");
3
3
 
4
4
  class Node {
5
5
  constructor(name) {
@@ -1,5 +1,5 @@
1
- import logger from "@ui5/logger";
2
- const log = logger.getLogger("lbt:graph:dominatorTree");
1
+ import {getLogger} from "@ui5/logger";
2
+ const log = getLogger("lbt:graph:dominatorTree");
3
3
 
4
4
  /**
5
5
  * Creates a dependency graph starting from the given set of root modules.
@@ -1,6 +1,6 @@
1
1
 
2
- import logger from "@ui5/logger";
3
- const log = logger.getLogger("lbt:graph:topologicalSort");
2
+ import {getLogger} from "@ui5/logger";
3
+ const log = getLogger("lbt:graph:topologicalSort");
4
4
 
5
5
  /**
6
6
  * Represents a module and its dependencies in a dependency graph.
@@ -3,8 +3,8 @@
3
3
  * It does not (yet) analyze dependencies of the library and therefore isn't part of the analyzer package (yet).
4
4
  */
5
5
  import xml2js from "xml2js";
6
- import logger from "@ui5/logger";
7
- const log = logger.getLogger("lbt:resources:LibraryFileAnalyzer");
6
+ import {getLogger} from "@ui5/logger";
7
+ const log = getLogger("lbt:resources:LibraryFileAnalyzer");
8
8
 
9
9
  const parser = new xml2js.Parser({
10
10
  // explicitChildren: true,
@@ -1,8 +1,8 @@
1
1
  import ResourceInfoList from "./ResourceInfoList.js";
2
2
  import ResourceFilterList from "./ResourceFilterList.js";
3
3
  import ResourceInfo from "./ResourceInfo.js";
4
- import logger from "@ui5/logger";
5
- const log = logger.getLogger("lbt:resources:ResourceCollector");
4
+ import {getLogger} from "@ui5/logger";
5
+ const log = getLogger("lbt:resources:ResourceCollector");
6
6
 
7
7
  const LOCALE = /^((?:[^/]+\/)*[^/]+?)_([A-Z]{2}(?:_[A-Z]{2}(?:_[A-Z0-9_]+)?)?)(\.properties|\.hdbtextbundle)$/i;
8
8
  const THEME = /^((?:[^/]+\/)*)themes\/([^/]+)\//;
@@ -1,6 +1,6 @@
1
1
 
2
- import logger from "@ui5/logger";
3
- const log = logger.getLogger("lbt:resources:ResourceFilterList");
2
+ import {getLogger} from "@ui5/logger";
3
+ const log = getLogger("lbt:resources:ResourceFilterList");
4
4
 
5
5
  const FILTER_PREFIXES = /^[-!+]/;
6
6
 
@@ -8,8 +8,8 @@ import XMLTemplateAnalyzer from "../analyzer/XMLTemplateAnalyzer.js";
8
8
  import {getDependencyInfos} from "./LibraryFileAnalyzer.js";
9
9
  import ModuleInfo from "./ModuleInfo.js";
10
10
  import ResourceFilterList from "./ResourceFilterList.js";
11
- import logger from "@ui5/logger";
12
- const log = logger.getLogger("lbt:resources:ResourcePool");
11
+ import {getLogger} from "@ui5/logger";
12
+ const log = getLogger("lbt:resources:ResourcePool");
13
13
  /*
14
14
  import Resource from "./Resource";
15
15
  */
@@ -1,5 +1,5 @@
1
- import logger from "@ui5/logger";
2
- const log = logger.getLogger("builder:processors:bootstrapHtmlTransformer");
1
+ import {getLogger} from "@ui5/logger";
2
+ const log = getLogger("builder:processors:bootstrapHtmlTransformer");
3
3
  import cheerio from "cheerio";
4
4
 
5
5
  /**
@@ -1,5 +1,5 @@
1
- import logger from "@ui5/logger";
2
- const log = logger.getLogger("builder:processors:bundlers:flexChangesBundler");
1
+ import {getLogger} from "@ui5/logger";
2
+ const log = getLogger("builder:processors:bundlers:flexChangesBundler");
3
3
  import {createResource} from "@ui5/fs/resourceFactory";
4
4
 
5
5
  /**
@@ -1,8 +1,8 @@
1
1
  import BundleBuilder from "../../lbt/bundle/Builder.js";
2
2
  import LocatorResourcePool from "../../lbt/resources/LocatorResourcePool.js";
3
3
  import EvoResource from "@ui5/fs/Resource";
4
- import logger from "@ui5/logger";
5
- const log = logger.getLogger("builder:processors:bundlers:moduleBundler");
4
+ import {getLogger} from "@ui5/logger";
5
+ const log = getLogger("builder:processors:bundlers:moduleBundler");
6
6
 
7
7
  /**
8
8
  * @public
@@ -1,7 +1,7 @@
1
1
  /*
2
2
  * Node script to create cross-library API index files for use in the UI5 SDKs.
3
3
  *
4
- * (c) Copyright 2009-2022 SAP SE or an SAP affiliate company.
4
+ * (c) Copyright 2009-2023 SAP SE or an SAP affiliate company.
5
5
  * Licensed under the Apache License, Version 2.0 - see LICENSE.txt.
6
6
  */
7
7
 
@@ -1,7 +1,7 @@
1
1
  /*
2
2
  * Node script to preprocess api.json files for use in the UI5 SDKs.
3
3
  *
4
- * (c) Copyright 2009-2022 SAP SE or an SAP affiliate company.
4
+ * (c) Copyright 2009-2023 SAP SE or an SAP affiliate company.
5
5
  * Licensed under the Apache License, Version 2.0 - see LICENSE.txt.
6
6
  */
7
7
 
@@ -1,7 +1,7 @@
1
1
  /*
2
2
  * JSDoc3 plugin for UI5 documentation generation.
3
3
  *
4
- * (c) Copyright 2009-2022 SAP SE or an SAP affiliate company.
4
+ * (c) Copyright 2009-2023 SAP SE or an SAP affiliate company.
5
5
  * Licensed under the Apache License, Version 2.0 - see LICENSE.txt.
6
6
  */
7
7
 
@@ -21,12 +21,18 @@
21
21
  * experimental
22
22
  *
23
23
  * final
24
+ *
25
+ * hideconstructor
24
26
  *
25
27
  * interface
26
28
  *
27
29
  * implements
28
30
  *
31
+ * ui5-omissible-param
29
32
  *
33
+ * ui5-restricted
34
+ *
35
+ *
30
36
  *
31
37
  * It furthermore listens to the following JSDoc3 events to implement additional functionality
32
38
  *
@@ -2594,6 +2600,13 @@ exports.defineTags = function(dictionary) {
2594
2600
  }
2595
2601
  }
2596
2602
  });
2603
+ dictionary.defineTag('ui5-omissible-params', {
2604
+ onTagged: function(doclet, tag) {
2605
+ if ( tag.value ) {
2606
+ ui5data(doclet).omissibleParams = tag.value.trim().split(/\s*,\s*/);
2607
+ }
2608
+ }
2609
+ });
2597
2610
 
2598
2611
  /**
2599
2612
  * Mark a doclet as synthetic.
@@ -3151,13 +3164,19 @@ exports.astNodeVisitor = {
3151
3164
  typeString += `(${paramTypes.join(", ")})`;
3152
3165
  }
3153
3166
  if (parsedType.result) {
3154
- typeString += `:${toTypeString(parsedType.result)}`;
3167
+ let resultType = toTypeString(parsedType.result);
3168
+ // ensure the function result remains belonging together even when a union of the entire function with other types is created
3169
+ // Example: ensure parentheses around function result in: function(int):({rows: int, columns: int}|null)|undefined
3170
+ if (parsedType.result.type === "TypeUnion") {
3171
+ resultType = `(${resultType})`;
3172
+ }
3173
+ typeString += `:${resultType}`;
3155
3174
  }
3156
3175
  types.push(typeString);
3157
3176
  // #### END: MODIFIED BY SAP
3158
3177
  break;
3159
3178
  case TYPES.NameExpression:
3160
- types.push(parsedType.name);
3179
+ types.push(parsedType.name);
3161
3180
  break;
3162
3181
  case TYPES.NullLiteral:
3163
3182
  types.push('null');
@@ -1,7 +1,7 @@
1
1
  /*
2
2
  * JSDoc3 template for UI5 documentation generation.
3
3
  *
4
- * (c) Copyright 2009-2022 SAP SE or an SAP affiliate company.
4
+ * (c) Copyright 2009-2023 SAP SE or an SAP affiliate company.
5
5
  * Licensed under the Apache License, Version 2.0 - see LICENSE.txt.
6
6
  */
7
7
 
@@ -2856,6 +2856,7 @@ function createAPIJSON4Symbol(symbol, omitDefaults) {
2856
2856
  }
2857
2857
  }
2858
2858
 
2859
+ const omissibleParams = new Set(member.__ui5 && member.__ui5.omissibleParams);
2859
2860
  if ( member.params && member.params.length > 0 ) {
2860
2861
  collection("parameters");
2861
2862
  for ( let j = 0; j < member.params.length; j++) {
@@ -2867,6 +2868,13 @@ function createAPIJSON4Symbol(symbol, omitDefaults) {
2867
2868
  attrib("name", param.name);
2868
2869
  attrib("type", listTypes(param.type));
2869
2870
  attrib("optional", !!param.optional, false, /* raw = */true);
2871
+ if ( omissibleParams.has(param.name) ) {
2872
+ if ( !param.optional ) {
2873
+ throw new Error(`@param ${param.name} is specified in '@ui5-omissible-params' for '${member.name}', but not marked as optional. Only optional params can be omissible.`);
2874
+ }
2875
+ attrib("omissible", true, false, /* raw = */true);
2876
+ omissibleParams.delete(param.name);
2877
+ }
2870
2878
  if ( param.variable ) {
2871
2879
  attrib("repeatable", !!param.variable, false, /* raw = */true);
2872
2880
  }
@@ -2882,6 +2890,9 @@ function createAPIJSON4Symbol(symbol, omitDefaults) {
2882
2890
  }
2883
2891
  endCollection("parameters");
2884
2892
  }
2893
+ if ( omissibleParams.size > 0 ) {
2894
+ throw new Error(`parameter(s) '${[...omissibleParams].join("' and '")}' specified as '@ui5-omissible-params' for '${member.name}' missing among the actual @params`);
2895
+ }
2885
2896
 
2886
2897
  exceptions(member);
2887
2898
 
@@ -1,5 +1,5 @@
1
- import logger from "@ui5/logger";
2
- const log = logger.getLogger("builder:processors:libraryLessGenerator");
1
+ import {getLogger} from "@ui5/logger";
2
+ const log = getLogger("builder:processors:libraryLessGenerator");
3
3
 
4
4
  import {promisify} from "node:util";
5
5
  import posixPath from "node:path/posix";
@@ -2,8 +2,8 @@
2
2
  import posixPath from "node:path/posix";
3
3
  import semver from "semver";
4
4
  const {SemVer: Version} = semver;
5
- import logger from "@ui5/logger";
6
- const log = logger.getLogger("builder:processors:manifestCreator");
5
+ import {getLogger} from "@ui5/logger";
6
+ const log = getLogger("builder:processors:manifestCreator");
7
7
  import Resource from "@ui5/fs/Resource";
8
8
  import xml2js from "xml2js";
9
9
  import analyzeLibraryJS from "../lbt/analyzer/analyzeLibraryJS.js";
@@ -1,21 +1,43 @@
1
+ import {fileURLToPath} from "node:url";
1
2
  import posixPath from "node:path/posix";
2
- import {minify} from "terser";
3
+ import os from "node:os";
4
+ import workerpool from "workerpool";
3
5
  import Resource from "@ui5/fs/Resource";
6
+ import {getLogger} from "@ui5/logger";
7
+ const log = getLogger("builder:processors:minifier");
4
8
 
5
- /**
6
- * Preserve comments which contain:
7
- * <ul>
8
- * <li>copyright notice</li>
9
- * <li>license terms</li>
10
- * <li>"@ui5-bundle"</li>
11
- * <li>"@ui5-bundle-raw-include"</li>
12
- * </ul>
13
- *
14
- * @type {RegExp}
15
- */
16
- const copyrightCommentsAndBundleCommentPattern = /copyright|\(c\)(?:[0-9]+|\s+[0-9A-Za-z])|released under|license|\u00a9|^@ui5-bundle-raw-include |^@ui5-bundle /i;
17
9
  const debugFileRegex = /((?:\.view|\.fragment|\.controller|\.designtime|\.support)?\.js)$/;
18
10
 
11
+ const MIN_WORKERS = 2;
12
+ const MAX_WORKERS = 4;
13
+ const osCpus = os.cpus().length || 1;
14
+ const maxWorkers = Math.max(Math.min(osCpus - 1, MAX_WORKERS), MIN_WORKERS);
15
+
16
+ // Shared workerpool across all executions until the taskUtil cleanup is triggered
17
+ let pool;
18
+
19
+ function getPool(taskUtil) {
20
+ if (!pool) {
21
+ log.verbose(`Creating workerpool with up to ${maxWorkers} workers (available CPU cores: ${osCpus})`);
22
+ const workerPath = fileURLToPath(new URL("./minifierWorker.js", import.meta.url));
23
+ pool = workerpool.pool(workerPath, {
24
+ workerType: "auto",
25
+ maxWorkers
26
+ });
27
+ taskUtil.registerCleanupTask(() => {
28
+ log.verbose(`Terminating workerpool`);
29
+ const poolToBeTerminated = pool;
30
+ pool = null;
31
+ poolToBeTerminated.terminate();
32
+ });
33
+ }
34
+ return pool;
35
+ }
36
+
37
+ async function minifyInWorker(options, taskUtil) {
38
+ return getPool(taskUtil).exec("execMinification", [options]);
39
+ }
40
+
19
41
  /**
20
42
  * @public
21
43
  * @module @ui5/builder/processors/minifier
@@ -40,13 +62,29 @@ const debugFileRegex = /((?:\.view|\.fragment|\.controller|\.designtime|\.suppor
40
62
  *
41
63
  * @param {object} parameters Parameters
42
64
  * @param {@ui5/fs/Resource[]} parameters.resources List of resources to be processed
65
+ * @param {@ui5/builder/tasks/TaskUtil|object} [parameters.taskUtil] TaskUtil instance.
66
+ * Required when using the <code>useWorkers</code> option
43
67
  * @param {object} [parameters.options] Options
44
68
  * @param {boolean} [parameters.options.addSourceMappingUrl=true]
45
- * Whether to add a sourceMappingURL reference to the end of the minified resource
69
+ * Whether to add a sourceMappingURL reference to the end of the minified resource
70
+ * @param {boolean} [parameters.options.useWorkers=false]
71
+ * Whether to offload the minification task onto separate CPU threads. This often speeds up the build process
46
72
  * @returns {Promise<module:@ui5/builder/processors/minifier~MinifierResult[]>}
47
- * Promise resolving with object of resource, dbgResource and sourceMap
73
+ * Promise resolving with object of resource, dbgResource and sourceMap
48
74
  */
49
- export default async function({resources, options: {addSourceMappingUrl = true} = {}}) {
75
+ export default async function({resources, taskUtil, options: {addSourceMappingUrl = true, useWorkers = false} = {}}) {
76
+ let minify;
77
+ if (useWorkers) {
78
+ if (!taskUtil) {
79
+ // TaskUtil is required for worker support
80
+ throw new Error(`Minifier: Option 'useWorkers' requires a taskUtil instance to be provided`);
81
+ }
82
+ minify = minifyInWorker;
83
+ } else {
84
+ // Do not use workerpool
85
+ minify = (await import("./minifierWorker.js")).default;
86
+ }
87
+
50
88
  return Promise.all(resources.map(async (resource) => {
51
89
  const dbgPath = resource.getPath().replace(debugFileRegex, "-dbg$1");
52
90
  const dbgResource = await resource.clone();
@@ -54,43 +92,26 @@ export default async function({resources, options: {addSourceMappingUrl = true}
54
92
 
55
93
  const filename = posixPath.basename(resource.getPath());
56
94
  const code = await resource.getString();
57
- try {
58
- const sourceMapOptions = {
59
- filename
60
- };
61
- if (addSourceMappingUrl) {
62
- sourceMapOptions.url = filename + ".map";
63
- }
64
- const dbgFilename = posixPath.basename(dbgPath);
65
- const result = await minify({
66
- // Use debug-name since this will be referenced in the source map "sources"
67
- [dbgFilename]: code
68
- }, {
69
- output: {
70
- comments: copyrightCommentsAndBundleCommentPattern,
71
- wrap_func_args: false
72
- },
73
- compress: false,
74
- mangle: {
75
- reserved: [
76
- "jQuery",
77
- "jquery",
78
- "sap",
79
- ]
80
- },
81
- sourceMap: sourceMapOptions
82
- });
83
- resource.setString(result.code);
84
- const sourceMapResource = new Resource({
85
- path: resource.getPath() + ".map",
86
- string: result.map
87
- });
88
- return {resource, dbgResource, sourceMapResource};
89
- } catch (err) {
90
- // Note: err.filename contains the debug-name
91
- throw new Error(
92
- `Minification failed with error: ${err.message} in file ${filename} ` +
93
- `(line ${err.line}, col ${err.col}, pos ${err.pos})`);
95
+
96
+ const sourceMapOptions = {
97
+ filename
98
+ };
99
+ if (addSourceMappingUrl) {
100
+ sourceMapOptions.url = filename + ".map";
94
101
  }
102
+ const dbgFilename = posixPath.basename(dbgPath);
103
+
104
+ const result = await minify({
105
+ filename,
106
+ dbgFilename,
107
+ code,
108
+ sourceMapOptions
109
+ }, taskUtil);
110
+ resource.setString(result.code);
111
+ const sourceMapResource = new Resource({
112
+ path: resource.getPath() + ".map",
113
+ string: result.map
114
+ });
115
+ return {resource, dbgResource, sourceMapResource};
95
116
  }));
96
117
  }
@@ -0,0 +1,77 @@
1
+ import workerpool from "workerpool";
2
+ import {minify} from "terser";
3
+
4
+ /**
5
+ * @private
6
+ * @module @ui5/builder/tasks/minifyWorker
7
+ */
8
+
9
+ /**
10
+ * Preserve comments which contain:
11
+ * <ul>
12
+ * <li>copyright notice</li>
13
+ * <li>license terms</li>
14
+ * <li>"@ui5-bundle"</li>
15
+ * <li>"@ui5-bundle-raw-include"</li>
16
+ * </ul>
17
+ *
18
+ * @type {RegExp}
19
+ */
20
+ const copyrightCommentsAndBundleCommentPattern = /copyright|\(c\)(?:[0-9]+|\s+[0-9A-Za-z])|released under|license|\u00a9|^@ui5-bundle-raw-include |^@ui5-bundle /i;
21
+
22
+ /**
23
+ * Task to minify resources.
24
+ *
25
+ * @private
26
+ * @function default
27
+ * @static
28
+ *
29
+ * @param {object} parameters Parameters
30
+ * @param {string} parameters.filename
31
+ * @param {string} parameters.dbgFilename
32
+ * @param {string} parameters.code
33
+ * @param {object} parameters.sourceMapOptions
34
+ * @returns {Promise<undefined>} Promise resolving once minification of the resource has finished
35
+ */
36
+ export default async function execMinification({
37
+ filename,
38
+ dbgFilename,
39
+ code,
40
+ sourceMapOptions
41
+ }) {
42
+ try {
43
+ return await minify({
44
+ // Use debug-name since this will be referenced in the source map "sources"
45
+ [dbgFilename]: code
46
+ }, {
47
+ output: {
48
+ comments: copyrightCommentsAndBundleCommentPattern,
49
+ wrap_func_args: false
50
+ },
51
+ compress: false,
52
+ mangle: {
53
+ reserved: [
54
+ "jQuery",
55
+ "jquery",
56
+ "sap",
57
+ ]
58
+ },
59
+ sourceMap: sourceMapOptions
60
+ });
61
+ } catch (err) {
62
+ // Note: err.filename contains the debug-name
63
+ throw new Error(
64
+ `Minification failed with error: ${err.message} in file ${filename} ` +
65
+ `(line ${err.line}, col ${err.col}, pos ${err.pos})`);
66
+ }
67
+ }
68
+
69
+ // Test execution via ava is never done on the main thread
70
+ /* istanbul ignore else */
71
+ if (!workerpool.isMainThread) {
72
+ // Script got loaded through workerpool
73
+ // => Create a worker and register public functions
74
+ workerpool.worker({
75
+ execMinification
76
+ });
77
+ }
@@ -1,6 +1,6 @@
1
1
 
2
- import logger from "@ui5/logger";
3
- const log = logger.getLogger("builder:processors:resourceListCreator");
2
+ import {getLogger} from "@ui5/logger";
3
+ const log = getLogger("builder:processors:resourceListCreator");
4
4
  import ResourceCollector from "../lbt/resources/ResourceCollector.js";
5
5
  import LocatorResourcePool from "../lbt/resources/LocatorResourcePool.js";
6
6
  import ResourceInfo from "../lbt/resources/ResourceInfo.js";
@@ -1,5 +1,5 @@
1
- import logger from "@ui5/logger";
2
- const log = logger.getLogger("builder:processors:themeBuilder");
1
+ import {getLogger} from "@ui5/logger";
2
+ const log = getLogger("builder:processors:themeBuilder");
3
3
  import posixPath from "node:path/posix";
4
4
  import less from "less-openui5";
5
5
  import Resource from "@ui5/fs/Resource";
@@ -1,5 +1,5 @@
1
- import logger from "@ui5/logger";
2
- const log = logger.getLogger("builder:processors:versionInfoGenerator");
1
+ import {getLogger} from "@ui5/logger";
2
+ const log = getLogger("builder:processors:versionInfoGenerator");
3
3
  import {createResource} from "@ui5/fs/resourceFactory";
4
4
  import posixPath from "node:path/posix";
5
5
 
@@ -2,8 +2,8 @@ import path from "node:path";
2
2
  import themeBuilder from "../processors/themeBuilder.js";
3
3
  import fsInterface from "@ui5/fs/fsInterface";
4
4
  import ReaderCollectionPrioritized from "@ui5/fs/ReaderCollectionPrioritized";
5
- import logger from "@ui5/logger";
6
- const log = logger.getLogger("builder:tasks:buildThemes");
5
+ import {getLogger} from "@ui5/logger";
6
+ const log = getLogger("builder:tasks:buildThemes");
7
7
 
8
8
  /**
9
9
  * @public
@@ -1,7 +1,7 @@
1
1
  import path from "node:path";
2
2
  import moduleBundler from "../../processors/bundlers/moduleBundler.js";
3
- import logger from "@ui5/logger";
4
- const log = logger.getLogger("builder:tasks:bundlers:generateComponentPreload");
3
+ import {getLogger} from "@ui5/logger";
4
+ const log = getLogger("builder:tasks:bundlers:generateComponentPreload");
5
5
  import {negateFilters} from "../../lbt/resources/ResourceFilterList.js";
6
6
 
7
7
  /**
@@ -1,5 +1,5 @@
1
- import logger from "@ui5/logger";
2
- const log = logger.getLogger("builder:tasks:bundlers:generateFlexChangesBundle");
1
+ import {getLogger} from "@ui5/logger";
2
+ const log = getLogger("builder:tasks:bundlers:generateFlexChangesBundle");
3
3
  import flexChangesBundler from "../../processors/bundlers/flexChangesBundler.js";
4
4
  import semver from "semver";
5
5
 
@@ -1,5 +1,5 @@
1
- import logger from "@ui5/logger";
2
- const log = logger.getLogger("builder:tasks:bundlers:generateLibraryPreload");
1
+ import {getLogger} from "@ui5/logger";
2
+ const log = getLogger("builder:tasks:bundlers:generateLibraryPreload");
3
3
  import moduleBundler from "../../processors/bundlers/moduleBundler.js";
4
4
  import {negateFilters} from "../../lbt/resources/ResourceFilterList.js";
5
5
  import createModuleNameMapping from "./utils/createModuleNameMapping.js";
@@ -1,5 +1,5 @@
1
- import logger from "@ui5/logger";
2
- const log = logger.getLogger("builder:tasks:bundlers:generateStandaloneAppBundle");
1
+ import {getLogger} from "@ui5/logger";
2
+ const log = getLogger("builder:tasks:bundlers:generateStandaloneAppBundle");
3
3
  import ReaderCollectionPrioritized from "@ui5/fs/ReaderCollectionPrioritized";
4
4
  import moduleBundler from "../../processors/bundlers/moduleBundler.js";
5
5
  import createModuleNameMapping from "./utils/createModuleNameMapping.js";
@@ -1,7 +1,7 @@
1
1
  import crypto from "node:crypto";
2
2
  import {createResource} from "@ui5/fs/resourceFactory";
3
- import logger from "@ui5/logger";
4
- const log = logger.getLogger("builder:tasks:generateCachebusterInfo");
3
+ import {getLogger} from "@ui5/logger";
4
+ const log = getLogger("builder:tasks:generateCachebusterInfo");
5
5
 
6
6
  /**
7
7
  * @public
@@ -1,6 +1,6 @@
1
1
 
2
- import logger from "@ui5/logger";
3
- const log = logger.getLogger("builder:tasks:generateLibraryManifest");
2
+ import {getLogger} from "@ui5/logger";
3
+ const log = getLogger("builder:tasks:generateLibraryManifest");
4
4
  import manifestCreator from "../processors/manifestCreator.js";
5
5
 
6
6
  /**
@@ -1,6 +1,6 @@
1
1
  import posixPath from "node:path/posix";
2
- import logger from "@ui5/logger";
3
- const log = logger.getLogger("builder:tasks:generateThemeDesignerResources");
2
+ import {getLogger} from "@ui5/logger";
3
+ const log = getLogger("builder:tasks:generateThemeDesignerResources");
4
4
  import libraryLessGenerator from "../processors/libraryLessGenerator.js";
5
5
  import ReaderCollectionPrioritized from "@ui5/fs/ReaderCollectionPrioritized";
6
6
  import Resource from "@ui5/fs/Resource";
@@ -1,5 +1,5 @@
1
- import logger from "@ui5/logger";
2
- const log = logger.getLogger("builder:tasks:jsdoc:executeJsdocSdkTransformation");
1
+ import {getLogger} from "@ui5/logger";
2
+ const log = getLogger("builder:tasks:jsdoc:executeJsdocSdkTransformation");
3
3
  import ReaderCollectionPrioritized from "@ui5/fs/ReaderCollectionPrioritized";
4
4
  import fsInterface from "@ui5/fs/fsInterface";
5
5
  import sdkTransformer from "../../processors/jsdoc/sdkTransformer.js";
@@ -1,5 +1,5 @@
1
- import logger from "@ui5/logger";
2
- const log = logger.getLogger("builder:tasks:jsdoc:generateJsdoc");
1
+ import {getLogger} from "@ui5/logger";
2
+ const log = getLogger("builder:tasks:jsdoc:generateJsdoc");
3
3
  import path from "node:path";
4
4
  import os from "node:os";
5
5
  import fs from "graceful-fs";
@@ -25,8 +25,10 @@ export default async function({workspace, taskUtil, options: {pattern, omitSourc
25
25
  const resources = await workspace.byGlob(pattern);
26
26
  const processedResources = await minifier({
27
27
  resources,
28
+ taskUtil,
28
29
  options: {
29
- addSourceMappingUrl: !omitSourceMapResources
30
+ addSourceMappingUrl: !omitSourceMapResources,
31
+ useWorkers: !!taskUtil,
30
32
  }
31
33
  });
32
34
 
@@ -1,5 +1,5 @@
1
- import logger from "@ui5/logger";
2
- const log = logger.getLogger("builder:tasks:transformBootstrapHtml");
1
+ import {getLogger} from "@ui5/logger";
2
+ const log = getLogger("builder:tasks:transformBootstrapHtml");
3
3
  import bootstrapHtmlTransformer from "../processors/bootstrapHtmlTransformer.js";
4
4
 
5
5
  /* eslint "jsdoc/check-param-names": ["error", {"disableExtraPropertyReporting":true}] */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ui5/builder",
3
- "version": "3.0.0-rc.2",
3
+ "version": "3.0.0-rc.4",
4
4
  "description": "UI5 Tooling - Builder",
5
5
  "author": {
6
6
  "name": "SAP SE",
@@ -28,7 +28,7 @@
28
28
  "./internal/jsdoc/template/publish": "./lib/processors/jsdoc/lib/ui5/template/publish.cjs"
29
29
  },
30
30
  "engines": {
31
- "node": "^16.18.0 || >=18.0.0",
31
+ "node": "^16.18.0 || >=18.12.0",
32
32
  "npm": ">= 8"
33
33
  },
34
34
  "scripts": {
@@ -118,8 +118,8 @@
118
118
  },
119
119
  "dependencies": {
120
120
  "@jridgewell/sourcemap-codec": "^1.4.14",
121
- "@ui5/fs": "^3.0.0-rc.3",
122
- "@ui5/logger": "^3.0.1-rc.1",
121
+ "@ui5/fs": "^3.0.0-rc.5",
122
+ "@ui5/logger": "^3.0.1-rc.3",
123
123
  "cheerio": "1.0.0-rc.12",
124
124
  "escape-unicode": "^0.2.0",
125
125
  "escope": "^4.0.0",
@@ -128,14 +128,15 @@
128
128
  "jsdoc": "^3.6.11",
129
129
  "less-openui5": "^0.11.6",
130
130
  "pretty-data": "^0.40.0",
131
- "rimraf": "^4.1.1",
131
+ "rimraf": "^4.1.2",
132
132
  "semver": "^7.3.8",
133
133
  "terser": "^5.16.1",
134
+ "workerpool": "^6.3.1",
134
135
  "xml2js": "^0.4.23"
135
136
  },
136
137
  "devDependencies": {
137
138
  "@istanbuljs/esm-loader-hook": "^0.2.0",
138
- "@ui5/project": "^3.0.0-rc.3",
139
+ "@ui5/project": "^3.0.0-rc.7",
139
140
  "ava": "^5.1.1",
140
141
  "chai": "^4.3.7",
141
142
  "chai-fs": "^2.0.0",
@@ -143,10 +144,10 @@
143
144
  "cross-env": "^7.0.3",
144
145
  "depcheck": "^1.4.3",
145
146
  "docdash": "^2.0.1",
146
- "eslint": "^8.32.0",
147
+ "eslint": "^8.33.0",
147
148
  "eslint-config-google": "^0.14.0",
148
149
  "eslint-plugin-ava": "^14.0.0",
149
- "eslint-plugin-jsdoc": "^39.6.7",
150
+ "eslint-plugin-jsdoc": "^39.7.4",
150
151
  "esmock": "^2.1.0",
151
152
  "nyc": "^15.1.0",
152
153
  "open-cli": "^7.1.0",