Skip to content

Commit 37d6531

Browse files
committed
[INTERNAL] AbstractBuilder: Refactoring & Introducing Build Phases
1 parent a3cc348 commit 37d6531

File tree

9 files changed

+173
-234
lines changed

9 files changed

+173
-234
lines changed

lib/builder/builder.js

Lines changed: 14 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,6 @@ const definedTasks = {
1616
generateLibraryPreload: require("../tasks/bundlers/generateLibraryPreload")
1717
};
1818

19-
20-
// Set of tasks for development
21-
const devTasks = [
22-
"replaceCopyright",
23-
"replaceVersion",
24-
"buildThemes"
25-
];
26-
2719
/**
2820
* Calculates the elapsed build time and returns a prettified output
2921
*
@@ -50,29 +42,31 @@ function getElapsedTime(startTime) {
5042
* @param {Object} parameters.tree Dependency tree
5143
* @param {string} parameters.destPath Target path
5244
* @param {boolean} [parameters.buildDependencies=false] Decides whether project dependencies are built as well
53-
* @param {boolean} [parameters.dev=false] Decides whether a development build should be activated (skips non-essential and time-intensive tasks)
45+
* @param {boolean} [parameters.basic=false] Decides whether a basic build should be activated (skips non-essential and time-intensive tasks)
5446
* @param {boolean} [parameters.selfContained=false] Flag to activate self contained build
5547
* @param {Array} [parameters.includedTasks=[]] List of tasks to be included
5648
* @param {Array} [parameters.excludedTasks=[]] List of tasks to be excluced. If the wildcard '*' is provided, only the included tasks will be executed.
57-
* @param {Array} [parameters.devExcludeProject=[]] List of projects to be exlcuded from development build
49+
* @param {Array} [parameters.devExcludeProject=[]] List of projects to be exlcuded from basic build
5850
* @returns {Promise<undefined>} Promise resolving to <code>undefined</code> once build has finished
5951
*/
60-
function build({tree, destPath, buildDependencies = false, dev = false, selfContained = false, includedTasks = [], excludedTasks = [], devExcludeProject = []}) {
52+
function build({tree, destPath, buildDependencies = false, basic = false, selfContained = false, includedTasks = [], excludedTasks = [], devExcludeProject = []}) {
6153
const startTime = process.hrtime();
6254
log.info(`Building project ${tree.metadata.name}` + (buildDependencies ? "" : " not") +
63-
" including dependencies..." + (dev ? " [dev mode]" : ""));
55+
" including dependencies..." + (basic ? " [basic mode]" : ""));
6456
log.verbose(`Building to ${destPath}...`);
6557

66-
let selectedTasks = composeTaskList({dev, selfContained, includedTasks, excludedTasks});
67-
6858
const fsTarget = resourceFactory.createAdapter({
6959
fsBasePath: destPath,
7060
virBasePath: "/"
7161
});
7262

63+
// If both build options are set to true, only the basic build mode will be activated
64+
if (basic && selfContained) {
65+
log.info("Building project in basic mode.");
66+
selfContained = false;
67+
}
7368

7469
const projects = {}; // Unique project index to prevent building the same project multiple times
75-
7670
const projectCountMarker = {};
7771
function projectCount(project, count = 0) {
7872
if (buildDependencies) {
@@ -91,7 +85,6 @@ function build({tree, destPath, buildDependencies = false, dev = false, selfCont
9185

9286
function buildProject(project) {
9387
let depPromise;
94-
let projectTasks = selectedTasks;
9588
if (buildDependencies) {
9689
// Build dependencies in sequence as it is far easier to detect issues and reduces
9790
// side effects or other issues such as too many open files
@@ -120,17 +113,17 @@ function build({tree, destPath, buildDependencies = false, dev = false, selfCont
120113
name: project.metadata.name
121114
});
122115

123-
if (dev && devExcludeProject.indexOf(project.metadata.name) !== -1) {
124-
projectTasks = composeTaskList({dev: false, selfContained, includedTasks, excludedTasks});
125-
}
126116
return projectType.build({
127117
resourceCollections: {
128118
workspace,
129119
dependencies: resourceCollections.dependencies
130120
},
131-
tasks: projectTasks,
132121
project,
133-
parentLogger: log
122+
parentLogger: log,
123+
buildOptions: {
124+
basic: basic,
125+
selfContained: selfContained
126+
}
134127
}).then(() => {
135128
log.verbose("Finished building project %s. Writing out files...", project.metadata.name);
136129
buildLogger.completeWork(1);
@@ -156,80 +149,6 @@ function build({tree, destPath, buildDependencies = false, dev = false, selfCont
156149
throw err;
157150
});
158151
}
159-
/**
160-
* Creates the list of tasks to be executed by the build process
161-
*
162-
* Sets specific tasks to be disabled by default, these tasks need to be included explicitly.
163-
* Based on the selected build mode (dev|selfContained|preload), different tasks are enabled.
164-
* Tasks can be enabled or disabled. The wildcard <code>*</code> is also supported and affects all tasks.
165-
*
166-
* @private
167-
* @param {boolean} dev Sets development mode, which only runs essential tasks
168-
* @param {boolean} selfContained True if a the build should be self-contained or false for prelead build bundles
169-
* @param {Array} includedTasks Task list to be included from build
170-
* @param {Array} excludedTasks Task list to be exlcuded from build
171-
* @returns {Array} Return a task list for the builder
172-
*/
173-
function composeTaskList({dev, selfContained, includedTasks, excludedTasks}) {
174-
let selectedTasks = Object.keys(definedTasks).reduce((list, key) => {
175-
list[key] = true;
176-
return list;
177-
}, {});
178-
179-
// Exclude tasks: manifestBundler
180-
selectedTasks.generateManifestBundle = false;
181-
selectedTasks.generateStandaloneAppBundle = false;
182-
183-
if (selfContained) {
184-
// No preloads, bundle only
185-
selectedTasks.generateAppPreload = false;
186-
selectedTasks.generateStandaloneAppBundle = true;
187-
selectedTasks.generateLibraryPreload = false;
188-
}
189-
190-
// Only run essential tasks in development mode, it is not desired to run time consuming tasks during development.
191-
if (dev) {
192-
// Overwrite all other tasks with noop promise
193-
Object.keys(selectedTasks).forEach((key) => {
194-
if (devTasks.indexOf(key) === -1) {
195-
selectedTasks[key] = false;
196-
}
197-
});
198-
}
199-
200-
// Exclude tasks
201-
for (let i = 0; i < excludedTasks.length; i++) {
202-
let taskName = excludedTasks[i];
203-
if (taskName === "*") {
204-
Object.keys(selectedTasks).forEach((sKey) => {
205-
selectedTasks[sKey] = false;
206-
});
207-
break;
208-
}
209-
if (selectedTasks[taskName] !== false) {
210-
selectedTasks[taskName] = false;
211-
}
212-
}
213-
214-
// Include tasks
215-
for (let i = 0; i < includedTasks.length; i++) {
216-
let taskName = includedTasks[i];
217-
if (taskName === "*") {
218-
Object.keys(selectedTasks).forEach((sKey) => {
219-
selectedTasks[sKey] = true;
220-
});
221-
break;
222-
}
223-
if (selectedTasks[taskName] === false) {
224-
selectedTasks[taskName] = true;
225-
}
226-
}
227-
228-
// Filter only for tasks that will be executed
229-
selectedTasks = Object.keys(selectedTasks).filter((task) => selectedTasks[task]);
230-
231-
return selectedTasks;
232-
}
233152

234153
module.exports = {
235154
build: build,

lib/types/AbstractBuilder.js

Lines changed: 38 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -10,27 +10,39 @@ class AbstractBuilder {
1010
* @param {object} project Project configuration
1111
* @param {GroupLogger} parentLogger Logger to use
1212
*/
13-
constructor({project, parentLogger}) {
14-
this.tasks = {};
13+
constructor({resourceCollections, project, parentLogger, buildOptions}) {
14+
this.resourceCollections = resourceCollections;
15+
this.project = project;
16+
this.buildOptions = buildOptions;
17+
this.tasks = [];
1518
this.log = parentLogger.createSubLogger(project.type + " " + project.metadata.name, 0.2);
1619
this.taskLog = this.log.createTaskLogger("🔨");
17-
this.availableTasks = [];
1820
}
1921

22+
// Build Phases
23+
preprocess() {}
24+
25+
themebuilding() {}
26+
27+
process() {}
28+
29+
bundle() {}
30+
31+
optimize() {}
32+
2033
/**
2134
* Adds a executable task to the builder
2235
*
23-
* This does not ensure the correct build order. The order is maintained through the property
24-
* [availableTasks]{@link AbstractBuilder#availableTasks}
36+
* The build order depends on the order the build tasks get added to the project.
2537
*
26-
* @param {string} taskName Name of the task which should be in the list availableTasks.
38+
* @param {string} taskName Name of the task
2739
* @param {function} taskFunction
2840
*/
2941
addTask(taskName, taskFunction) {
30-
if (this.availableTasks.indexOf(taskName) === -1) {
31-
throw new Error(`Task "${taskName}" does not exist.`);
32-
}
33-
this.tasks[taskName] = taskFunction;
42+
this.tasks.push({
43+
taskName: taskName,
44+
taskFunction: taskFunction
45+
});
3446
}
3547

3648
/**
@@ -39,20 +51,27 @@ class AbstractBuilder {
3951
* @param {array} tasksToRun List of tasks which should be executed
4052
* @returns {Promise} Returns promise chain with tasks
4153
*/
42-
build(tasksToRun) {
43-
const allTasksCount = tasksToRun.filter((value) => this.availableTasks.includes(value)).length;
54+
build() {
55+
// Run phases and add tasks to queue
56+
this.preprocess();
57+
this.themebuilding();
58+
59+
if (!this.buildOptions.basic) {
60+
this.process();
61+
this.bundle();
62+
this.optimize();
63+
}
64+
65+
const allTasksCount = Object.keys(this.tasks).length;
4466
this.taskLog.addWork(allTasksCount);
4567

4668
let taskChain = Promise.resolve();
47-
for (let i = 0; i < this.availableTasks.length; i++) {
48-
let taskName = this.availableTasks[i];
49-
50-
if (!tasksToRun.includes(taskName)) {
51-
continue;
52-
}
5369

54-
taskChain = taskChain.then(this.wrapTask(taskName, this.tasks[taskName]));
70+
for (var i = 0; i < this.tasks.length; i++) {
71+
var task = this.tasks[i];
72+
taskChain = taskChain.then(this.wrapTask(task.taskName, task.taskFunction));
5573
}
74+
5675
return taskChain;
5776
}
5877

0 commit comments

Comments
 (0)