@ui5/builder 2.11.4 → 3.0.0-alpha.2
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 +52 -9
- package/index.js +4 -16
- package/jsdoc.json +0 -1
- package/lib/builder/BuildContext.js +17 -0
- package/lib/builder/ProjectBuildContext.js +9 -7
- package/lib/builder/builder.js +1 -2
- package/lib/lbt/analyzer/JSModuleAnalyzer.js +18 -3
- package/lib/lbt/analyzer/XMLTemplateAnalyzer.js +2 -1
- package/lib/lbt/bundle/AutoSplitter.js +10 -24
- package/lib/lbt/bundle/Builder.js +363 -134
- package/lib/lbt/bundle/BundleWriter.js +17 -0
- package/lib/lbt/bundle/Resolver.js +1 -1
- package/lib/lbt/resources/LocatorResource.js +9 -7
- package/lib/lbt/resources/LocatorResourcePool.js +8 -4
- package/lib/lbt/resources/Resource.js +7 -0
- package/lib/lbt/resources/ResourceCollector.js +33 -15
- package/lib/lbt/utils/parseUtils.js +1 -1
- package/lib/processors/bundlers/moduleBundler.js +39 -14
- package/lib/processors/minifier.js +89 -0
- package/lib/processors/resourceListCreator.js +2 -16
- package/lib/tasks/TaskUtil.js +9 -9
- package/lib/tasks/bundlers/generateBundle.js +92 -6
- package/lib/tasks/bundlers/generateComponentPreload.js +20 -6
- package/lib/tasks/bundlers/generateLibraryPreload.js +77 -10
- package/lib/tasks/bundlers/generateStandaloneAppBundle.js +58 -12
- package/lib/tasks/generateResourcesJson.js +14 -8
- package/lib/tasks/minify.js +39 -0
- package/lib/tasks/replaceVersion.js +1 -1
- package/lib/tasks/taskRepository.js +6 -2
- package/lib/types/application/ApplicationBuilder.js +22 -31
- package/lib/types/library/LibraryBuilder.js +23 -29
- package/lib/types/themeLibrary/ThemeLibraryBuilder.js +1 -0
- package/package.json +15 -13
- package/lib/processors/debugFileCreator.js +0 -52
- package/lib/processors/resourceCopier.js +0 -24
- package/lib/processors/uglifier.js +0 -45
- package/lib/tasks/createDebugFiles.js +0 -30
- package/lib/tasks/uglify.js +0 -33
|
@@ -11,6 +11,8 @@ const SPACES_OR_TABS_ONLY = /^[ \t]+$/;
|
|
|
11
11
|
*
|
|
12
12
|
* Most methods have been extracted from JSMergeWriter.
|
|
13
13
|
*
|
|
14
|
+
* columnOffset and lineOffset are used for sourcemap merging as reference to where we are at a given point in time
|
|
15
|
+
*
|
|
14
16
|
* @author Frank Weigel
|
|
15
17
|
* @since 1.27.0
|
|
16
18
|
* @private
|
|
@@ -18,6 +20,8 @@ const SPACES_OR_TABS_ONLY = /^[ \t]+$/;
|
|
|
18
20
|
class BundleWriter {
|
|
19
21
|
constructor() {
|
|
20
22
|
this.buf = "";
|
|
23
|
+
this.lineOffset = 0;
|
|
24
|
+
this.columnOffset = 0;
|
|
21
25
|
this.segments = [];
|
|
22
26
|
this.currentSegment = null;
|
|
23
27
|
this.currentSourceIndex = 0;
|
|
@@ -28,6 +32,11 @@ class BundleWriter {
|
|
|
28
32
|
let writeBuf = "";
|
|
29
33
|
for ( let i = 0; i < str.length; i++ ) {
|
|
30
34
|
writeBuf += str[i];
|
|
35
|
+
if (str[i] != null && str[i].split) {
|
|
36
|
+
const strSplit = str[i].split(NL);
|
|
37
|
+
this.lineOffset += strSplit.length - 1;
|
|
38
|
+
this.columnOffset += strSplit[strSplit.length - 1].length;
|
|
39
|
+
}
|
|
31
40
|
}
|
|
32
41
|
if ( writeBuf.length >= 1 ) {
|
|
33
42
|
this.buf += writeBuf;
|
|
@@ -40,15 +49,23 @@ class BundleWriter {
|
|
|
40
49
|
writeln(...str) {
|
|
41
50
|
for ( let i = 0; i < str.length; i++ ) {
|
|
42
51
|
this.buf += str[i];
|
|
52
|
+
if (str[i] != null && str[i].split) {
|
|
53
|
+
const strSplit = str[i].split(NL);
|
|
54
|
+
this.lineOffset += strSplit.length - 1;
|
|
55
|
+
}
|
|
43
56
|
}
|
|
44
57
|
this.buf += NL;
|
|
45
58
|
this.endsWithNewLine = true;
|
|
59
|
+
this.lineOffset += 1;
|
|
60
|
+
this.columnOffset = 0;
|
|
46
61
|
}
|
|
47
62
|
|
|
48
63
|
ensureNewLine() {
|
|
49
64
|
if ( !this.endsWithNewLine ) {
|
|
50
65
|
this.buf += NL;
|
|
51
66
|
this.endsWithNewLine = true;
|
|
67
|
+
this.lineOffset += 1;
|
|
68
|
+
this.columnOffset = 0;
|
|
52
69
|
}
|
|
53
70
|
}
|
|
54
71
|
|
|
@@ -289,7 +289,7 @@ class BundleResolver {
|
|
|
289
289
|
|
|
290
290
|
return collectModulesForSection(section).
|
|
291
291
|
then( (modules) => {
|
|
292
|
-
if ( section.mode == SectionType.Raw && section.sort ) {
|
|
292
|
+
if ( section.mode == SectionType.Raw && section.sort !== false ) {
|
|
293
293
|
// sort the modules in topological order
|
|
294
294
|
return topologicalSort(pool, modules).then( (modules) => {
|
|
295
295
|
log.verbose(" resolved modules (sorted): %s", modules);
|
|
@@ -1,14 +1,12 @@
|
|
|
1
1
|
const Resource = require("./Resource");
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
}
|
|
7
|
-
|
|
3
|
+
// function extractName(path) {
|
|
4
|
+
// return path.slice( "/resources/".length);
|
|
5
|
+
// }
|
|
8
6
|
|
|
9
7
|
class LocatorResource extends Resource {
|
|
10
|
-
constructor(pool, resource) {
|
|
11
|
-
super(pool,
|
|
8
|
+
constructor(pool, resource, moduleName) {
|
|
9
|
+
super(pool, moduleName, null, resource.getStatInfo());
|
|
12
10
|
this.resource = resource;
|
|
13
11
|
}
|
|
14
12
|
|
|
@@ -19,6 +17,10 @@ class LocatorResource extends Resource {
|
|
|
19
17
|
getProject() {
|
|
20
18
|
return this.resource._project;
|
|
21
19
|
}
|
|
20
|
+
|
|
21
|
+
getPath() {
|
|
22
|
+
return this.resource.getPath();
|
|
23
|
+
}
|
|
22
24
|
}
|
|
23
25
|
|
|
24
26
|
module.exports = LocatorResource;
|
|
@@ -2,12 +2,16 @@ const ResourcePool = require("./ResourcePool");
|
|
|
2
2
|
const LocatorResource = require("./LocatorResource");
|
|
3
3
|
|
|
4
4
|
class LocatorResourcePool extends ResourcePool {
|
|
5
|
-
prepare(resources) {
|
|
5
|
+
prepare(resources, moduleNameMapping) {
|
|
6
6
|
resources = resources.filter( (res) => !res.getStatInfo().isDirectory() );
|
|
7
7
|
return Promise.all(
|
|
8
|
-
resources.map(
|
|
9
|
-
|
|
10
|
-
|
|
8
|
+
resources.map((resource) => {
|
|
9
|
+
let moduleName = moduleNameMapping && moduleNameMapping[resource.getPath()];
|
|
10
|
+
if (!moduleName) {
|
|
11
|
+
moduleName = resource.getPath().slice("/resources/".length);
|
|
12
|
+
}
|
|
13
|
+
this.addResource(new LocatorResource(this, resource, moduleName));
|
|
14
|
+
}).filter(Boolean)
|
|
11
15
|
);
|
|
12
16
|
}
|
|
13
17
|
}
|
|
@@ -18,6 +18,13 @@ class Resource {
|
|
|
18
18
|
async buffer() {
|
|
19
19
|
return readFile(this.file);
|
|
20
20
|
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* @returns {Promise<string>} String of the file content
|
|
24
|
+
*/
|
|
25
|
+
async string() {
|
|
26
|
+
return (await this.buffer()).toString();
|
|
27
|
+
}
|
|
21
28
|
}
|
|
22
29
|
|
|
23
30
|
module.exports = Resource;
|
|
@@ -193,17 +193,16 @@ class ResourceCollector {
|
|
|
193
193
|
}
|
|
194
194
|
|
|
195
195
|
async determineResourceDetails({
|
|
196
|
-
debugResources, mergedResources, designtimeResources, supportResources
|
|
196
|
+
debugResources, mergedResources, designtimeResources, supportResources
|
|
197
197
|
}) {
|
|
198
198
|
const baseNames = new Set();
|
|
199
199
|
const debugFilter = new ResourceFilterList(debugResources);
|
|
200
200
|
const mergeFilter = new ResourceFilterList(mergedResources);
|
|
201
201
|
const designtimeFilter = new ResourceFilterList(designtimeResources);
|
|
202
202
|
const supportFilter = new ResourceFilterList(supportResources);
|
|
203
|
-
const debugBundleFilter = new ResourceFilterList(debugBundles);
|
|
204
203
|
|
|
205
204
|
const promises = [];
|
|
206
|
-
const
|
|
205
|
+
const debugResourcesInfo = [];
|
|
207
206
|
|
|
208
207
|
for (const [name, info] of this._resources.entries()) {
|
|
209
208
|
if ( debugFilter.matches(name) ) {
|
|
@@ -231,13 +230,14 @@ class ResourceCollector {
|
|
|
231
230
|
}
|
|
232
231
|
|
|
233
232
|
if ( /(?:\.js|\.view\.xml|\.control\.xml|\.fragment\.xml)$/.test(name) ) {
|
|
234
|
-
if (
|
|
235
|
-
// Only analyze non-
|
|
233
|
+
if ( !info.isDebug ) {
|
|
234
|
+
// Only analyze non-dbg files in first run
|
|
236
235
|
promises.push(
|
|
237
236
|
this.enrichWithDependencyInfo(info)
|
|
238
237
|
);
|
|
239
238
|
} else {
|
|
240
|
-
|
|
239
|
+
// Collect dbg files to be handled in a second step (see below)
|
|
240
|
+
debugResourcesInfo.push(info);
|
|
241
241
|
}
|
|
242
242
|
}
|
|
243
243
|
|
|
@@ -279,19 +279,37 @@ class ResourceCollector {
|
|
|
279
279
|
|
|
280
280
|
await Promise.all(promises);
|
|
281
281
|
|
|
282
|
-
|
|
283
|
-
|
|
282
|
+
const debugBundlePromises = [];
|
|
283
|
+
|
|
284
|
+
for (let i = debugResourcesInfo.length - 1; i >= 0; i--) {
|
|
285
|
+
const dbgInfo = debugResourcesInfo[i];
|
|
284
286
|
const nonDebugName = ResourceInfoList.getNonDebugName(dbgInfo.name);
|
|
285
287
|
const nonDbgInfo = this._resources.get(nonDebugName);
|
|
286
|
-
const newDbgInfo = new ResourceInfo(dbgInfo.name);
|
|
287
|
-
|
|
288
|
-
// First copy info of analysis from non-dbg file (included, required, condRequired, ...)
|
|
289
|
-
newDbgInfo.copyFrom(null, nonDbgInfo);
|
|
290
|
-
// Then copy over info from dbg file to properly set name, isDebug, etc.
|
|
291
|
-
newDbgInfo.copyFrom(null, dbgInfo);
|
|
292
288
|
|
|
293
|
-
|
|
289
|
+
// FIXME: "merged" property is only calculated in ResourceInfo#copyFrom
|
|
290
|
+
// Therefore using the same logic here to compute it.
|
|
291
|
+
if (!nonDbgInfo || (nonDbgInfo.included != null && nonDbgInfo.included.size > 0)) {
|
|
292
|
+
// We need to analyze the dbg resource if there is no non-dbg variant or
|
|
293
|
+
// it is a bundle because we will (usually) have different content.
|
|
294
|
+
debugBundlePromises.push(
|
|
295
|
+
this.enrichWithDependencyInfo(dbgInfo)
|
|
296
|
+
);
|
|
297
|
+
} else {
|
|
298
|
+
// If the non-dbg resource is not a bundle, we can just copy over the info and skip
|
|
299
|
+
// analyzing the dbg variant as both should have the same info.
|
|
300
|
+
|
|
301
|
+
const newDbgInfo = new ResourceInfo(dbgInfo.name);
|
|
302
|
+
|
|
303
|
+
// First copy info of analysis from non-dbg file (included, required, condRequired, ...)
|
|
304
|
+
newDbgInfo.copyFrom(null, nonDbgInfo);
|
|
305
|
+
// Then copy over info from dbg file to properly set name, isDebug, etc.
|
|
306
|
+
newDbgInfo.copyFrom(null, dbgInfo);
|
|
307
|
+
|
|
308
|
+
this._resources.set(dbgInfo.name, newDbgInfo);
|
|
309
|
+
}
|
|
294
310
|
}
|
|
311
|
+
|
|
312
|
+
await Promise.all(debugBundlePromises);
|
|
295
313
|
}
|
|
296
314
|
|
|
297
315
|
createOrphanFilters() {
|
|
@@ -9,7 +9,7 @@ function parseJS(code, userOptions = {}) {
|
|
|
9
9
|
// allowed options and their defaults
|
|
10
10
|
const options = {
|
|
11
11
|
comment: false,
|
|
12
|
-
ecmaVersion:
|
|
12
|
+
ecmaVersion: 2021, // NOTE: Adopt JSModuleAnalyzer.js to allow new Syntax when upgrading to newer ECMA versions
|
|
13
13
|
range: false,
|
|
14
14
|
sourceType: "script",
|
|
15
15
|
};
|
|
@@ -89,7 +89,9 @@ const log = require("@ui5/logger").getLogger("builder:processors:bundlers:module
|
|
|
89
89
|
*
|
|
90
90
|
* @public
|
|
91
91
|
* @typedef {object} ModuleBundleOptions
|
|
92
|
-
* @property {boolean} [optimize=
|
|
92
|
+
* @property {boolean} [optimize=true] Whether the module bundle gets minified
|
|
93
|
+
* @property {boolean} [sourceMap] Whether to generate a source map file for the bundle.
|
|
94
|
+
* Defaults to true if <code>optimize</code> is set to true
|
|
93
95
|
* @property {boolean} [decorateBootstrapModule=false] If set to 'false', the module won't be decorated
|
|
94
96
|
* with an optimization marker
|
|
95
97
|
* @property {boolean} [addTryCatchRestartWrapper=false] Whether to wrap bootable module bundles with
|
|
@@ -101,23 +103,39 @@ const log = require("@ui5/logger").getLogger("builder:processors:bundlers:module
|
|
|
101
103
|
*/
|
|
102
104
|
|
|
103
105
|
/**
|
|
104
|
-
*
|
|
106
|
+
* Result set
|
|
107
|
+
*
|
|
108
|
+
* @public
|
|
109
|
+
* @typedef {object} ModuleBundlerResult
|
|
110
|
+
* @property {module:@ui5/fs.Resource} bundle Bundle resource
|
|
111
|
+
* @property {module:@ui5/fs.Resource} sourceMap Source Map
|
|
112
|
+
* @memberof module:@ui5/builder.processors
|
|
113
|
+
*/
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Legacy module bundler.
|
|
105
117
|
*
|
|
106
118
|
* @public
|
|
107
119
|
* @alias module:@ui5/builder.processors.moduleBundler
|
|
108
120
|
* @param {object} parameters Parameters
|
|
109
121
|
* @param {module:@ui5/fs.Resource[]} parameters.resources Resources
|
|
110
122
|
* @param {object} parameters.options Options
|
|
123
|
+
* @param {object} [parameters.options.moduleNameMapping]
|
|
124
|
+
Optional mapping of resource paths to module name in order to overwrite the default determination
|
|
111
125
|
* @param {ModuleBundleDefinition} parameters.options.bundleDefinition Module bundle definition
|
|
112
|
-
* @param {ModuleBundleOptions} parameters.options.bundleOptions Module bundle options
|
|
113
|
-
* @returns {Promise<module:@ui5/
|
|
126
|
+
* @param {ModuleBundleOptions} [parameters.options.bundleOptions] Module bundle options
|
|
127
|
+
* @returns {Promise<module:@ui5/builder.processors.MinifierResult[]>} Promise resolving with module bundle resources
|
|
114
128
|
*/
|
|
115
|
-
module.exports = function({resources, options: {bundleDefinition, bundleOptions}}) {
|
|
116
|
-
//
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
129
|
+
module.exports = function({resources, options: {bundleDefinition, bundleOptions, moduleNameMapping}}) {
|
|
130
|
+
// Apply defaults without modifying the passed object
|
|
131
|
+
bundleOptions = Object.assign({}, {
|
|
132
|
+
optimize: true,
|
|
133
|
+
decorateBootstrapModule: false,
|
|
134
|
+
addTryCatchRestartWrapper: false,
|
|
135
|
+
usePredefineCalls: false,
|
|
136
|
+
numberOfParts: 1,
|
|
137
|
+
ignoreMissingModules: false
|
|
138
|
+
}, bundleOptions);
|
|
121
139
|
|
|
122
140
|
const pool = new LocatorResourcePool({
|
|
123
141
|
ignoreMissingModules: bundleOptions.ignoreMissingModules
|
|
@@ -130,7 +148,7 @@ module.exports = function({resources, options: {bundleDefinition, bundleOptions}
|
|
|
130
148
|
log.verbose(`bundleOptions: ${JSON.stringify(bundleOptions, null, 2)}`);
|
|
131
149
|
}
|
|
132
150
|
|
|
133
|
-
return pool.prepare( resources ).
|
|
151
|
+
return pool.prepare( resources, moduleNameMapping ).
|
|
134
152
|
then( () => builder.createBundle(bundleDefinition, bundleOptions) ).
|
|
135
153
|
then( (results) => {
|
|
136
154
|
let bundles;
|
|
@@ -142,13 +160,20 @@ module.exports = function({resources, options: {bundleDefinition, bundleOptions}
|
|
|
142
160
|
|
|
143
161
|
return Promise.all(bundles.map((bundleObj) => {
|
|
144
162
|
if ( bundleObj ) {
|
|
145
|
-
const {name, content} = bundleObj;
|
|
163
|
+
const {name, content, sourceMap} = bundleObj;
|
|
146
164
|
// console.log("creating bundle as '%s'", "/resources/" + name);
|
|
147
|
-
const
|
|
165
|
+
const res = {};
|
|
166
|
+
res.bundle = new EvoResource({
|
|
148
167
|
path: "/resources/" + name,
|
|
149
168
|
string: content
|
|
150
169
|
});
|
|
151
|
-
|
|
170
|
+
if (sourceMap) {
|
|
171
|
+
res.sourceMap = new EvoResource({
|
|
172
|
+
path: "/resources/" + name + ".map",
|
|
173
|
+
string: sourceMap
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
return res;
|
|
152
177
|
}
|
|
153
178
|
}));
|
|
154
179
|
});
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
const path = require("path");
|
|
2
|
+
const terser = require("terser");
|
|
3
|
+
const Resource = require("@ui5/fs").Resource;
|
|
4
|
+
/**
|
|
5
|
+
* Preserve comments which contain:
|
|
6
|
+
* <ul>
|
|
7
|
+
* <li>copyright notice</li>
|
|
8
|
+
* <li>license terms</li>
|
|
9
|
+
* <li>"@ui5-bundle"</li>
|
|
10
|
+
* <li>"@ui5-bundle-raw-include"</li>
|
|
11
|
+
* </ul>
|
|
12
|
+
*
|
|
13
|
+
* @type {RegExp}
|
|
14
|
+
*/
|
|
15
|
+
const copyrightCommentsAndBundleCommentPattern = /copyright|\(c\)(?:[0-9]+|\s+[0-9A-za-z])|released under|license|\u00a9|^@ui5-bundle-raw-include |^@ui5-bundle /i;
|
|
16
|
+
const debugFileRegex = /((?:\.view|\.fragment|\.controller|\.designtime|\.support)?\.js)$/;
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Result set
|
|
21
|
+
*
|
|
22
|
+
* @public
|
|
23
|
+
* @typedef {object} MinifierResult
|
|
24
|
+
* @property {module:@ui5/fs.Resource} resource Minified resource
|
|
25
|
+
* @property {module:@ui5/fs.Resource} dbgResource Debug (non-minified) variant
|
|
26
|
+
* @property {module:@ui5/fs.Resource} sourceMap Source Map
|
|
27
|
+
* @memberof module:@ui5/builder.processors
|
|
28
|
+
*/
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Minifies the supplied resources.
|
|
32
|
+
*
|
|
33
|
+
* @public
|
|
34
|
+
* @alias module:@ui5/builder.processors.minifier
|
|
35
|
+
* @param {object} parameters Parameters
|
|
36
|
+
* @param {module:@ui5/fs.Resource[]} parameters.resources List of resources to be processed
|
|
37
|
+
* @param {boolean} [parameters.addSourceMappingUrl=true]
|
|
38
|
+
* Whether to add a sourceMappingURL reference to the end of the minified resource
|
|
39
|
+
* @returns {Promise<module:@ui5/builder.processors.MinifierResult[]>}
|
|
40
|
+
* Promise resolving with object of resource, dbgResource and sourceMap
|
|
41
|
+
*/
|
|
42
|
+
module.exports = async function({resources, addSourceMappingUrl = true}) {
|
|
43
|
+
return Promise.all(resources.map(async (resource) => {
|
|
44
|
+
const dbgPath = resource.getPath().replace(debugFileRegex, "-dbg$1");
|
|
45
|
+
const dbgResource = await resource.clone();
|
|
46
|
+
dbgResource.setPath(dbgPath);
|
|
47
|
+
|
|
48
|
+
const filename = path.posix.basename(resource.getPath());
|
|
49
|
+
const code = await resource.getString();
|
|
50
|
+
try {
|
|
51
|
+
const sourceMapOptions = {
|
|
52
|
+
filename
|
|
53
|
+
};
|
|
54
|
+
if (addSourceMappingUrl) {
|
|
55
|
+
sourceMapOptions.url = filename + ".map";
|
|
56
|
+
}
|
|
57
|
+
const dbgFilename = path.posix.basename(dbgPath);
|
|
58
|
+
const result = await terser.minify({
|
|
59
|
+
// Use debug-name since this will be referenced in the source map "sources"
|
|
60
|
+
[dbgFilename]: code
|
|
61
|
+
}, {
|
|
62
|
+
output: {
|
|
63
|
+
comments: copyrightCommentsAndBundleCommentPattern,
|
|
64
|
+
wrap_func_args: false
|
|
65
|
+
},
|
|
66
|
+
compress: false,
|
|
67
|
+
mangle: {
|
|
68
|
+
reserved: [
|
|
69
|
+
"jQuery",
|
|
70
|
+
"jquery",
|
|
71
|
+
"sap",
|
|
72
|
+
]
|
|
73
|
+
},
|
|
74
|
+
sourceMap: sourceMapOptions
|
|
75
|
+
});
|
|
76
|
+
resource.setString(result.code);
|
|
77
|
+
const sourceMapResource = new Resource({
|
|
78
|
+
path: resource.getPath() + ".map",
|
|
79
|
+
string: result.map
|
|
80
|
+
});
|
|
81
|
+
return {resource, dbgResource, sourceMapResource};
|
|
82
|
+
} catch (err) {
|
|
83
|
+
// Note: err.filename contains the debug-name
|
|
84
|
+
throw new Error(
|
|
85
|
+
`Minification failed with error: ${err.message} in file ${filename} ` +
|
|
86
|
+
`(line ${err.line}, col ${err.col}, pos ${err.pos})`);
|
|
87
|
+
}
|
|
88
|
+
}));
|
|
89
|
+
};
|
|
@@ -66,17 +66,6 @@ const DEFAULT_SUPPORT_RESOURCES_FILTER = [
|
|
|
66
66
|
"**/*.support.js"
|
|
67
67
|
];
|
|
68
68
|
|
|
69
|
-
/**
|
|
70
|
-
* Hard coded debug bundle, to trigger separate analysis for this filename
|
|
71
|
-
* because sap-ui-core.js and sap-ui-core-dbg.js have different includes
|
|
72
|
-
*
|
|
73
|
-
* @type {string[]}
|
|
74
|
-
*/
|
|
75
|
-
const DEBUG_BUNDLES = [
|
|
76
|
-
"sap-ui-core-dbg.js",
|
|
77
|
-
"sap-ui-core-nojQuery-dbg.js"
|
|
78
|
-
];
|
|
79
|
-
|
|
80
69
|
/**
|
|
81
70
|
* Creates and adds resources.json entry (itself) to the list.
|
|
82
71
|
*
|
|
@@ -138,8 +127,7 @@ module.exports = async function({resources, dependencyResources = [], options})
|
|
|
138
127
|
debugResources: DEFAULT_DEBUG_RESOURCES_FILTER,
|
|
139
128
|
mergedResources: DEFAULT_BUNDLE_RESOURCES_FILTER,
|
|
140
129
|
designtimeResources: DEFAULT_DESIGNTIME_RESOURCES_FILTER,
|
|
141
|
-
supportResources: DEFAULT_SUPPORT_RESOURCES_FILTER
|
|
142
|
-
debugBundles: DEBUG_BUNDLES
|
|
130
|
+
supportResources: DEFAULT_SUPPORT_RESOURCES_FILTER
|
|
143
131
|
}, options);
|
|
144
132
|
|
|
145
133
|
const pool = new LocatorResourcePool();
|
|
@@ -158,12 +146,10 @@ module.exports = async function({resources, dependencyResources = [], options})
|
|
|
158
146
|
}
|
|
159
147
|
|
|
160
148
|
await collector.determineResourceDetails({
|
|
161
|
-
pool,
|
|
162
149
|
debugResources: options.debugResources,
|
|
163
150
|
mergedResources: options.mergedResources,
|
|
164
151
|
designtimeResources: options.designtimeResources,
|
|
165
|
-
supportResources: options.supportResources
|
|
166
|
-
debugBundles: options.debugBundles
|
|
152
|
+
supportResources: options.supportResources
|
|
167
153
|
});
|
|
168
154
|
|
|
169
155
|
// group resources by components and create ResourceInfoLists
|
package/lib/tasks/TaskUtil.js
CHANGED
|
@@ -51,14 +51,14 @@ class TaskUtil {
|
|
|
51
51
|
* This method is only available to custom task extensions defining
|
|
52
52
|
* <b>Specification Version 2.2 and above</b>.
|
|
53
53
|
*
|
|
54
|
-
* @param {module:@ui5/fs.Resource}
|
|
54
|
+
* @param {string|module:@ui5/fs.Resource} resourcePath Path or resource-instance the tag should be stored for
|
|
55
55
|
* @param {string} tag Name of the tag.
|
|
56
56
|
* Currently only the [STANDARD_TAGS]{@link module:@ui5/builder.tasks.TaskUtil#STANDARD_TAGS} are allowed
|
|
57
57
|
* @param {string|boolean|integer} [value=true] Tag value. Must be primitive
|
|
58
58
|
* @public
|
|
59
59
|
*/
|
|
60
|
-
setTag(
|
|
61
|
-
return this._projectBuildContext.getResourceTagCollection().setTag(
|
|
60
|
+
setTag(resourcePath, tag, value) {
|
|
61
|
+
return this._projectBuildContext.getResourceTagCollection().setTag(resourcePath, tag, value);
|
|
62
62
|
}
|
|
63
63
|
|
|
64
64
|
/**
|
|
@@ -68,14 +68,14 @@ class TaskUtil {
|
|
|
68
68
|
* This method is only available to custom task extensions defining
|
|
69
69
|
* <b>Specification Version 2.2 and above</b>.
|
|
70
70
|
*
|
|
71
|
-
* @param {module:@ui5/fs.Resource}
|
|
71
|
+
* @param {string|module:@ui5/fs.Resource} resourcePath Path or resource-instance the tag should be retrieved for
|
|
72
72
|
* @param {string} tag Name of the tag
|
|
73
73
|
* @returns {string|boolean|integer|undefined} Tag value for the given resource.
|
|
74
74
|
* <code>undefined</code> if no value is available
|
|
75
75
|
* @public
|
|
76
76
|
*/
|
|
77
|
-
getTag(
|
|
78
|
-
return this._projectBuildContext.getResourceTagCollection().getTag(
|
|
77
|
+
getTag(resourcePath, tag) {
|
|
78
|
+
return this._projectBuildContext.getResourceTagCollection().getTag(resourcePath, tag);
|
|
79
79
|
}
|
|
80
80
|
|
|
81
81
|
/**
|
|
@@ -86,12 +86,12 @@ class TaskUtil {
|
|
|
86
86
|
* This method is only available to custom task extensions defining
|
|
87
87
|
* <b>Specification Version 2.2 and above</b>.
|
|
88
88
|
*
|
|
89
|
-
* @param {module:@ui5/fs.Resource}
|
|
89
|
+
* @param {string|module:@ui5/fs.Resource} resourcePath Path or resource-instance the tag should be cleared for
|
|
90
90
|
* @param {string} tag Tag
|
|
91
91
|
* @public
|
|
92
92
|
*/
|
|
93
|
-
clearTag(
|
|
94
|
-
return this._projectBuildContext.getResourceTagCollection().clearTag(
|
|
93
|
+
clearTag(resourcePath, tag) {
|
|
94
|
+
return this._projectBuildContext.getResourceTagCollection().clearTag(resourcePath, tag);
|
|
95
95
|
}
|
|
96
96
|
|
|
97
97
|
/**
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
const moduleBundler = require("../../processors/bundlers/moduleBundler");
|
|
2
|
+
const ModuleName = require("../../lbt/utils/ModuleName");
|
|
2
3
|
const ReaderCollectionPrioritized = require("@ui5/fs").ReaderCollectionPrioritized;
|
|
3
4
|
|
|
4
5
|
/**
|
|
@@ -13,30 +14,115 @@ const ReaderCollectionPrioritized = require("@ui5/fs").ReaderCollectionPrioritiz
|
|
|
13
14
|
* @param {object} parameters.options Options
|
|
14
15
|
* @param {string} parameters.options.projectName Project name
|
|
15
16
|
* @param {ModuleBundleDefinition} parameters.options.bundleDefinition Module bundle definition
|
|
16
|
-
* @param {ModuleBundleOptions} parameters.options.bundleOptions Module bundle options
|
|
17
|
+
* @param {ModuleBundleOptions} [parameters.options.bundleOptions] Module bundle options
|
|
17
18
|
* @returns {Promise} Promise resolving with <code>undefined</code> once data has been written
|
|
18
19
|
*/
|
|
19
20
|
module.exports = function({
|
|
20
21
|
workspace, dependencies, taskUtil, options: {projectName, bundleDefinition, bundleOptions}
|
|
21
22
|
}) {
|
|
22
|
-
|
|
23
|
+
let combo = new ReaderCollectionPrioritized({
|
|
23
24
|
name: `libraryBundler - prioritize workspace over dependencies: ${projectName}`,
|
|
24
25
|
readers: [workspace, dependencies]
|
|
25
26
|
});
|
|
26
27
|
|
|
27
|
-
|
|
28
|
+
const optimize = !bundleOptions || bundleOptions.optimize !== false;
|
|
29
|
+
if (taskUtil) {
|
|
30
|
+
/* Scenarios
|
|
31
|
+
1. Optimize bundle with minification already done
|
|
32
|
+
Workspace:
|
|
33
|
+
* /resources/my/lib/Control.js [ui5:HasDebugVariant]
|
|
34
|
+
* /resources/my/lib/Control.js.map [ui5:HasDebugVariant]
|
|
35
|
+
* /resources/my/lib/Control-dbg.js [ui5:IsDebugVariant]
|
|
36
|
+
|
|
37
|
+
Bundler input:
|
|
38
|
+
* /resources/my/lib/Control.js
|
|
39
|
+
* /resources/my/lib/Control.js.map
|
|
40
|
+
|
|
41
|
+
=> Filter out debug resources
|
|
42
|
+
|
|
43
|
+
2. Optimize bundle with no minification
|
|
44
|
+
* /resources/my/lib/Control.js
|
|
45
|
+
|
|
46
|
+
=> No action necessary
|
|
47
|
+
|
|
48
|
+
3. Debug-bundle with minification already done
|
|
49
|
+
Workspace:
|
|
50
|
+
* /resources/my/lib/Control.js [ui5:HasDebugVariant]
|
|
51
|
+
* /resources/my/lib/Control.js.map [ui5:HasDebugVariant]
|
|
52
|
+
* /resources/my/lib/Control-dbg.js [ui5:IsDebugVariant]
|
|
53
|
+
|
|
54
|
+
Bundler input:
|
|
55
|
+
* /resources/my/lib/Control-dbg.js
|
|
56
|
+
* moduleNameMapping: [{"/resources/my/lib/Control-dbg.js": "my/lib/Control.js"}]
|
|
57
|
+
|
|
58
|
+
=> Filter out minified-resources (tagged as "HasDebugVariant", incl. source maps) and rename debug-files
|
|
59
|
+
|
|
60
|
+
4. Debug-bundle with no minification
|
|
61
|
+
* /resources/my/lib/Control.js
|
|
62
|
+
|
|
63
|
+
=> No action necessary
|
|
64
|
+
|
|
65
|
+
5. Bundle with external input (optimize or not), e.g. TS-project
|
|
66
|
+
Workspace:
|
|
67
|
+
* /resources/my/lib/Control.ts
|
|
68
|
+
* /resources/my/lib/Control.js
|
|
69
|
+
* /resources/my/lib/Control.js.map
|
|
70
|
+
|
|
71
|
+
Bundler input:
|
|
72
|
+
* /resources/my/lib/Control.js
|
|
73
|
+
* /resources/my/lib/Control.js.map
|
|
74
|
+
*/
|
|
75
|
+
|
|
76
|
+
// Omit -dbg files for optimize bundles and vice versa
|
|
77
|
+
const filterTag = optimize ?
|
|
78
|
+
taskUtil.STANDARD_TAGS.IsDebugVariant : taskUtil.STANDARD_TAGS.HasDebugVariant;
|
|
79
|
+
combo = combo.filter(function(resource) {
|
|
80
|
+
return !taskUtil.getTag(resource, filterTag);
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
return combo.byGlob("/resources/**/*.{js,json,xml,html,properties,library,js.map}").then((resources) => {
|
|
85
|
+
const moduleNameMapping = {};
|
|
86
|
+
if (!optimize && taskUtil) {
|
|
87
|
+
// For "unoptimized" bundles, the non-debug files have already been filtered out above.
|
|
88
|
+
// Now we need to create a mapping from the debug-variant resource path to the respective module name,
|
|
89
|
+
// which is basically the non-debug resource path, minus the "/resources/"" prefix.
|
|
90
|
+
// This mapping overwrites internal logic of the LocatorResourcePool which would otherwise determine
|
|
91
|
+
// the module name from the resource path, which would contain "-dbg" in this case. That would be
|
|
92
|
+
// incorrect since debug-variants should still keep the original module name.
|
|
93
|
+
for (let i = resources.length - 1; i >= 0; i--) {
|
|
94
|
+
const resourcePath = resources[i].getPath();
|
|
95
|
+
if (taskUtil.getTag(resourcePath, taskUtil.STANDARD_TAGS.IsDebugVariant)) {
|
|
96
|
+
const nonDbgPath = ModuleName.getNonDebugName(resourcePath);
|
|
97
|
+
if (!nonDbgPath) {
|
|
98
|
+
throw new Error(`Failed to resolve non-debug name for ${resourcePath}`);
|
|
99
|
+
}
|
|
100
|
+
moduleNameMapping[resourcePath] = nonDbgPath.slice("/resources/".length);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
28
104
|
return moduleBundler({
|
|
29
105
|
options: {
|
|
30
106
|
bundleDefinition,
|
|
31
|
-
bundleOptions
|
|
107
|
+
bundleOptions,
|
|
108
|
+
moduleNameMapping
|
|
32
109
|
},
|
|
33
110
|
resources
|
|
34
111
|
}).then((bundles) => {
|
|
35
|
-
return Promise.all(bundles.map((bundle) => {
|
|
112
|
+
return Promise.all(bundles.map(({bundle, sourceMap}) => {
|
|
36
113
|
if (taskUtil) {
|
|
37
114
|
taskUtil.setTag(bundle, taskUtil.STANDARD_TAGS.IsBundle);
|
|
115
|
+
if (sourceMap) {
|
|
116
|
+
// Clear tag that might have been set by the minify task, in cases where
|
|
117
|
+
// the bundle name is identical to a source file
|
|
118
|
+
taskUtil.clearTag(sourceMap, taskUtil.STANDARD_TAGS.OmitFromBuildResult);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
const writes = [workspace.write(bundle)];
|
|
122
|
+
if (sourceMap) {
|
|
123
|
+
writes.push(workspace.write(sourceMap));
|
|
38
124
|
}
|
|
39
|
-
return
|
|
125
|
+
return Promise.all(writes);
|
|
40
126
|
}));
|
|
41
127
|
});
|
|
42
128
|
});
|
|
@@ -28,13 +28,20 @@ const {negateFilters} = require("../../lbt/resources/ResourceFilterList");
|
|
|
28
28
|
module.exports = function({
|
|
29
29
|
workspace, dependencies, taskUtil, options: {projectName, paths, namespaces, excludes = []}
|
|
30
30
|
}) {
|
|
31
|
-
|
|
31
|
+
let combo = new ReaderCollectionPrioritized({
|
|
32
32
|
name: `generateComponentPreload - prioritize workspace over dependencies: ${projectName}`,
|
|
33
33
|
readers: [workspace, dependencies]
|
|
34
34
|
});
|
|
35
35
|
|
|
36
|
+
if (taskUtil) {
|
|
37
|
+
combo = combo.filter(function(resource) {
|
|
38
|
+
// Remove any debug variants
|
|
39
|
+
return !taskUtil.getTag(resource, taskUtil.STANDARD_TAGS.IsDebugVariant);
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
|
|
36
43
|
// TODO 3.0: Limit to workspace resources?
|
|
37
|
-
return combo.byGlob("/resources/**/*.{js,json,xml,html,properties,library}")
|
|
44
|
+
return combo.byGlob("/resources/**/*.{js,json,xml,html,properties,library,js.map}")
|
|
38
45
|
.then(async (resources) => {
|
|
39
46
|
let allNamespaces = [];
|
|
40
47
|
if (paths) {
|
|
@@ -141,12 +148,19 @@ module.exports = function({
|
|
|
141
148
|
});
|
|
142
149
|
}));
|
|
143
150
|
})
|
|
144
|
-
.then((
|
|
145
|
-
|
|
151
|
+
.then((results) => {
|
|
152
|
+
const bundles = Array.prototype.concat.apply([], results);
|
|
153
|
+
return Promise.all(bundles.map(({bundle, sourceMap}) => {
|
|
146
154
|
if (taskUtil) {
|
|
147
|
-
taskUtil.setTag(
|
|
155
|
+
taskUtil.setTag(bundle, taskUtil.STANDARD_TAGS.IsBundle);
|
|
156
|
+
// Clear tag that might have been set by the minify task, in cases where
|
|
157
|
+
// the bundle name is identical to a source file
|
|
158
|
+
taskUtil.clearTag(sourceMap, taskUtil.STANDARD_TAGS.OmitFromBuildResult);
|
|
148
159
|
}
|
|
149
|
-
return
|
|
160
|
+
return Promise.all([
|
|
161
|
+
workspace.write(bundle),
|
|
162
|
+
workspace.write(sourceMap)
|
|
163
|
+
]);
|
|
150
164
|
}));
|
|
151
165
|
});
|
|
152
166
|
};
|