@ui5/builder 3.0.6 → 3.0.7

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,7 +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/v3.0.6...HEAD).
5
+ A list of unreleased changes can be found [here](https://github.com/SAP/ui5-builder/compare/v3.0.7...HEAD).
6
+
7
+ <a name="v3.0.7"></a>
8
+ ## [v3.0.7] - 2023-07-12
9
+ ### Bug Fixes
10
+ - Don't report a missing module that's contained in another bundle ([#915](https://github.com/SAP/ui5-builder/issues/915)) [`8f23f38`](https://github.com/SAP/ui5-builder/commit/8f23f388f6d64f313ae8a89d0fcaf39ba905a70b)
11
+
6
12
 
7
13
  <a name="v3.0.6"></a>
8
14
  ## [v3.0.6] - 2023-06-21
@@ -803,6 +809,7 @@ to load the custom bundle file instead.
803
809
 
804
810
  ### Features
805
811
  - Add ability to configure component preloads and custom bundles [`2241e5f`](https://github.com/SAP/ui5-builder/commit/2241e5ff98fd95f1f80cc74959655ae7a9c660e7)
812
+ [v3.0.7]: https://github.com/SAP/ui5-builder/compare/v3.0.6...v3.0.7
806
813
  [v3.0.6]: https://github.com/SAP/ui5-builder/compare/v3.0.5...v3.0.6
807
814
  [v3.0.5]: https://github.com/SAP/ui5-builder/compare/v3.0.4...v3.0.5
808
815
  [v3.0.4]: https://github.com/SAP/ui5-builder/compare/v3.0.3...v3.0.4
@@ -3,7 +3,6 @@ import escope from "escope";
3
3
  import {fromUI5LegacyName, fromRequireJSName, resolveRelativeRequireJSName} from "../utils/ModuleName.js";
4
4
  import moduleInfo from "../resources/ModuleInfo.js";
5
5
  const ModuleFormat = moduleInfo.Format;
6
- import {MODULE__JQUERY_SAP_GLOBAL, MODULE__UI5LOADER_AUTOCONFIG} from "../UI5ClientConstants.js";
7
6
  import {
8
7
  findOwnProperty,
9
8
  getLocation,
@@ -335,17 +334,6 @@ class JSModuleAnalyzer {
335
334
  }
336
335
  }
337
336
 
338
- // depending on the used module APIs, add an implicit dependency to the loader entry module
339
- if ( info.format === ModuleFormat.UI5_LEGACY ) {
340
- info.addImplicitDependency(MODULE__JQUERY_SAP_GLOBAL);
341
- } else if ( info.format === ModuleFormat.UI5_DEFINE ) {
342
- // Note: the implicit dependency for sap.ui.define modules points to the standard UI5
343
- // loader config module. A more general approach would be to add a dependency to the loader
344
- // only, but then standard configuration would be missed by dependency resolution
345
- // (to be clarified)
346
- info.addImplicitDependency(MODULE__UI5LOADER_AUTOCONFIG);
347
- }
348
-
349
337
  if ( !bIsUi5Module ) {
350
338
  // when there are no indicators for module APIs, mark the module as 'raw' module
351
339
  info.rawModule = true;
@@ -178,8 +178,6 @@ class XMLTemplateAnalyzer {
178
178
  // console.log(result);
179
179
  // clear();
180
180
  if ( isFragment ) {
181
- // all fragments implicitly depend on the fragment class
182
- this.info.addImplicitDependency(FRAGMENT_MODULE);
183
181
  this._analyzeNode(result);
184
182
  } else {
185
183
  // views require a special handling of the root node
@@ -196,8 +194,6 @@ class XMLTemplateAnalyzer {
196
194
  }
197
195
 
198
196
  _analyzeViewRootNode(node) {
199
- this.info.addImplicitDependency(XMLVIEW_MODULE);
200
-
201
197
  const controllerName = getAttribute(node, XMLVIEW_CONTROLLERNAME_ATTRIBUTE);
202
198
  if ( controllerName ) {
203
199
  this._addDependency( fromUI5LegacyName(controllerName, ".controller.js"), this.conditional );
@@ -51,6 +51,16 @@ class BundleResolver {
51
51
  let selectedResources = Object.create(null);
52
52
  let selectedResourcesSequence = [];
53
53
  const pool = this.pool;
54
+ /**
55
+ * Names of modules that are required in some way but could not be found
56
+ * in the resource pool.
57
+ */
58
+ const missingModules = Object.create(null);
59
+ /**
60
+ * Names of modules that are included in non-decomposable bundles.
61
+ * If they occur in the missingModules, then this is not an error.
62
+ */
63
+ const includedModules = new Set();
54
64
 
55
65
  /**
56
66
  * @param {JSModuleSectionDefinition} section
@@ -71,11 +81,16 @@ class BundleResolver {
71
81
  }
72
82
 
73
83
  function checkForDecomposableBundle(resource) {
74
- if ( resource == null ||
75
- resource.info == null ||
76
- resource.info.subModules.length === 0 ||
77
- /(?:^|\/)library.js$/.test(resource.info.name) ) {
78
- return {resource, decomposable: false};
84
+ const isBundle =
85
+ resource?.info?.subModules.length > 0 &&
86
+ !/(?:^|\/)library.js$/.test(resource.info.name);
87
+
88
+ if (!isBundle) {
89
+ return {
90
+ resource,
91
+ isBundle,
92
+ decomposable: false
93
+ };
79
94
  }
80
95
 
81
96
  return Promise.all(
@@ -83,7 +98,11 @@ class BundleResolver {
83
98
  ).then((modules) => {
84
99
  // it might look more natural to expect 'all' embedded modules to exist in the pool,
85
100
  // but expecting only 'some' module to exist is a more conservative approach
86
- return ({resource, decomposable: modules.some(($) => ($))});
101
+ return {
102
+ resource,
103
+ isBundle,
104
+ decomposable: modules.some(($) => ($))
105
+ };
87
106
  });
88
107
  }
89
108
 
@@ -105,20 +124,29 @@ class BundleResolver {
105
124
  .catch( (err) => {
106
125
  // if the caller provided an error message, log it
107
126
  if ( msg ) {
108
- log.error(msg);
127
+ missingModules[resourceName] ??= [];
128
+ missingModules[resourceName].push(msg);
109
129
  }
110
130
  // return undefined
111
131
  })
112
132
  .then( (resource) => checkForDecomposableBundle(resource) )
113
- .then( ({resource, decomposable}) => {
133
+ .then( ({resource, isBundle, decomposable}) => {
114
134
  const dependencyInfo = resource && resource.info;
115
135
  let promises = [];
116
136
 
137
+ if ( isBundle && !decomposable ) {
138
+ resource.info.subModules.forEach(
139
+ (included) => {
140
+ includedModules.add(included);
141
+ }
142
+ );
143
+ }
144
+
117
145
  if ( decomposable ) {
118
146
  // bundles are not added, only their embedded modules
119
147
  promises = dependencyInfo.subModules.map( (included) => {
120
148
  return checkAndAddResource(included, depth + 1,
121
- "**** error: missing submodule " + included + ", included by " + resourceName);
149
+ `**** error: missing submodule ${included}, included by ${resourceName}`);
122
150
  });
123
151
  } else if ( resource != null ) {
124
152
  // trace.trace(" checking dependencies of " + resource.name );
@@ -136,8 +164,8 @@ class BundleResolver {
136
164
  return;
137
165
  }
138
166
 
139
- return checkAndAddResource( required, depth + 1,
140
- "**** error: missing module " + required + ", required by " + resourceName);
167
+ return checkAndAddResource(required, depth + 1,
168
+ `**** error: missing module ${required}, required by ${resourceName}`);
141
169
  });
142
170
  }
143
171
 
@@ -317,6 +345,17 @@ class BundleResolver {
317
345
  // NODE-TODO if ( PerfMeasurement.ACTIVE ) PerfMeasurement.stop(PerfKeys.RESOLVE_MODULE);
318
346
 
319
347
  return previous.then( function() {
348
+ // ignore missing modules that have been found in non-decomposable bundles
349
+ includedModules.forEach((included) => delete missingModules[included]);
350
+
351
+ // report the remaining missing modules
352
+ Object.keys(missingModules).sort().forEach((missing) => {
353
+ const messages = missingModules[missing];
354
+ messages.sort().forEach((msg) => {
355
+ log.error(msg);
356
+ });
357
+ });
358
+
320
359
  log.verbose(" Resolving bundle done");
321
360
 
322
361
  return resolved;
@@ -6,14 +6,6 @@
6
6
  */
7
7
  const STRICT = 0;
8
8
 
9
- /**
10
- * An implicit dependency is also strict, but has not been declared. E.g. each UI5 module depends on
11
- * jquery.sap.global.
12
- *
13
- * @private
14
- */
15
- const IMPLICIT = 1;
16
-
17
9
  /**
18
10
  * A conditional dependency has to be resolved only under certain conditions that typically are
19
11
  * checked at runtime.
@@ -112,7 +104,7 @@ class ModuleInfo {
112
104
  // included already as a submodule.
113
105
  // If the dependency was known already, update the kind
114
106
  // only when the new kind is stronger than the current one.
115
- // STRICT is stronger than IMPLICIT, IMPLICIT is stronger than CONDITIONAL
107
+ // STRICT is stronger than CONDITIONAL
116
108
  if ( dependency &&
117
109
  dependency !== this.name &&
118
110
  this.subModules.indexOf(dependency) < 0 &&
@@ -121,10 +113,6 @@ class ModuleInfo {
121
113
  }
122
114
  }
123
115
 
124
- addImplicitDependency(dependency) {
125
- this._addDependency(dependency, IMPLICIT);
126
- }
127
-
128
116
  addDependency(dependency, conditional) {
129
117
  this._addDependency(dependency, conditional ? CONDITIONAL : STRICT);
130
118
  }
@@ -175,10 +163,6 @@ class ModuleInfo {
175
163
  return this._dependencies[dependency] === CONDITIONAL;
176
164
  }
177
165
 
178
- isImplicitDependency(dependency) {
179
- return this._dependencies[dependency] === IMPLICIT;
180
- }
181
-
182
166
  get name() {
183
167
  return this._name;
184
168
  }
@@ -124,7 +124,7 @@ class ResourceCollector {
124
124
  moduleInfo.dependencies.forEach((dep) => {
125
125
  if ( moduleInfo.isConditionalDependency(dep) ) {
126
126
  resourceInfo.condRequired.add(dep);
127
- } else if ( !moduleInfo.isImplicitDependency(dep) ) {
127
+ } else {
128
128
  resourceInfo.required.add(dep);
129
129
  }
130
130
  });
@@ -158,7 +158,7 @@ class ResourceCollector {
158
158
  if (!resourceInfo.required.has(dep)) {
159
159
  resourceInfo.condRequired.add(dep);
160
160
  }
161
- } else if ( !subModuleInfo.isImplicitDependency(dep) ) {
161
+ } else {
162
162
  // Move module from condRequired to required
163
163
  if (resourceInfo.condRequired.has(dep)) {
164
164
  resourceInfo.condRequired.delete(dep);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ui5/builder",
3
- "version": "3.0.6",
3
+ "version": "3.0.7",
4
4
  "description": "UI5 Tooling - Builder",
5
5
  "author": {
6
6
  "name": "SAP SE",
@@ -38,7 +38,7 @@
38
38
  "unit": "rimraf test/tmp && ava",
39
39
  "unit-verbose": "rimraf test/tmp && cross-env UI5_LOG_LVL=verbose ava --verbose --serial",
40
40
  "unit-watch": "rimraf test/tmp && ava --watch",
41
- "unit-xunit": "rimraf test/tmp && ava --node-arguments=\"--experimental-loader=@istanbuljs/esm-loader-hook\" --tap --timeout=1m | tap-xunit --dontUseCommentsAsTestNames=true > test-results.xml",
41
+ "unit-xunit": "rimraf test/tmp && ava --no-worker-threads --node-arguments=\"--experimental-loader=@istanbuljs/esm-loader-hook\" --tap --timeout=1m | tap-xunit --dontUseCommentsAsTestNames=true > test-results.xml",
42
42
  "unit-inspect": "cross-env UI5_LOG_LVL=verbose ava debug --break",
43
43
  "coverage": "rimraf test/tmp && nyc ava --node-arguments=\"--experimental-loader=@istanbuljs/esm-loader-hook\"",
44
44
  "coverage-xunit": "nyc --reporter=text --reporter=text-summary --reporter=cobertura npm run unit-xunit",
@@ -123,20 +123,20 @@
123
123
  "cheerio": "1.0.0-rc.12",
124
124
  "escape-unicode": "^0.2.0",
125
125
  "escope": "^4.0.0",
126
- "espree": "^9.5.2",
126
+ "espree": "^9.6.0",
127
127
  "graceful-fs": "^4.2.11",
128
128
  "jsdoc": "^4.0.2",
129
129
  "less-openui5": "^0.11.6",
130
130
  "pretty-data": "^0.40.0",
131
131
  "rimraf": "^5.0.1",
132
- "semver": "^7.5.2",
133
- "terser": "^5.18.1",
132
+ "semver": "^7.5.4",
133
+ "terser": "^5.18.2",
134
134
  "workerpool": "^6.4.0",
135
135
  "xml2js": "^0.6.0"
136
136
  },
137
137
  "devDependencies": {
138
138
  "@istanbuljs/esm-loader-hook": "^0.2.0",
139
- "@ui5/project": "^3.3.2",
139
+ "@ui5/project": "^3.4.1",
140
140
  "ava": "^5.3.1",
141
141
  "chai": "^4.3.7",
142
142
  "chai-fs": "^2.0.0",
@@ -144,10 +144,10 @@
144
144
  "cross-env": "^7.0.3",
145
145
  "depcheck": "^1.4.3",
146
146
  "docdash": "^2.0.1",
147
- "eslint": "^8.43.0",
147
+ "eslint": "^8.44.0",
148
148
  "eslint-config-google": "^0.14.0",
149
149
  "eslint-plugin-ava": "^14.0.0",
150
- "eslint-plugin-jsdoc": "^46.2.6",
150
+ "eslint-plugin-jsdoc": "^46.4.3",
151
151
  "esmock": "^2.3.1",
152
152
  "nyc": "^15.1.0",
153
153
  "open-cli": "^7.2.0",