@ui5/builder 3.0.8 → 3.0.9
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 +6 -2
- package/lib/processors/themeBuilderWorker.js +278 -0
- package/lib/tasks/buildThemes.js +83 -14
- package/package.json +3 -3
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/v3.0.
|
|
5
|
+
A list of unreleased changes can be found [here](https://github.com/SAP/ui5-builder/compare/v3.0.9...HEAD).
|
|
6
|
+
|
|
7
|
+
<a name="v3.0.9"></a>
|
|
8
|
+
## [v3.0.9] - 2023-07-25
|
|
6
9
|
|
|
7
10
|
<a name="v3.0.8"></a>
|
|
8
|
-
## [v3.0.8] - 2023-07-
|
|
11
|
+
## [v3.0.8] - 2023-07-19
|
|
9
12
|
### Bug Fixes
|
|
10
13
|
- Revert "[INTERNAL] Remove implicit dependencies concept ([#913](https://github.com/SAP/ui5-builder/issues/913))" [`1043714`](https://github.com/SAP/ui5-builder/commit/1043714e3b952a8280f1ff7909f79db3b750eb0c)
|
|
11
14
|
- **generateJsdoc:** Also process resources created by preceeding tasks [`04447bd`](https://github.com/SAP/ui5-builder/commit/04447bdec28b8bf18c24bd53e3fe8be9bdeed6c2)
|
|
@@ -816,6 +819,7 @@ to load the custom bundle file instead.
|
|
|
816
819
|
|
|
817
820
|
### Features
|
|
818
821
|
- Add ability to configure component preloads and custom bundles [`2241e5f`](https://github.com/SAP/ui5-builder/commit/2241e5ff98fd95f1f80cc74959655ae7a9c660e7)
|
|
822
|
+
[v3.0.9]: https://github.com/SAP/ui5-builder/compare/v3.0.8...v3.0.9
|
|
819
823
|
[v3.0.8]: https://github.com/SAP/ui5-builder/compare/v3.0.7...v3.0.8
|
|
820
824
|
[v3.0.7]: https://github.com/SAP/ui5-builder/compare/v3.0.6...v3.0.7
|
|
821
825
|
[v3.0.6]: https://github.com/SAP/ui5-builder/compare/v3.0.5...v3.0.6
|
|
@@ -0,0 +1,278 @@
|
|
|
1
|
+
import workerpool from "workerpool";
|
|
2
|
+
import themeBuilder from "./themeBuilder.js";
|
|
3
|
+
import {createResource} from "@ui5/fs/resourceFactory";
|
|
4
|
+
import {Buffer} from "node:buffer";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Task to build library themes.
|
|
8
|
+
*
|
|
9
|
+
* @private
|
|
10
|
+
* @function default
|
|
11
|
+
* @static
|
|
12
|
+
*
|
|
13
|
+
* @param {object} parameters Parameters
|
|
14
|
+
* @param {MessagePort} parameters.fsInterfacePort
|
|
15
|
+
* @param {object[]} parameters.themeResources Input array of Uint8Array transferable objects
|
|
16
|
+
* that are the less sources to build upon. By nature those are @ui5/fs/Resource.
|
|
17
|
+
* @param {object} parameters.options Less compiler options
|
|
18
|
+
* @returns {Promise<object[]>} Resulting array of Uint8Array transferable objects
|
|
19
|
+
*/
|
|
20
|
+
export default async function execThemeBuild({
|
|
21
|
+
fsInterfacePort,
|
|
22
|
+
themeResources = [],
|
|
23
|
+
options = {}
|
|
24
|
+
}) {
|
|
25
|
+
const fsThemeResources = deserializeResources(themeResources);
|
|
26
|
+
const fsReader = new FsWorkerThreadInterface(fsInterfacePort);
|
|
27
|
+
|
|
28
|
+
const result = await themeBuilder({
|
|
29
|
+
resources: fsThemeResources,
|
|
30
|
+
fs: fsReader,
|
|
31
|
+
options
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
return serializeResources(result);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Casts @ui5/fs/Resource-s into an Uint8Array transferable object
|
|
39
|
+
*
|
|
40
|
+
* @param {@ui5/fs/Resource[]} resourceCollection
|
|
41
|
+
* @returns {Promise<object[]>}
|
|
42
|
+
*/
|
|
43
|
+
export async function serializeResources(resourceCollection) {
|
|
44
|
+
return Promise.all(
|
|
45
|
+
resourceCollection.map(async (res) => ({
|
|
46
|
+
buffer: await res.getBuffer(),
|
|
47
|
+
path: res.getPath()
|
|
48
|
+
}))
|
|
49
|
+
);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Casts Uint8Array into @ui5/fs/Resource-s transferable object
|
|
54
|
+
*
|
|
55
|
+
* @param {Promise<object[]>} resources
|
|
56
|
+
* @returns {@ui5/fs/Resource[]}
|
|
57
|
+
*/
|
|
58
|
+
export function deserializeResources(resources) {
|
|
59
|
+
return resources.map((res) => {
|
|
60
|
+
// res.buffer is an Uint8Array object and needs to be cast
|
|
61
|
+
// to a Buffer in order to be read correctly.
|
|
62
|
+
return createResource({path: res.path, buffer: Buffer.from(res.buffer)});
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* "@ui5/fs/fsInterface" like class that uses internally
|
|
68
|
+
* "@ui5/fs/fsInterface", implements its methods, and
|
|
69
|
+
* sends the results to a MessagePort.
|
|
70
|
+
*
|
|
71
|
+
* Used in the main thread in a combination with FsWorkerThreadInterface.
|
|
72
|
+
*/
|
|
73
|
+
export class FsMainThreadInterface {
|
|
74
|
+
#comPorts = new Set();
|
|
75
|
+
#fsInterfaceReader = null;
|
|
76
|
+
#cache = Object.create(null);
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Constructor
|
|
80
|
+
*
|
|
81
|
+
* @param {@ui5/fs/fsInterface} fsInterfaceReader Reader for the Resources
|
|
82
|
+
*/
|
|
83
|
+
constructor(fsInterfaceReader) {
|
|
84
|
+
if (!fsInterfaceReader) {
|
|
85
|
+
throw new Error("fsInterfaceReader is mandatory argument");
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
this.#fsInterfaceReader = fsInterfaceReader;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Adds MessagePort and starts listening for requests on it.
|
|
93
|
+
*
|
|
94
|
+
* @param {MessagePort} comPort port1 from a {code}MessageChannel{/code}
|
|
95
|
+
*/
|
|
96
|
+
startCommunication(comPort) {
|
|
97
|
+
if (!comPort) {
|
|
98
|
+
throw new Error("Communication channel is mandatory argument");
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
this.#comPorts.add(comPort);
|
|
102
|
+
comPort.on("message", (e) => this.#onMessage(e, comPort));
|
|
103
|
+
comPort.on("close", () => comPort.close());
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Ends MessagePort communication.
|
|
108
|
+
*
|
|
109
|
+
* @param {MessagePort} comPort port1 to remove from handling.
|
|
110
|
+
*/
|
|
111
|
+
endCommunication(comPort) {
|
|
112
|
+
comPort.close();
|
|
113
|
+
this.#comPorts.delete(comPort);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Destroys the FsMainThreadInterface
|
|
118
|
+
*/
|
|
119
|
+
cleanup() {
|
|
120
|
+
this.#comPorts.forEach((comPort) => comPort.close());
|
|
121
|
+
this.#cache = null;
|
|
122
|
+
this.#fsInterfaceReader = null;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Handles messages from the MessagePort
|
|
127
|
+
*
|
|
128
|
+
* @param {object} e data to construct the request
|
|
129
|
+
* @param {string} e.action Action to perform. Corresponds to the names of
|
|
130
|
+
* the public methods of "@ui5/fs/fsInterface"
|
|
131
|
+
* @param {string} e.fsPath Path of the Resource
|
|
132
|
+
* @param {object} e.options Options for "readFile" action
|
|
133
|
+
* @param {MessagePort} comPort The communication channel
|
|
134
|
+
*/
|
|
135
|
+
#onMessage(e, comPort) {
|
|
136
|
+
switch (e.action) {
|
|
137
|
+
case "readFile":
|
|
138
|
+
this.#doRequest(comPort, {action: "readFile", fsPath: e.fsPath, options: e.options});
|
|
139
|
+
break;
|
|
140
|
+
case "stat":
|
|
141
|
+
this.#doRequest(comPort, {action: "stat", fsPath: e.fsPath});
|
|
142
|
+
break;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* Requests a Resource from the "@ui5/fs/fsInterface" and sends it to the worker threads
|
|
148
|
+
* via postMessage.
|
|
149
|
+
*
|
|
150
|
+
* @param {MessagePort} comPort The communication channel
|
|
151
|
+
* @param {object} parameters
|
|
152
|
+
* @param {string} parameters.action Action to perform. Corresponds to the names of
|
|
153
|
+
* the public methods of "@ui5/fs/fsInterface" and triggers this method of the
|
|
154
|
+
* "@ui5/fs/fsInterface" instance.
|
|
155
|
+
* @param {string} parameters.fsPath Path of the Resource
|
|
156
|
+
* @param {object} parameters.options Options for "readFile" action
|
|
157
|
+
*/
|
|
158
|
+
async #doRequest(comPort, {action, fsPath, options}) {
|
|
159
|
+
const cacheKey = `${fsPath}-${action}`;
|
|
160
|
+
if (!this.#cache[cacheKey]) {
|
|
161
|
+
this.#cache[cacheKey] = new Promise((res) => {
|
|
162
|
+
if (action === "readFile") {
|
|
163
|
+
this.#fsInterfaceReader.readFile(fsPath, options, (error, result) => res({error, result}));
|
|
164
|
+
} else if (action === "stat") {
|
|
165
|
+
this.#fsInterfaceReader.stat(fsPath, (error, result) =>
|
|
166
|
+
// The Stat object has some special methods that sometimes cannot be serialized
|
|
167
|
+
// properly in the postMessage. In this scenario, we do not need those methods,
|
|
168
|
+
// but just to check whether stats has resolved to something.
|
|
169
|
+
res(JSON.parse(JSON.stringify({error, result})))
|
|
170
|
+
);
|
|
171
|
+
} else {
|
|
172
|
+
res({error: new Error(`Action "${action}" is not available.`), result: null});
|
|
173
|
+
}
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
const fromCache = await this.#cache[cacheKey];
|
|
178
|
+
comPort.postMessage({action, fsPath, ...fromCache});
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* "@ui5/fs/fsInterface" like class that uses internally
|
|
184
|
+
* "@ui5/fs/fsInterface", implements its methods, and
|
|
185
|
+
* requests resources via MessagePort.
|
|
186
|
+
*
|
|
187
|
+
* Used in the main thread in a combination with FsMainThreadInterface.
|
|
188
|
+
*/
|
|
189
|
+
export class FsWorkerThreadInterface {
|
|
190
|
+
#comPort = null;
|
|
191
|
+
#callbacks = [];
|
|
192
|
+
#cache = Object.create(null);
|
|
193
|
+
|
|
194
|
+
/**
|
|
195
|
+
* Constructor
|
|
196
|
+
*
|
|
197
|
+
* @param {MessagePort} comPort Communication port
|
|
198
|
+
*/
|
|
199
|
+
constructor(comPort) {
|
|
200
|
+
if (!comPort) {
|
|
201
|
+
throw new Error("Communication port is mandatory argument");
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
this.#comPort = comPort;
|
|
205
|
+
comPort.on("message", this.#onMessage.bind(this));
|
|
206
|
+
comPort.on("close", this.#onClose.bind(this));
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
/**
|
|
210
|
+
* Handles messages from MessagePort
|
|
211
|
+
*
|
|
212
|
+
* @param {object} e
|
|
213
|
+
* @param {string} e.action Action to perform. Corresponds to the names of
|
|
214
|
+
* the public methods of "@ui5/fs/fsInterface"
|
|
215
|
+
* @param {string} e.fsPath Path of the Resource
|
|
216
|
+
* @param {*} e.result Response from the "action".
|
|
217
|
+
* @param {object} e.error Error from the "action".
|
|
218
|
+
*/
|
|
219
|
+
#onMessage(e) {
|
|
220
|
+
const cbObject = this.#callbacks.find((cb) => cb.action === e.action && cb.fsPath === e.fsPath);
|
|
221
|
+
|
|
222
|
+
if (cbObject) {
|
|
223
|
+
this.#cache[`${e.fsPath}-${e.action}`] = {error: e.error, result: e.result};
|
|
224
|
+
this.#callbacks.splice(this.#callbacks.indexOf(cbObject), 1);
|
|
225
|
+
cbObject.callback(e.error, e.result);
|
|
226
|
+
} else {
|
|
227
|
+
throw new Error("No callback found for this message! Possible hang for the thread!", e);
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
/**
|
|
232
|
+
* End communication
|
|
233
|
+
*/
|
|
234
|
+
#onClose() {
|
|
235
|
+
this.#comPort.close();
|
|
236
|
+
this.#cache = null;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
/**
|
|
240
|
+
* Makes a request via the MessagePort
|
|
241
|
+
*
|
|
242
|
+
* @param {object} parameters
|
|
243
|
+
* @param {string} parameters.action Action to perform. Corresponds to the names of
|
|
244
|
+
* the public methods.
|
|
245
|
+
* @param {string} parameters.fsPath Path of the Resource
|
|
246
|
+
* @param {object} parameters.options Options for "readFile" action
|
|
247
|
+
* @param {Function} callback Callback to call when the "action" is executed and ready.
|
|
248
|
+
*/
|
|
249
|
+
#doRequest({action, fsPath, options}, callback) {
|
|
250
|
+
const cacheKey = `${fsPath}-${action}`;
|
|
251
|
+
|
|
252
|
+
if (this.#cache[cacheKey]) {
|
|
253
|
+
const {result, error} = this.#cache[cacheKey];
|
|
254
|
+
callback(error, result);
|
|
255
|
+
} else {
|
|
256
|
+
this.#callbacks.push({action, fsPath, callback});
|
|
257
|
+
this.#comPort.postMessage({action, fsPath, options});
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
readFile(fsPath, options, callback) {
|
|
262
|
+
this.#doRequest({action: "readFile", fsPath, options}, callback);
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
stat(fsPath, callback) {
|
|
266
|
+
this.#doRequest({action: "stat", fsPath}, callback);
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
// Test execution via ava is never done on the main thread
|
|
271
|
+
/* istanbul ignore else */
|
|
272
|
+
if (!workerpool.isMainThread) {
|
|
273
|
+
// Script got loaded through workerpool
|
|
274
|
+
// => Create a worker and register public functions
|
|
275
|
+
workerpool.worker({
|
|
276
|
+
execThemeBuild
|
|
277
|
+
});
|
|
278
|
+
}
|
package/lib/tasks/buildThemes.js
CHANGED
|
@@ -1,9 +1,44 @@
|
|
|
1
1
|
import path from "node:path";
|
|
2
|
-
import themeBuilder from "../processors/themeBuilder.js";
|
|
3
2
|
import fsInterface from "@ui5/fs/fsInterface";
|
|
4
3
|
import ReaderCollectionPrioritized from "@ui5/fs/ReaderCollectionPrioritized";
|
|
5
4
|
import {getLogger} from "@ui5/logger";
|
|
6
5
|
const log = getLogger("builder:tasks:buildThemes");
|
|
6
|
+
import {fileURLToPath} from "node:url";
|
|
7
|
+
import os from "node:os";
|
|
8
|
+
import workerpool from "workerpool";
|
|
9
|
+
import {deserializeResources, serializeResources, FsMainThreadInterface} from "../processors/themeBuilderWorker.js";
|
|
10
|
+
|
|
11
|
+
let pool;
|
|
12
|
+
|
|
13
|
+
function getPool(taskUtil) {
|
|
14
|
+
if (!pool) {
|
|
15
|
+
const MIN_WORKERS = 2;
|
|
16
|
+
const MAX_WORKERS = 4;
|
|
17
|
+
const osCpus = os.cpus().length || 1;
|
|
18
|
+
const maxWorkers = Math.max(Math.min(osCpus - 1, MAX_WORKERS), MIN_WORKERS);
|
|
19
|
+
|
|
20
|
+
log.verbose(`Creating workerpool with up to ${maxWorkers} workers (available CPU cores: ${osCpus})`);
|
|
21
|
+
const workerPath = fileURLToPath(new URL("../processors/themeBuilderWorker.js", import.meta.url));
|
|
22
|
+
pool = workerpool.pool(workerPath, {
|
|
23
|
+
workerType: "thread",
|
|
24
|
+
maxWorkers
|
|
25
|
+
});
|
|
26
|
+
taskUtil.registerCleanupTask(() => {
|
|
27
|
+
log.verbose(`Terminating workerpool`);
|
|
28
|
+
const poolToBeTerminated = pool;
|
|
29
|
+
pool = null;
|
|
30
|
+
poolToBeTerminated.terminate();
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
return pool;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
async function buildThemeInWorker(taskUtil, options, transferList) {
|
|
37
|
+
const toTransfer = transferList ? {transfer: transferList} : undefined;
|
|
38
|
+
|
|
39
|
+
return getPool(taskUtil).exec("execThemeBuild", [options], toTransfer);
|
|
40
|
+
}
|
|
41
|
+
|
|
7
42
|
|
|
8
43
|
/**
|
|
9
44
|
* @public
|
|
@@ -19,6 +54,8 @@ const log = getLogger("builder:tasks:buildThemes");
|
|
|
19
54
|
* @param {object} parameters Parameters
|
|
20
55
|
* @param {@ui5/fs/DuplexCollection} parameters.workspace DuplexCollection to read and write files
|
|
21
56
|
* @param {@ui5/fs/AbstractReader} parameters.dependencies Reader or Collection to read dependency files
|
|
57
|
+
* @param {@ui5/builder/tasks/TaskUtil|object} [parameters.taskUtil] TaskUtil instance.
|
|
58
|
+
* Required to run buildThemes in parallel execution mode.
|
|
22
59
|
* @param {object} parameters.options Options
|
|
23
60
|
* @param {string} parameters.options.projectName Project name
|
|
24
61
|
* @param {string} parameters.options.inputPattern Search pattern for *.less files to be built
|
|
@@ -29,9 +66,10 @@ const log = getLogger("builder:tasks:buildThemes");
|
|
|
29
66
|
* @returns {Promise<undefined>} Promise resolving with <code>undefined</code> once data has been written
|
|
30
67
|
*/
|
|
31
68
|
export default async function({
|
|
32
|
-
workspace, dependencies,
|
|
69
|
+
workspace, dependencies, taskUtil,
|
|
33
70
|
options: {
|
|
34
|
-
projectName, inputPattern, librariesPattern, themesPattern, compress,
|
|
71
|
+
projectName, inputPattern, librariesPattern, themesPattern, compress,
|
|
72
|
+
cssVariables
|
|
35
73
|
}
|
|
36
74
|
}) {
|
|
37
75
|
const combo = new ReaderCollectionPrioritized({
|
|
@@ -41,7 +79,7 @@ export default async function({
|
|
|
41
79
|
|
|
42
80
|
compress = compress === undefined ? true : compress;
|
|
43
81
|
|
|
44
|
-
const
|
|
82
|
+
const pThemeResources = workspace.byGlob(inputPattern);
|
|
45
83
|
let pAvailableLibraries;
|
|
46
84
|
let pAvailableThemes;
|
|
47
85
|
if (librariesPattern) {
|
|
@@ -78,7 +116,7 @@ export default async function({
|
|
|
78
116
|
});
|
|
79
117
|
}
|
|
80
118
|
|
|
81
|
-
let
|
|
119
|
+
let themeResources = await pThemeResources;
|
|
82
120
|
|
|
83
121
|
const isAvailable = function(resource) {
|
|
84
122
|
let libraryAvailable = false;
|
|
@@ -128,17 +166,48 @@ export default async function({
|
|
|
128
166
|
log.verbose(`Available sap.ui.core themes: ${availableThemes.join(", ")}`);
|
|
129
167
|
}
|
|
130
168
|
}
|
|
131
|
-
|
|
169
|
+
themeResources = themeResources.filter(isAvailable);
|
|
132
170
|
}
|
|
133
171
|
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
172
|
+
let processedResources;
|
|
173
|
+
const useWorkers = !!taskUtil;
|
|
174
|
+
if (useWorkers) {
|
|
175
|
+
const threadMessageHandler = new FsMainThreadInterface(fsInterface(combo));
|
|
176
|
+
|
|
177
|
+
processedResources = await Promise.all(themeResources.map(async (themeRes) => {
|
|
178
|
+
const {port1, port2} = new MessageChannel();
|
|
179
|
+
threadMessageHandler.startCommunication(port1);
|
|
180
|
+
|
|
181
|
+
const result = await buildThemeInWorker(taskUtil, {
|
|
182
|
+
fsInterfacePort: port2,
|
|
183
|
+
themeResources: await serializeResources([themeRes]),
|
|
184
|
+
options: {
|
|
185
|
+
compress,
|
|
186
|
+
cssVariables: !!cssVariables,
|
|
187
|
+
},
|
|
188
|
+
}, [port2]);
|
|
189
|
+
|
|
190
|
+
threadMessageHandler.endCommunication(port1);
|
|
191
|
+
|
|
192
|
+
return result;
|
|
193
|
+
}))
|
|
194
|
+
.then((resources) => Array.prototype.concat.apply([], resources))
|
|
195
|
+
.then(deserializeResources);
|
|
196
|
+
|
|
197
|
+
threadMessageHandler.cleanup();
|
|
198
|
+
} else {
|
|
199
|
+
// Do not use workerpool
|
|
200
|
+
const themeBuilder = (await import("../processors/themeBuilder.js")).default;
|
|
201
|
+
|
|
202
|
+
processedResources = await themeBuilder({
|
|
203
|
+
resources: themeResources,
|
|
204
|
+
fs: fsInterface(combo),
|
|
205
|
+
options: {
|
|
206
|
+
compress,
|
|
207
|
+
cssVariables: !!cssVariables,
|
|
208
|
+
}
|
|
209
|
+
});
|
|
210
|
+
}
|
|
142
211
|
|
|
143
212
|
await Promise.all(processedResources.map((resource) => {
|
|
144
213
|
return workspace.write(resource);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ui5/builder",
|
|
3
|
-
"version": "3.0.
|
|
3
|
+
"version": "3.0.9",
|
|
4
4
|
"description": "UI5 Tooling - Builder",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "SAP SE",
|
|
@@ -131,7 +131,7 @@
|
|
|
131
131
|
"pretty-data": "^0.40.0",
|
|
132
132
|
"rimraf": "^5.0.1",
|
|
133
133
|
"semver": "^7.5.4",
|
|
134
|
-
"terser": "^5.19.
|
|
134
|
+
"terser": "^5.19.2",
|
|
135
135
|
"workerpool": "^6.4.0",
|
|
136
136
|
"xml2js": "^0.6.0"
|
|
137
137
|
},
|
|
@@ -149,7 +149,7 @@
|
|
|
149
149
|
"eslint-config-google": "^0.14.0",
|
|
150
150
|
"eslint-plugin-ava": "^14.0.0",
|
|
151
151
|
"eslint-plugin-jsdoc": "^46.4.4",
|
|
152
|
-
"esmock": "^2.3.
|
|
152
|
+
"esmock": "^2.3.2",
|
|
153
153
|
"nyc": "^15.1.0",
|
|
154
154
|
"open-cli": "^7.2.0",
|
|
155
155
|
"recursive-readdir": "^2.2.3",
|