@ui5/builder 3.0.0-alpha.2 → 3.0.0-alpha.5
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 +32 -2
- package/lib/builder/BuildContext.js +6 -2
- package/lib/builder/ProjectBuildContext.js +4 -0
- package/lib/builder/builder.js +8 -2
- package/lib/lbt/resources/LocatorResource.js +0 -4
- package/lib/lbt/resources/LocatorResourcePool.js +1 -1
- package/lib/processors/bundlers/moduleBundler.js +4 -3
- package/lib/processors/minifier.js +3 -2
- package/lib/tasks/TaskUtil.js +12 -0
- package/lib/tasks/bundlers/generateBundle.js +10 -28
- package/lib/tasks/bundlers/generateLibraryPreload.js +6 -18
- package/lib/tasks/bundlers/generateStandaloneAppBundle.js +6 -18
- package/lib/tasks/bundlers/utils/createModuleNameMapping.js +30 -0
- package/lib/tasks/generateThemeDesignerResources.js +110 -0
- package/lib/tasks/minify.js +3 -1
- package/lib/types/application/ApplicationBuilder.js +21 -21
- package/lib/types/library/LibraryBuilder.js +20 -19
- package/lib/types/themeLibrary/ThemeLibraryBuilder.js +2 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,10 +2,37 @@
|
|
|
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-alpha.
|
|
5
|
+
A list of unreleased changes can be found [here](https://github.com/SAP/ui5-builder/compare/v3.0.0-alpha.5...HEAD).
|
|
6
|
+
|
|
7
|
+
<a name="v3.0.0-alpha.5"></a>
|
|
8
|
+
## [v3.0.0-alpha.5] - 2022-04-14
|
|
9
|
+
### Bug Fixes
|
|
10
|
+
- **LibraryBuilder:** Align task order of "generateComponentPreload" [`aea061d`](https://github.com/SAP/ui5-builder/commit/aea061d9d6c2ac0c11484dcc08bdcda23ab62986)
|
|
11
|
+
|
|
12
|
+
### Features
|
|
13
|
+
- **generateThemeDesignerResources task:** Create css_variables.less ([#730](https://github.com/SAP/ui5-builder/issues/730)) [`34e69be`](https://github.com/SAP/ui5-builder/commit/34e69be95fc8ec1961b24b7e2580c2c993d814d3)
|
|
14
|
+
|
|
15
|
+
### BREAKING CHANGE
|
|
16
|
+
|
|
17
|
+
For library projects, the task "generateComponentPreload" is now
|
|
18
|
+
executed after tasks "generateLibraryManifest" and
|
|
19
|
+
"generateManifestBundle" instead of before them.
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
<a name="v3.0.0-alpha.4"></a>
|
|
23
|
+
## [v3.0.0-alpha.4] - 2022-04-05
|
|
24
|
+
### Features
|
|
25
|
+
- **builder:** Add cssVariables option ([#728](https://github.com/SAP/ui5-builder/issues/728)) [`30d58e1`](https://github.com/SAP/ui5-builder/commit/30d58e1081c1bdc665f13952ecbe5c400b5f4ed7)
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
<a name="v3.0.0-alpha.3"></a>
|
|
29
|
+
## [v3.0.0-alpha.3] - 2022-03-10
|
|
30
|
+
### Bug Fixes
|
|
31
|
+
- **LocatorResourcePool:** Wait for resources in prepare step ([#719](https://github.com/SAP/ui5-builder/issues/719)) [`1b7f93f`](https://github.com/SAP/ui5-builder/commit/1b7f93f4988340d7a6575be3191a02e6c295ebd0)
|
|
32
|
+
|
|
6
33
|
|
|
7
34
|
<a name="v3.0.0-alpha.2"></a>
|
|
8
|
-
## [v3.0.0-alpha.2] - 2022-02-
|
|
35
|
+
## [v3.0.0-alpha.2] - 2022-02-25
|
|
9
36
|
### Bug Fixes
|
|
10
37
|
- **XMLTemplateAnalyzer:** Analyze core:require of FragmentDefinition [`af075ed`](https://github.com/SAP/ui5-builder/commit/af075edf784d9f1ba162a34f0bf150dbcbc0f479)
|
|
11
38
|
|
|
@@ -687,6 +714,9 @@ to load the custom bundle file instead.
|
|
|
687
714
|
- Add ability to configure component preloads and custom bundles [`2241e5f`](https://github.com/SAP/ui5-builder/commit/2241e5ff98fd95f1f80cc74959655ae7a9c660e7)
|
|
688
715
|
|
|
689
716
|
|
|
717
|
+
[v3.0.0-alpha.5]: https://github.com/SAP/ui5-builder/compare/v3.0.0-alpha.4...v3.0.0-alpha.5
|
|
718
|
+
[v3.0.0-alpha.4]: https://github.com/SAP/ui5-builder/compare/v3.0.0-alpha.3...v3.0.0-alpha.4
|
|
719
|
+
[v3.0.0-alpha.3]: https://github.com/SAP/ui5-builder/compare/v3.0.0-alpha.2...v3.0.0-alpha.3
|
|
690
720
|
[v3.0.0-alpha.2]: https://github.com/SAP/ui5-builder/compare/v3.0.0-alpha.1...v3.0.0-alpha.2
|
|
691
721
|
[v3.0.0-alpha.1]: https://github.com/SAP/ui5-builder/compare/v3.0.0-alpha.0...v3.0.0-alpha.1
|
|
692
722
|
[v3.0.0-alpha.0]: https://github.com/SAP/ui5-builder/compare/v2.11.2...v3.0.0-alpha.0
|
|
@@ -15,22 +15,26 @@ const GLOBAL_TAGS = Object.freeze({
|
|
|
15
15
|
* @memberof module:@ui5/builder.builder
|
|
16
16
|
*/
|
|
17
17
|
class BuildContext {
|
|
18
|
-
constructor({rootProject}) {
|
|
18
|
+
constructor({rootProject, options = {}}) {
|
|
19
19
|
if (!rootProject) {
|
|
20
20
|
throw new Error(`Missing parameter 'rootProject'`);
|
|
21
21
|
}
|
|
22
22
|
this.rootProject = rootProject;
|
|
23
23
|
this.projectBuildContexts = [];
|
|
24
|
-
|
|
25
24
|
this._resourceTagCollection = new ResourceTagCollection({
|
|
26
25
|
allowedTags: Object.values(GLOBAL_TAGS)
|
|
27
26
|
});
|
|
27
|
+
this.options = options;
|
|
28
28
|
}
|
|
29
29
|
|
|
30
30
|
getRootProject() {
|
|
31
31
|
return this.rootProject;
|
|
32
32
|
}
|
|
33
33
|
|
|
34
|
+
getOption(key) {
|
|
35
|
+
return this.options[key];
|
|
36
|
+
}
|
|
37
|
+
|
|
34
38
|
createProjectContext({project, resources}) {
|
|
35
39
|
const projectBuildContext = new ProjectBuildContext({
|
|
36
40
|
buildContext: this,
|
package/lib/builder/builder.js
CHANGED
|
@@ -224,6 +224,7 @@ module.exports = {
|
|
|
224
224
|
* @param {boolean} [parameters.dev=false]
|
|
225
225
|
* Decides whether a development build should be activated (skips non-essential and time-intensive tasks)
|
|
226
226
|
* @param {boolean} [parameters.selfContained=false] Flag to activate self contained build
|
|
227
|
+
* @param {boolean} [parameters.cssVariables=false] Flag to activate CSS variables generation
|
|
227
228
|
* @param {boolean} [parameters.jsdoc=false] Flag to activate JSDoc build
|
|
228
229
|
* @param {Array.<string>} [parameters.includedTasks=[]] List of tasks to be included
|
|
229
230
|
* @param {Array.<string>} [parameters.excludedTasks=[]] List of tasks to be excluded.
|
|
@@ -234,7 +235,7 @@ module.exports = {
|
|
|
234
235
|
async build({
|
|
235
236
|
tree, destPath, cleanDest = false,
|
|
236
237
|
buildDependencies = false, includedDependencies = [], excludedDependencies = [],
|
|
237
|
-
dev = false, selfContained = false, jsdoc = false,
|
|
238
|
+
dev = false, selfContained = false, cssVariables = false, jsdoc = false,
|
|
238
239
|
includedTasks = [], excludedTasks = [], devExcludeProject = []
|
|
239
240
|
}) {
|
|
240
241
|
const startTime = process.hrtime();
|
|
@@ -249,7 +250,12 @@ module.exports = {
|
|
|
249
250
|
virBasePath: "/"
|
|
250
251
|
});
|
|
251
252
|
|
|
252
|
-
const buildContext = new BuildContext({
|
|
253
|
+
const buildContext = new BuildContext({
|
|
254
|
+
rootProject: tree,
|
|
255
|
+
options: {
|
|
256
|
+
cssVariables: cssVariables
|
|
257
|
+
}
|
|
258
|
+
});
|
|
253
259
|
const cleanupSigHooks = registerCleanupSigHooks(buildContext);
|
|
254
260
|
|
|
255
261
|
const projects = {}; // Unique project index to prevent building the same project multiple times
|
|
@@ -1,9 +1,5 @@
|
|
|
1
1
|
const Resource = require("./Resource");
|
|
2
2
|
|
|
3
|
-
// function extractName(path) {
|
|
4
|
-
// return path.slice( "/resources/".length);
|
|
5
|
-
// }
|
|
6
|
-
|
|
7
3
|
class LocatorResource extends Resource {
|
|
8
4
|
constructor(pool, resource, moduleName) {
|
|
9
5
|
super(pool, moduleName, null, resource.getStatInfo());
|
|
@@ -10,7 +10,7 @@ class LocatorResourcePool extends ResourcePool {
|
|
|
10
10
|
if (!moduleName) {
|
|
11
11
|
moduleName = resource.getPath().slice("/resources/".length);
|
|
12
12
|
}
|
|
13
|
-
this.addResource(new LocatorResource(this, resource, moduleName));
|
|
13
|
+
return this.addResource(new LocatorResource(this, resource, moduleName));
|
|
14
14
|
}).filter(Boolean)
|
|
15
15
|
);
|
|
16
16
|
}
|
|
@@ -90,8 +90,7 @@ const log = require("@ui5/logger").getLogger("builder:processors:bundlers:module
|
|
|
90
90
|
* @public
|
|
91
91
|
* @typedef {object} ModuleBundleOptions
|
|
92
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
|
+
* @property {boolean} [sourceMap=true] Whether to generate a source map file for the bundle
|
|
95
94
|
* @property {boolean} [decorateBootstrapModule=false] If set to 'false', the module won't be decorated
|
|
96
95
|
* with an optimization marker
|
|
97
96
|
* @property {boolean} [addTryCatchRestartWrapper=false] Whether to wrap bootable module bundles with
|
|
@@ -124,12 +123,14 @@ const log = require("@ui5/logger").getLogger("builder:processors:bundlers:module
|
|
|
124
123
|
Optional mapping of resource paths to module name in order to overwrite the default determination
|
|
125
124
|
* @param {ModuleBundleDefinition} parameters.options.bundleDefinition Module bundle definition
|
|
126
125
|
* @param {ModuleBundleOptions} [parameters.options.bundleOptions] Module bundle options
|
|
127
|
-
* @returns {Promise<module:@ui5/builder.processors.
|
|
126
|
+
* @returns {Promise<module:@ui5/builder.processors.ModuleBundlerResult[]>}
|
|
127
|
+
* Promise resolving with module bundle resources
|
|
128
128
|
*/
|
|
129
129
|
module.exports = function({resources, options: {bundleDefinition, bundleOptions, moduleNameMapping}}) {
|
|
130
130
|
// Apply defaults without modifying the passed object
|
|
131
131
|
bundleOptions = Object.assign({}, {
|
|
132
132
|
optimize: true,
|
|
133
|
+
sourceMap: true,
|
|
133
134
|
decorateBootstrapModule: false,
|
|
134
135
|
addTryCatchRestartWrapper: false,
|
|
135
136
|
usePredefineCalls: false,
|
|
@@ -34,12 +34,13 @@ const debugFileRegex = /((?:\.view|\.fragment|\.controller|\.designtime|\.suppor
|
|
|
34
34
|
* @alias module:@ui5/builder.processors.minifier
|
|
35
35
|
* @param {object} parameters Parameters
|
|
36
36
|
* @param {module:@ui5/fs.Resource[]} parameters.resources List of resources to be processed
|
|
37
|
-
* @param {
|
|
37
|
+
* @param {object} [parameters.options] Options
|
|
38
|
+
* @param {boolean} [parameters.options.addSourceMappingUrl=true]
|
|
38
39
|
* Whether to add a sourceMappingURL reference to the end of the minified resource
|
|
39
40
|
* @returns {Promise<module:@ui5/builder.processors.MinifierResult[]>}
|
|
40
41
|
* Promise resolving with object of resource, dbgResource and sourceMap
|
|
41
42
|
*/
|
|
42
|
-
module.exports = async function({resources, addSourceMappingUrl = true}) {
|
|
43
|
+
module.exports = async function({resources, options: {addSourceMappingUrl = true} = {}}) {
|
|
43
44
|
return Promise.all(resources.map(async (resource) => {
|
|
44
45
|
const dbgPath = resource.getPath().replace(debugFileRegex, "-dbg$1");
|
|
45
46
|
const dbgResource = await resource.clone();
|
package/lib/tasks/TaskUtil.js
CHANGED
|
@@ -108,6 +108,18 @@ class TaskUtil {
|
|
|
108
108
|
return this._projectBuildContext.isRootProject();
|
|
109
109
|
}
|
|
110
110
|
|
|
111
|
+
/**
|
|
112
|
+
* Retrieves a build option defined by its <code>key</code.
|
|
113
|
+
* If no option with the given <code>key</code> is stored, <code>undefined</code> is returned.
|
|
114
|
+
*
|
|
115
|
+
* @param {string} key The option key
|
|
116
|
+
* @returns {any|undefined} The build option (or undefined)
|
|
117
|
+
* @private
|
|
118
|
+
*/
|
|
119
|
+
getBuildOption(key) {
|
|
120
|
+
return this._projectBuildContext.getOption(key);
|
|
121
|
+
}
|
|
122
|
+
|
|
111
123
|
/**
|
|
112
124
|
* Register a function that must be executed once the build is finished. This can be used to, for example,
|
|
113
125
|
* clean up files temporarily created on the file system. If the callback returns a Promise, it will be waited for.
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
const moduleBundler = require("../../processors/bundlers/moduleBundler");
|
|
2
|
-
const
|
|
2
|
+
const createModuleNameMapping = require("./utils/createModuleNameMapping");
|
|
3
3
|
const ReaderCollectionPrioritized = require("@ui5/fs").ReaderCollectionPrioritized;
|
|
4
4
|
|
|
5
5
|
/**
|
|
@@ -21,7 +21,7 @@ module.exports = function({
|
|
|
21
21
|
workspace, dependencies, taskUtil, options: {projectName, bundleDefinition, bundleOptions}
|
|
22
22
|
}) {
|
|
23
23
|
let combo = new ReaderCollectionPrioritized({
|
|
24
|
-
name: `
|
|
24
|
+
name: `generateBundle - prioritize workspace over dependencies: ${projectName}`,
|
|
25
25
|
readers: [workspace, dependencies]
|
|
26
26
|
});
|
|
27
27
|
|
|
@@ -82,34 +82,16 @@ module.exports = function({
|
|
|
82
82
|
}
|
|
83
83
|
|
|
84
84
|
return combo.byGlob("/resources/**/*.{js,json,xml,html,properties,library,js.map}").then((resources) => {
|
|
85
|
-
const
|
|
85
|
+
const options = {bundleDefinition, bundleOptions};
|
|
86
86
|
if (!optimize && taskUtil) {
|
|
87
|
-
|
|
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
|
-
}
|
|
87
|
+
options.moduleNameMapping = createModuleNameMapping({resources, taskUtil});
|
|
103
88
|
}
|
|
104
|
-
return moduleBundler({
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
resources
|
|
111
|
-
}).then((bundles) => {
|
|
112
|
-
return Promise.all(bundles.map(({bundle, sourceMap}) => {
|
|
89
|
+
return moduleBundler({options, resources}).then((bundles) => {
|
|
90
|
+
return Promise.all(bundles.map(({bundle, sourceMap} = {}) => {
|
|
91
|
+
if (!bundle) {
|
|
92
|
+
// Skip empty bundles
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
113
95
|
if (taskUtil) {
|
|
114
96
|
taskUtil.setTag(bundle, taskUtil.STANDARD_TAGS.IsBundle);
|
|
115
97
|
if (sourceMap) {
|
|
@@ -2,7 +2,7 @@ const log = require("@ui5/logger").getLogger("builder:tasks:bundlers:generateLib
|
|
|
2
2
|
const moduleBundler = require("../../processors/bundlers/moduleBundler");
|
|
3
3
|
const ReaderCollectionPrioritized = require("@ui5/fs").ReaderCollectionPrioritized;
|
|
4
4
|
const {negateFilters} = require("../../lbt/resources/ResourceFilterList");
|
|
5
|
-
const
|
|
5
|
+
const createModuleNameMapping = require("./utils/createModuleNameMapping");
|
|
6
6
|
|
|
7
7
|
function getDefaultLibraryPreloadFilters(namespace, excludes) {
|
|
8
8
|
const filters = [
|
|
@@ -311,7 +311,7 @@ module.exports = function({workspace, dependencies, taskUtil, options: {projectN
|
|
|
311
311
|
return resource.getPath() === "/resources/ui5loader.js";
|
|
312
312
|
});
|
|
313
313
|
|
|
314
|
-
|
|
314
|
+
let unoptimizedModuleNameMapping;
|
|
315
315
|
let unoptimizedResources = resources;
|
|
316
316
|
if (taskUtil) {
|
|
317
317
|
unoptimizedResources = await new ReaderCollectionPrioritized({
|
|
@@ -322,22 +322,10 @@ module.exports = function({workspace, dependencies, taskUtil, options: {projectN
|
|
|
322
322
|
return !taskUtil.getTag(resource, taskUtil.STANDARD_TAGS.HasDebugVariant);
|
|
323
323
|
}).byGlob("/**/*.{js,json,xml,html,properties,library,js.map}");
|
|
324
324
|
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
// the module name from the resource path, which would contain "-dbg" in this case. That would be
|
|
330
|
-
// incorrect since debug-variants should still keep the original module name.
|
|
331
|
-
for (let i = unoptimizedResources.length - 1; i >= 0; i--) {
|
|
332
|
-
const resourcePath = unoptimizedResources[i].getPath();
|
|
333
|
-
if (taskUtil.getTag(resourcePath, taskUtil.STANDARD_TAGS.IsDebugVariant)) {
|
|
334
|
-
const nonDbgPath = ModuleName.getNonDebugName(resourcePath);
|
|
335
|
-
if (!nonDbgPath) {
|
|
336
|
-
throw new Error(`Failed to resolve non-debug name for ${resourcePath}`);
|
|
337
|
-
}
|
|
338
|
-
unoptimizedModuleNameMapping[resourcePath] = nonDbgPath.slice("/resources/".length);
|
|
339
|
-
}
|
|
340
|
-
}
|
|
325
|
+
unoptimizedModuleNameMapping = createModuleNameMapping({
|
|
326
|
+
resources: unoptimizedResources,
|
|
327
|
+
taskUtil
|
|
328
|
+
});
|
|
341
329
|
}
|
|
342
330
|
|
|
343
331
|
let filters;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
const log = require("@ui5/logger").getLogger("builder:tasks:bundlers:generateStandaloneAppBundle");
|
|
2
2
|
const ReaderCollectionPrioritized = require("@ui5/fs").ReaderCollectionPrioritized;
|
|
3
3
|
const moduleBundler = require("../../processors/bundlers/moduleBundler");
|
|
4
|
-
const
|
|
4
|
+
const createModuleNameMapping = require("./utils/createModuleNameMapping");
|
|
5
5
|
|
|
6
6
|
function getBundleDefinition(config) {
|
|
7
7
|
const bundleDefinition = {
|
|
@@ -101,7 +101,7 @@ module.exports = async function({workspace, dependencies, taskUtil, options: {pr
|
|
|
101
101
|
filters = ["jquery.sap.global.js"];
|
|
102
102
|
}
|
|
103
103
|
|
|
104
|
-
|
|
104
|
+
let unoptimizedModuleNameMapping;
|
|
105
105
|
let unoptimizedResources = resources;
|
|
106
106
|
if (taskUtil) {
|
|
107
107
|
unoptimizedResources = await new ReaderCollectionPrioritized({
|
|
@@ -112,22 +112,10 @@ module.exports = async function({workspace, dependencies, taskUtil, options: {pr
|
|
|
112
112
|
return !taskUtil.getTag(resource, taskUtil.STANDARD_TAGS.HasDebugVariant);
|
|
113
113
|
}).byGlob("/resources/**/*.{js,json,xml,html,properties,library,js.map}");
|
|
114
114
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
// the module name from the resource path, which would contain "-dbg" in this case. That would be
|
|
120
|
-
// incorrect since debug-variants should still keep the original module name.
|
|
121
|
-
for (let i = unoptimizedResources.length - 1; i >= 0; i--) {
|
|
122
|
-
const resourcePath = unoptimizedResources[i].getPath();
|
|
123
|
-
if (taskUtil.getTag(resourcePath, taskUtil.STANDARD_TAGS.IsDebugVariant)) {
|
|
124
|
-
const nonDbgPath = ModuleName.getNonDebugName(resourcePath);
|
|
125
|
-
if (!nonDbgPath) {
|
|
126
|
-
throw new Error(`Failed to resolve non-debug name for ${resourcePath}`);
|
|
127
|
-
}
|
|
128
|
-
unoptimizedModuleNameMapping[resourcePath] = nonDbgPath.slice("/resources/".length);
|
|
129
|
-
}
|
|
130
|
-
}
|
|
115
|
+
unoptimizedModuleNameMapping = createModuleNameMapping({
|
|
116
|
+
resources: unoptimizedResources,
|
|
117
|
+
taskUtil
|
|
118
|
+
});
|
|
131
119
|
}
|
|
132
120
|
|
|
133
121
|
await Promise.all([
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
const ModuleName = require("../../../lbt/utils/ModuleName");
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* For "unoptimized" bundles, the non-debug files have already been filtered out above.
|
|
5
|
+
* Now we need to create a mapping from the debug-variant resource path to the respective module
|
|
6
|
+
* name, which is basically the non-debug resource path, minus the "/resources/"" prefix.
|
|
7
|
+
* This mapping overwrites internal logic of the LocatorResourcePool which would otherwise determine
|
|
8
|
+
* the module name from the resource path, which would contain "-dbg" in this case. That would be
|
|
9
|
+
* incorrect since debug-variants should still keep the original module name.
|
|
10
|
+
*
|
|
11
|
+
* @private
|
|
12
|
+
* @param {object} parameters Parameters
|
|
13
|
+
* @param {module:@ui5/fs.Resource[]} parameters.resources List of resources
|
|
14
|
+
* @param {module:@ui5/builder.tasks.TaskUtil|object} parameters.taskUtil TaskUtil
|
|
15
|
+
* @returns {object} Module name mapping
|
|
16
|
+
*/
|
|
17
|
+
module.exports = function({resources, taskUtil}) {
|
|
18
|
+
const moduleNameMapping = {};
|
|
19
|
+
for (let i = resources.length - 1; i >= 0; i--) {
|
|
20
|
+
const resourcePath = resources[i].getPath();
|
|
21
|
+
if (taskUtil.getTag(resourcePath, taskUtil.STANDARD_TAGS.IsDebugVariant)) {
|
|
22
|
+
const nonDbgPath = ModuleName.getNonDebugName(resourcePath);
|
|
23
|
+
if (!nonDbgPath) {
|
|
24
|
+
throw new Error(`Failed to resolve non-debug name for ${resourcePath}`);
|
|
25
|
+
}
|
|
26
|
+
moduleNameMapping[resourcePath] = nonDbgPath.slice("/resources/".length);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
return moduleNameMapping;
|
|
30
|
+
};
|
|
@@ -3,6 +3,37 @@ const log = require("@ui5/logger").getLogger("builder:tasks:generateThemeDesigne
|
|
|
3
3
|
const libraryLessGenerator = require("../processors/libraryLessGenerator");
|
|
4
4
|
const {ReaderCollectionPrioritized, Resource, fsInterface} = require("@ui5/fs");
|
|
5
5
|
|
|
6
|
+
/**
|
|
7
|
+
* Returns a relative path from the given themeFolder to the root namespace.
|
|
8
|
+
*
|
|
9
|
+
* When combining the given themeFolder with the returned relative path it
|
|
10
|
+
* resolves to "/resources/". However the "/resources/" part is not important
|
|
11
|
+
* here as it doesn't exist within the theming engine environment where the
|
|
12
|
+
* UI5 resources are part of a "UI5" folder (e.g. "UI5/sap/ui/core/") that
|
|
13
|
+
* is next to a "Base" folder.
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* getPathToRoot("/resources/sap/ui/foo/themes/base")
|
|
17
|
+
* > "../../../../../"
|
|
18
|
+
*
|
|
19
|
+
* @param {string} themeFolder Virtual path including /resources/
|
|
20
|
+
* @returns {string} Relative path to root namespace
|
|
21
|
+
*/
|
|
22
|
+
function getPathToRoot(themeFolder) {
|
|
23
|
+
// -2 for initial "/"" and "resources/"
|
|
24
|
+
return "../".repeat(themeFolder.split("/").length - 2);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Generates an less import statement for the given <code>filePath</code>
|
|
29
|
+
*
|
|
30
|
+
* @param {string} filePath The path to the desired file
|
|
31
|
+
* @returns {string} The less import statement
|
|
32
|
+
*/
|
|
33
|
+
function lessImport(filePath) {
|
|
34
|
+
return `@import "${filePath}";\n`;
|
|
35
|
+
}
|
|
36
|
+
|
|
6
37
|
function generateLibraryDotTheming({namespace, version, hasThemes}) {
|
|
7
38
|
const dotTheming = {
|
|
8
39
|
sEntity: "Library",
|
|
@@ -80,6 +111,82 @@ async function generateThemeDotTheming({workspace, combo, themeFolder}) {
|
|
|
80
111
|
return newDotThemingResource;
|
|
81
112
|
}
|
|
82
113
|
|
|
114
|
+
async function createCssVariablesLessResource({workspace, combo, themeFolder}) {
|
|
115
|
+
const pathToRoot = getPathToRoot(themeFolder);
|
|
116
|
+
const cssVariablesSourceLessFile = "css_variables.source.less";
|
|
117
|
+
const cssVariablesLessFile = "css_variables.less";
|
|
118
|
+
|
|
119
|
+
// posix as it is a virtual path (separated with /)
|
|
120
|
+
const themeName = posixPath.basename(themeFolder);
|
|
121
|
+
// The "base" theme of the baseLib is called "baseTheme"
|
|
122
|
+
const baseLibThemeName = themeName === "base" ? "baseTheme" : themeName;
|
|
123
|
+
|
|
124
|
+
// Some themes do not have a base.less file (e.g. sap_hcb)
|
|
125
|
+
const hasBaseLess = !!(await combo.byPath(`/resources/sap/ui/core/themes/${themeName}/base.less`));
|
|
126
|
+
|
|
127
|
+
let cssVariablesLess =
|
|
128
|
+
`/* NOTE: This file was generated as an optimized version of "${cssVariablesSourceLessFile}" \
|
|
129
|
+
for the Theme Designer. */\n\n`;
|
|
130
|
+
|
|
131
|
+
if (themeName !== "base") {
|
|
132
|
+
const cssVariablesSourceLessResource = await workspace.byPath(
|
|
133
|
+
posixPath.join(themeFolder, cssVariablesSourceLessFile)
|
|
134
|
+
);
|
|
135
|
+
|
|
136
|
+
if (!cssVariablesSourceLessResource) {
|
|
137
|
+
throw new Error(`Could not find file "${cssVariablesSourceLessFile}" in theme "${themeFolder}"`);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
const cssVariablesSourceLess = await cssVariablesSourceLessResource.getString();
|
|
141
|
+
|
|
142
|
+
cssVariablesLess += lessImport(`../base/${cssVariablesLessFile}`);
|
|
143
|
+
cssVariablesLess += `
|
|
144
|
+
/* START "${cssVariablesSourceLessFile}" */
|
|
145
|
+
${cssVariablesSourceLess}
|
|
146
|
+
/* END "${cssVariablesSourceLessFile}" */
|
|
147
|
+
|
|
148
|
+
`;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
if (hasBaseLess) {
|
|
152
|
+
cssVariablesLess += lessImport(`${pathToRoot}../Base/baseLib/${baseLibThemeName}/base.less`);
|
|
153
|
+
}
|
|
154
|
+
cssVariablesLess += lessImport(`${pathToRoot}sap/ui/core/themes/${themeName}/global.less`);
|
|
155
|
+
|
|
156
|
+
return new Resource({
|
|
157
|
+
path: posixPath.join(themeFolder, cssVariablesLessFile),
|
|
158
|
+
string: cssVariablesLess
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
async function generateCssVariablesLess({workspace, combo, namespace}) {
|
|
163
|
+
let cssVariablesSourceLessResourcePattern;
|
|
164
|
+
if (namespace) {
|
|
165
|
+
// In case of a library only check for themes directly below the namespace
|
|
166
|
+
cssVariablesSourceLessResourcePattern = `/resources/${namespace}/themes/*/css_variables.source.less`;
|
|
167
|
+
} else {
|
|
168
|
+
// In case of a theme-library check for all "themes"
|
|
169
|
+
cssVariablesSourceLessResourcePattern = `/resources/**/themes/*/css_variables.source.less`;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
const cssVariablesSourceLessResource = await workspace.byGlob(cssVariablesSourceLessResourcePattern);
|
|
173
|
+
|
|
174
|
+
const hasCssVariables = cssVariablesSourceLessResource.length > 0;
|
|
175
|
+
|
|
176
|
+
if (hasCssVariables) {
|
|
177
|
+
await Promise.all(
|
|
178
|
+
cssVariablesSourceLessResource.map(async (cssVariableSourceLess) => {
|
|
179
|
+
const themeFolder = posixPath.dirname(cssVariableSourceLess.getPath());
|
|
180
|
+
log.verbose(`Generating css_variables.less for theme ${themeFolder}`);
|
|
181
|
+
const r = await createCssVariablesLessResource({
|
|
182
|
+
workspace, combo, themeFolder
|
|
183
|
+
});
|
|
184
|
+
return await workspace.write(r);
|
|
185
|
+
})
|
|
186
|
+
);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
|
|
83
190
|
/**
|
|
84
191
|
* Generates resources required for integration with the SAP Theme Designer.
|
|
85
192
|
*
|
|
@@ -163,4 +270,7 @@ module.exports = async function({workspace, dependencies, options: {projectName,
|
|
|
163
270
|
await Promise.all(
|
|
164
271
|
libraryLessResources.map((resource) => workspace.write(resource))
|
|
165
272
|
);
|
|
273
|
+
|
|
274
|
+
// css_variables.less
|
|
275
|
+
await generateCssVariablesLess({workspace, combo, namespace});
|
|
166
276
|
};
|
package/lib/tasks/minify.js
CHANGED
|
@@ -18,7 +18,9 @@ module.exports = async function({workspace, taskUtil, options: {pattern, omitSou
|
|
|
18
18
|
const resources = await workspace.byGlob(pattern);
|
|
19
19
|
const processedResources = await minifier({
|
|
20
20
|
resources,
|
|
21
|
-
|
|
21
|
+
options: {
|
|
22
|
+
addSourceMappingUrl: !omitSourceMapResources
|
|
23
|
+
}
|
|
22
24
|
});
|
|
23
25
|
|
|
24
26
|
return Promise.all(processedResources.map(async ({resource, dbgResource, sourceMapResource}) => {
|
|
@@ -43,6 +43,27 @@ class ApplicationBuilder extends AbstractBuilder {
|
|
|
43
43
|
});
|
|
44
44
|
});
|
|
45
45
|
|
|
46
|
+
// Support rules should not be minified to have readable code in the Support Assistant
|
|
47
|
+
const minificationPattern = ["/**/*.js", "!**/*.support.js"];
|
|
48
|
+
if (["2.6"].includes(project.specVersion)) {
|
|
49
|
+
const minificationExcludes = project.builder && project.builder.minification &&
|
|
50
|
+
project.builder.minification.excludes;
|
|
51
|
+
if (minificationExcludes) {
|
|
52
|
+
// TODO 3.0: namespaces should become mandatory, see existing check above
|
|
53
|
+
const patternPrefix = project.metadata.namespace ? "/resources/" : "/";
|
|
54
|
+
this.enhancePatternWithExcludes(minificationPattern, minificationExcludes, patternPrefix);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
this.addTask("minify", async () => {
|
|
58
|
+
return getTask("minify").task({
|
|
59
|
+
workspace: resourceCollections.workspace,
|
|
60
|
+
taskUtil,
|
|
61
|
+
options: {
|
|
62
|
+
pattern: minificationPattern
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
});
|
|
66
|
+
|
|
46
67
|
this.addTask("generateFlexChangesBundle", async () => {
|
|
47
68
|
const generateFlexChangesBundle = getTask("generateFlexChangesBundle").task;
|
|
48
69
|
return generateFlexChangesBundle({
|
|
@@ -67,27 +88,6 @@ class ApplicationBuilder extends AbstractBuilder {
|
|
|
67
88
|
});
|
|
68
89
|
}
|
|
69
90
|
|
|
70
|
-
// Support rules should not be minified to have readable code in the Support Assistant
|
|
71
|
-
const minificationPattern = ["/**/*.js", "!**/*.support.js"];
|
|
72
|
-
if (["2.6"].includes(project.specVersion)) {
|
|
73
|
-
const minificationExcludes = project.builder && project.builder.minification &&
|
|
74
|
-
project.builder.minification.excludes;
|
|
75
|
-
if (minificationExcludes) {
|
|
76
|
-
// TODO 3.0: namespaces should become mandatory, see existing check above
|
|
77
|
-
const patternPrefix = project.metadata.namespace ? "/resources/" : "/";
|
|
78
|
-
this.enhancePatternWithExcludes(minificationPattern, minificationExcludes, patternPrefix);
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
this.addTask("minify", async () => {
|
|
82
|
-
return getTask("minify").task({
|
|
83
|
-
workspace: resourceCollections.workspace,
|
|
84
|
-
taskUtil,
|
|
85
|
-
options: {
|
|
86
|
-
pattern: minificationPattern
|
|
87
|
-
}
|
|
88
|
-
});
|
|
89
|
-
});
|
|
90
|
-
|
|
91
91
|
const componentPreload = project.builder && project.builder.componentPreload;
|
|
92
92
|
if (componentPreload && (componentPreload.namespaces || componentPreload.paths)) {
|
|
93
93
|
this.addTask("generateComponentPreload", async () => {
|
|
@@ -38,7 +38,7 @@ class LibraryBuilder extends AbstractBuilder {
|
|
|
38
38
|
workspace: resourceCollections.workspace,
|
|
39
39
|
options: {
|
|
40
40
|
version: project.version,
|
|
41
|
-
pattern: "/**/*.{js,json,library,less,theme,html}"
|
|
41
|
+
pattern: "/**/*.{js,json,library,css,less,theme,html}"
|
|
42
42
|
}
|
|
43
43
|
});
|
|
44
44
|
});
|
|
@@ -109,23 +109,6 @@ class LibraryBuilder extends AbstractBuilder {
|
|
|
109
109
|
});
|
|
110
110
|
});
|
|
111
111
|
|
|
112
|
-
const componentPreload = project.builder && project.builder.componentPreload;
|
|
113
|
-
if (componentPreload) {
|
|
114
|
-
this.addTask("generateComponentPreload", async () => {
|
|
115
|
-
return getTask("generateComponentPreload").task({
|
|
116
|
-
workspace: resourceCollections.workspace,
|
|
117
|
-
dependencies: resourceCollections.dependencies,
|
|
118
|
-
taskUtil,
|
|
119
|
-
options: {
|
|
120
|
-
projectName: project.metadata.name,
|
|
121
|
-
paths: componentPreload.paths,
|
|
122
|
-
namespaces: componentPreload.namespaces,
|
|
123
|
-
excludes: componentPreload.excludes
|
|
124
|
-
}
|
|
125
|
-
});
|
|
126
|
-
});
|
|
127
|
-
}
|
|
128
|
-
|
|
129
112
|
this.addTask("generateLibraryManifest", async () => {
|
|
130
113
|
return getTask("generateLibraryManifest").task({
|
|
131
114
|
workspace: resourceCollections.workspace,
|
|
@@ -150,6 +133,23 @@ class LibraryBuilder extends AbstractBuilder {
|
|
|
150
133
|
});
|
|
151
134
|
}
|
|
152
135
|
|
|
136
|
+
const componentPreload = project.builder && project.builder.componentPreload;
|
|
137
|
+
if (componentPreload) {
|
|
138
|
+
this.addTask("generateComponentPreload", async () => {
|
|
139
|
+
return getTask("generateComponentPreload").task({
|
|
140
|
+
workspace: resourceCollections.workspace,
|
|
141
|
+
dependencies: resourceCollections.dependencies,
|
|
142
|
+
taskUtil,
|
|
143
|
+
options: {
|
|
144
|
+
projectName: project.metadata.name,
|
|
145
|
+
paths: componentPreload.paths,
|
|
146
|
+
namespaces: componentPreload.namespaces,
|
|
147
|
+
excludes: componentPreload.excludes
|
|
148
|
+
}
|
|
149
|
+
});
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
|
|
153
153
|
this.addTask("generateLibraryPreload", async () => {
|
|
154
154
|
return getTask("generateLibraryPreload").task({
|
|
155
155
|
workspace: resourceCollections.workspace,
|
|
@@ -198,7 +198,8 @@ class LibraryBuilder extends AbstractBuilder {
|
|
|
198
198
|
projectName: project.metadata.name,
|
|
199
199
|
librariesPattern: !taskUtil.isRootProject() ? "/resources/**/(*.library|library.js)" : undefined,
|
|
200
200
|
themesPattern: !taskUtil.isRootProject() ? "/resources/sap/ui/core/themes/*" : undefined,
|
|
201
|
-
inputPattern
|
|
201
|
+
inputPattern,
|
|
202
|
+
cssVariables: taskUtil.getBuildOption("cssVariables")
|
|
202
203
|
}
|
|
203
204
|
});
|
|
204
205
|
});
|
|
@@ -31,7 +31,8 @@ class ThemeLibraryBuilder extends AbstractBuilder {
|
|
|
31
31
|
projectName: project.metadata.name,
|
|
32
32
|
librariesPattern: !taskUtil.isRootProject() ? "/resources/**/(*.library|library.js)" : undefined,
|
|
33
33
|
themesPattern: !taskUtil.isRootProject() ? "/resources/sap/ui/core/themes/*" : undefined,
|
|
34
|
-
inputPattern: "/resources/**/themes/*/library.source.less"
|
|
34
|
+
inputPattern: "/resources/**/themes/*/library.source.less",
|
|
35
|
+
cssVariables: taskUtil.getBuildOption("cssVariables")
|
|
35
36
|
}
|
|
36
37
|
});
|
|
37
38
|
});
|