Last active
May 21, 2021 10:27
-
-
Save bmarti44/f6b8d3d7b331cd79305ca8f45eb8997b to your computer and use it in GitHub Desktop.
Build all Angular apps in batches asynchronously
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | |
}); | |
} | |
}); | |
👍
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
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.