It would be useful to have a way to build a certain set of projects on a workspace.
Perhaps this can be achieved with global workspace targets, or via a filtering mechanism.
Followup to https://github.com/angular/angular-cli/pull/10397
Any plans for this feature?
Hi @filipesilva,
Every project in a workspace already contains package.json (_obviously_). We could use peerDependencies to declare the dependencies between projects of the workspace. Then build and test commands would be able to detect the dependencies and build the libraries in the correct sequence.
I have written myself a node executable that does exactly that. Follows the dependency tree and builds the libraries in the correct sequence.
If that is something you see as a valuable addition to Angular CLI I would be more than happy to contribute.
@klemenoslaj the approach we are looking at now would be able to do that implicitly, we hope. We're still finishing up the Architect API (this is what we use for build definitions).
@filipesilva, that sounds good :+1:
I however still like the idea of using peerDependencies, because it forces people to think about their dependencies (very important for published packages) and if that is done correctly, build sequence is automatically correct.
I can see how that can be a bit complex for someone, but I still think handling dependencies via package.json is a good way to go.
Are there any plans when it can be expected?
Is it possible with the new CLI builders announced here : https://blog.angular.io/introducing-cli-builders-d012d4489f1b ?
If yes could we have an example ?
Actually, the builder approach is just project related and not workspace related. We already implemented npm script that just analyzes all projects, builds dependency tree and calls sequentially build but still problems during watch mode: build is too slow!
During development time I guess only productive way is to change tsconfig path as described on https://github.com/angular/angular-cli/issues/10643#issuecomment-388389988
@meriturva Is this possible for multiple libraries within a single project? I understand schematics exposes options to invoke external schematics and builder is just an extension of schematics!?
@Goonersid our approach is just for a single project with multiple libraries. Right now we have all to test new build based on bazel before improving our internal solution.
@meriturva I'm looking for a cli cmd that builds all libraries within a single project... Is it possible with v6 or the latest stable? Something like ng build-all
@Goonersid you have to write you own task script and run as: npm run build-all
@Goonersid I was also looking for something like this and created a script, which reads the angular.json file and executes ng build for every project and every configuration. Also this script collects all failed builds and prints them to stdout at the end.
EDIT:
I am using nrwl/nx, so I don't have to build libraries manually.
So this script will probably not work for default Angular CLI.
The script looks like this:
import { ProjectType, WorkspaceSchema } from "@schematics/angular/utility/workspace-models";
import { execSync } from "child_process";
import { readFileSync } from "fs";
interface ExecParams {
project: string;
config: string;
}
interface ExecError extends ExecParams {
message: string;
}
function buildAll() {
const json: WorkspaceSchema = JSON.parse(readFileSync("./angular.json").toString());
const errors: ExecError[] = Object.keys(json.projects)
// Filter application-projects
.filter(name => json.projects[name].projectType === ProjectType.Application)
// Determine parameters needed for the build command
.reduce<ExecParams[]>((arr, project) => {
const proj = json.projects[project];
let build = proj.architect && proj.architect.build;
if (build) {
arr = arr.concat(...Object.keys(build.configurations || {})
.map(config => ({ project, config }))
);
}
return arr;
}, [])
// Execute `ng build` and collect errors.
.reduce<ExecError[]>((err, exec) => {
try {
console.log(`Building ${exec.project} (${exec.config}):`);
execSync(`ng build --prod --project ${exec.project} --configuration ${exec.config}`, {stdio: "inherit"});
}
catch (error) {
err.push({
project: exec.project,
config: exec.config,
message: error.message
});
}
console.log("\n");
return err;
}, []);
// Conditionally log errors
if (errors.length === 0)
console.log("Completed");
else {
console.log("\n");
errors.forEach(error => {
console.error(`Building ${error.project} (${error.config}) failed:\n\t${error.message}`);
});
}
}
buildAll();
This script can be compiled to Javascript and then you can run it using NodeJs.
@Springrbua but you're not following any dependencies, therefore if some library depends on another this will break or work by accident.
@klemenoslaj You are right, I never used the normal Angular CLI for multi app projects and therefore forgot, that you need to build libraries yourself.
I am using nrwl/nx, which automatically builds all needed libraries when executing ng build, so that's not a problem in my case.
I think this is an important feature for enterprise project with many library
I'm using too https://github.com/otiai10/too.js,
hoping it would help
Any plans actually?
A dirty hack (that ignores inner-dependencies) for windows would also be this BATCH-script:
DIR "projects\" /B /AD > "projects.txt"
FOR /f "usebackq delims=" %%f IN ("projects.txt") DO call ng build %%f
FOR /f "usebackq delims=" %%f IN ("projects.txt") DO call ng build %%f
DEL "projects.txt"
I do the FOR-loop twice because of an inner dependency in my projects. Also i use "call" to ignore errors in the first run.... dirty as hell but it's a workaround.
Most helpful comment
Any plans for this feature?