Skip to content

Instantly share code, notes, and snippets.

@bmarti44
Last active May 21, 2021 10:27
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bmarti44/f6b8d3d7b331cd79305ca8f45eb8997b to your computer and use it in GitHub Desktop.
Save bmarti44/f6b8d3d7b331cd79305ca8f45eb8997b to your computer and use it in GitHub Desktop.
Build all Angular apps in batches asynchronously
const fs = require('fs'),
spawn = require('child_process').spawn,
// Custom output path.
outputPath = '/nba-angular',
// Number of projects to build asynchronously.
batch = 3;
let ngCli;
function buildProject(project) {
return new Promise((resolve, reject) => {
let child = spawn('ng', ['build', '--project', project, '--prod', '--extract-licenses', '--build-optimizer', `--output-path=${outputPath}/dist/` + project]);
child.stdout.on('data', (data) => {
console.log(data.toString());
});
child.stderr.on('data', (data) => {
process.stdout.write(data.toString());
});
child.on('close', (code) => {
if (code === 0) {
resolve(code);
} else {
reject(code);
}
});
})
}
function filterProjects(projects) {
return Object.keys(projects).filter(project => project.indexOf('e2e') === -1);
}
function batchProjects(projects) {
let currentBatch = 0,
i,
batches = {};
for (i = 0; i < projects.length; i += 1) {
if ((i) % batch === 0) {
currentBatch += 1;
}
if (typeof (batches['batch' + currentBatch]) === 'undefined') {
batches['batch' + currentBatch] = [];
}
batches['batch' + currentBatch].push(projects[i]);
}
return batches;
}
fs.readFile('angular.json', 'utf8', async (err, data) => {
let batches = {},
batchesArray = [],
i;
if (err) {
throw err;
}
ngCli = JSON.parse(data);
batches = batchProjects(filterProjects(ngCli.projects));
batchesArray = Object.keys(batches);
for (i = 0; i < batchesArray.length; i += 1) {
let promises = [];
batches[batchesArray[i]].forEach((project) => {
promises.push(buildProject(project));
});
console.log('Building projects ' + batches[batchesArray[i]].join(','));
await Promise.all(promises).then(statusCode => {
console.log('Projects ' + batches[batchesArray[i]].join(',') + ' built successfully!');
if (i + 1 === batchesArray.length) {
process.exit(0);
}
}, (reject, total) => {
console.log(reject);
process.exit(1);
});
}
});
@bmarti44
Copy link
Author

I've updated this to build in batches of 3 apps at a time, but that is configurable. I'm also using async/await to try to simplify things, and switched to child_process spawn to further optimize how much memory the script uses.

@thunder-coding
Copy link

thunder-coding commented Jan 18, 2021

👍

@krishnathota
Copy link

This would work out just fine in the ideal case if there is no cross dependency of libraries. But if there is a cross dependency this would fail. For example, we have 3 libraries

lib1
lib2
lib3

If lib3 is used inside lib2, while building lib2, since lib3 is not built yet, the build would fail.

Did you happen to face this? Any solution for this use case?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment