Skip to content

Commit

Permalink
[FEATURE] Add ability to configure component preloads and custom bundles
Browse files Browse the repository at this point in the history
- lbt: Ignore missing manifest.json errors
- moduleBundler: Add parameter for custom bundle options
- Use /resources as base for all bundle globs
  • Loading branch information
devtomtom committed May 9, 2018
1 parent d34a3b2 commit 2241e5f
Show file tree
Hide file tree
Showing 81 changed files with 949 additions and 109 deletions.
3 changes: 2 additions & 1 deletion index.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,12 @@ const ui5Builder = {
versionInfoGenerator: require("./lib/processors/versionInfoGenerator")
},
tasks: {
generateAppPreload: require("./lib/tasks/bundlers/generateAppPreload"),
generateComponentPreload: require("./lib/tasks/bundlers/generateComponentPreload"),
generateFlexChangesBundle: require("./lib/tasks/bundlers/generateFlexChangesBundle"),
generateLibraryPreload: require("./lib/tasks/bundlers/generateLibraryPreload"),
generateManifestBundle: require("./lib/tasks/bundlers/generateManifestBundle"),
generateStandaloneAppBundle: require("./lib/tasks/bundlers/generateStandaloneAppBundle"),
generateBundle: require("./lib/tasks/bundlers/generateBundle"),
buildThemes: require("./lib/tasks/buildThemes"),
createDebugFiles: require("./lib/tasks/createDebugFiles"),
generateVersionInfo: require("./lib/tasks/generateVersionInfo"),
Expand Down
5 changes: 3 additions & 2 deletions lib/builder/builder.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,9 @@ const definedTasks = {
generateVersionInfo: require("../tasks/generateVersionInfo"),
generateManifestBundle: require("../tasks/bundlers/generateManifestBundle"),
generateFlexChangesBundle: require("../tasks/bundlers/generateFlexChangesBundle"),
generateAppPreload: require("../tasks/bundlers/generateAppPreload"),
generateComponentPreload: require("../tasks/bundlers/generateComponentPreload"),
generateStandaloneAppBundle: require("../tasks/bundlers/generateStandaloneAppBundle"),
generateBundle: require("../tasks/bundlers/generateBundle"),
generateLibraryPreload: require("../tasks/bundlers/generateLibraryPreload")
};

Expand Down Expand Up @@ -182,7 +183,7 @@ function composeTaskList({dev, selfContained, includedTasks, excludedTasks}) {

if (selfContained) {
// No preloads, bundle only
selectedTasks.generateAppPreload = false;
selectedTasks.generateComponentPreload = false;
selectedTasks.generateStandaloneAppBundle = true;
selectedTasks.generateLibraryPreload = false;
}
Expand Down
6 changes: 3 additions & 3 deletions lib/lbt/analyzer/ComponentAnalyzer.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,12 +50,12 @@ class ComponentAnalyzer {
}

let manifestName = resource.name.replace(/Component\.js$/, "manifest.json");
let manifestResource = await this._pool.findResource(manifestName);
let fileContent = await manifestResource.buffer();
try {
let manifestResource = await this._pool.findResource(manifestName);
let fileContent = await manifestResource.buffer();
this._analyzeManifest( JSON.parse(fileContent.toString()), info );
} catch (err) {
// ignore
log.error("an error occurred while analyzing component %s (ignored)", resource.name, err);
}

return info;
Expand Down
4 changes: 2 additions & 2 deletions lib/lbt/analyzer/FioriElementsAnalyzer.js
Original file line number Diff line number Diff line change
Expand Up @@ -94,9 +94,9 @@ class FioriElementsAnalyzer {
}

let manifestName = resource.name.replace(/Component\.js$/, "manifest.json");
let manifestResource = await this._pool.findResource(manifestName);
let fileContent = await manifestResource.buffer();
try {
let manifestResource = await this._pool.findResource(manifestName);
let fileContent = await manifestResource.buffer();
await this._analyzeManifest( JSON.parse(fileContent.toString()), info );
} catch (err) {
log.error("an error occurred while analyzing template app %s (ignored)", resource.name, err);
Expand Down
4 changes: 2 additions & 2 deletions lib/lbt/analyzer/SmartTemplateAnalyzer.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,9 @@ class TemplateComponentAnalyzer {
}

let manifestName = resource.name.replace(/Component\.js$/, "manifest.json");
let manifestResource = await this._pool.findResource(manifestName);
let fileContent = await manifestResource.buffer();
try {
let manifestResource = await this._pool.findResource(manifestName);
let fileContent = await manifestResource.buffer();
await this._analyzeManifest( JSON.parse(fileContent.toString()), info );
} catch (err) {
log.error("an error occurred while analyzing template app %s (ignored)", resource.name, err);
Expand Down
33 changes: 21 additions & 12 deletions lib/processors/bundlers/moduleBundler.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,8 @@ class LocatorResourcePool extends ResourcePool {
* @param {Object} parameters Parameters
* @param {Resource[]} parameters.resources Resources
* @param {Object} parameters.options Options
* @param {string} parameters.options.bundleDefinition Module bundle definition
* @param {Object} parameters.options.bundleDefinition Module bundle definition
* @param {Object} parameters.options.bundleOptions Module bundle options
* @returns {Promise<Resource[]>} Promise resolving with module bundle resources
*/
module.exports = function({resources, options}) {
Expand All @@ -54,17 +55,25 @@ module.exports = function({resources, options}) {
const pool = new LocatorResourcePool();
const builder = new BundleBuilder(pool);

const bundleOptions = options.bundleOptions || {optimize: true};

return pool.prepare( resources ).
then( () => builder.createBundle(options.bundleDefinition, {optimize: true}) ).
then( ({name, content, bundleInfo}) => {
// console.log("creating bundle as '%s'", "/resources/" + name);
const resource = new EvoResource({
path: "/resources/" + name,
string: content
});
return [resource];
// return source.write(resource).then(
// () => ({name, content, bundleInfo})
// );
then( () => builder.createBundle(options.bundleDefinition, bundleOptions) ).
then( (results) => {
let bundles;
if (results instanceof Array) {
bundles = results;
} else {
bundles = [results];
}

return Promise.all(bundles.map(function({name, content, bundleInfo}) {
console.log("creating bundle as '%s'", "/resources/" + name);
const resource = new EvoResource({
path: "/resources/" + name,
string: content
});
return resource;
}));
});
};
50 changes: 0 additions & 50 deletions lib/tasks/bundlers/generateAppPreload.js

This file was deleted.

36 changes: 36 additions & 0 deletions lib/tasks/bundlers/generateBundle.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
const moduleBundler = require("../../processors/bundlers/moduleBundler");
const ReaderCollectionPrioritized = require("@ui5/fs").ReaderCollectionPrioritized;

/**
* Generates a bundle based on the given bundle definition
*
* @module builder/tasks/bundlers/generateBundle
* @param {Object} parameters Parameters
* @param {DuplexCollection} parameters.workspace DuplexCollection to read and write files
* @param {Collection} parameters.dependencies Collection to read dependency files
* @param {Object} parameters.options Options
* @param {string} parameters.options.projectName Project name
* @param {Object} parameters.options.bundleDefintion Module bundle definition
* @param {Object} parameters.options.bundleOptions Module bundle options
* @returns {Promise} Promise resolving with undefined once data has been written
*/
module.exports = function({workspace, dependencies, options}) {
const combo = new ReaderCollectionPrioritized({
name: `libraryBundler - prioritize workspace over dependencies: ${options.projectName}`,
readers: [workspace, dependencies]
});

return combo.byGlob("/resources/**/*.{js,json,xml,html,properties,library}").then((resources) => {
return moduleBundler({
options: {
bundleDefinition: options.bundleDefinition,
bundleOptions: options.bundleOptions
},
resources
}).then((bundles) => {
bundles.forEach((bundle) => {
workspace.write(bundle);
});
});
});
};
86 changes: 86 additions & 0 deletions lib/tasks/bundlers/generateComponentPreload.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
const path = require("path");
const moduleBundler = require("../../processors/bundlers/moduleBundler");
const ReaderCollectionPrioritized = require("@ui5/fs").ReaderCollectionPrioritized;

/**
* Task to for application bundling.
*
* @module builder/tasks/bundlers/generateComponentPreload
* @param {Object} parameters Parameters
* @param {DuplexCollection} parameters.workspace DuplexCollection to read and write files
* @param {AbstractReader} parameters.dependencies Reader or Collection to read dependency files
* @param {Object} parameters.options Options
* @param {string} parameters.options.projectName Project name
* @param {Array} parameters.options.paths Array of paths (or glob patterns) for component files
* @param {Array} parameters.options.namespaces Array of component namespaces
* @returns {Promise<undefined>} Promise resolving with <code>undefined</code> once data has been written
*/
module.exports = function({workspace, dependencies, options}) {
const combo = new ReaderCollectionPrioritized({
name: `generateComponentPreload - prioritize workspace over dependencies: ${options.projectName}`,
readers: [workspace, dependencies]
});

return combo.byGlob("/resources/**/*.{js,json,xml,html,properties,library}")
.then(async (resources) => {
let namespaces = [];
if (options.paths) {
namespaces = await Promise.all(options.paths.map(async (componentPath) => {
const components = await combo.byGlob("/resources/" + componentPath);
return components.map((component) => {
console.log(component.getPath());
console.log(path.dirname(component.getPath()));
return path.dirname(component.getPath()).replace(/^\/resources\//i, "");
});
}));
}
if (options.namespaces) {
namespaces.push(...options.namespaces);
}

namespaces = Array.prototype.concat.apply([], namespaces);
if (!namespaces || !namespaces.length) {
throw new Error("generateComponentPreload: No component namespace(s) " +
`found for project: ${options.projectName}`);
}

return Promise.all(namespaces.map((namespace) => {
var filters = [
`${namespace}/`,
`!${namespace}/test/`,
`!${namespace}/*.html`
];

// Exclude other namespaces
namespaces.forEach((ns) => {
if (ns !== namespace && ns.indexOf(namespace) === 0) {
filters.push(`!${ns}/`);
}
});

return moduleBundler({
resources,
options: {
bundleDefinition: {
name: `${namespace}/Component-preload.js`,
defaultFileTypes: [".js", ".fragment.xml", ".view.xml", ".properties", ".json"],
sections: [
{
mode: "preload",
filters: filters,
resolve: false,
resolveConditional: false,
renderer: false
}
]
}
}
});
}));
})
.then((processedResources) => {
return Promise.all(processedResources.map((resource) => {
return workspace.write(resource[0]);
}));
});
};
3 changes: 2 additions & 1 deletion lib/tasks/bundlers/generateStandaloneAppBundle.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ const ReaderCollectionPrioritized = require("@ui5/fs").ReaderCollectionPrioritiz
* @param {DuplexCollection} parameters.workspace DuplexCollection to read and write files
* @param {AbstractReader} parameters.dependencies Reader or Collection to read dependency files
* @param {Object} parameters.options Options
* @param {string} parameters.options.projectName Project name
* @param {string} parameters.options.namespace Project namespace
* @returns {Promise<undefined>} Promise resolving with <code>undefined</code> once data has been written
*/
Expand All @@ -17,7 +18,7 @@ module.exports = function({workspace, dependencies, options}) {
name: `appBundlerStandalone - prioritize workspace over dependencies: ${options.projectName}`,
readers: [workspace, dependencies]
});
return combo.byGlob("/**/*.{js,json,xml,html,properties,library}")
return combo.byGlob("/resources/**/*.{js,json,xml,html,properties,library}")
.then((resources) => {
const isEvo = resources.find((resource) => {
return resource.getPath() === "/resources/ui5loader.js";
Expand Down
6 changes: 5 additions & 1 deletion lib/types/AbstractBuilder.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,11 @@ class AbstractBuilder {
continue;
}

taskChain = taskChain.then(this.wrapTask(taskName, this.tasks[taskName]));
let taskFunction = this.tasks[taskName];

if (typeof taskFunction === "function") {
taskChain = taskChain.then(this.wrapTask(taskName, taskFunction));
}
}
return taskChain;
}
Expand Down
Loading

0 comments on commit 2241e5f

Please sign in to comment.