feat(@angular/build): add library builder - #34106
alan-agius4 wants to merge 3 commits into
Conversation
e9c43b0 to
67110b0
Compare
67110b0 to
5513da2
Compare
5513da2 to
b3ffd2d
Compare
|
/gemini review |
There was a problem hiding this comment.
Code Review
This pull request introduces a new library builder (@angular/build:library) designed to compile, bundle, and package Angular libraries in compliance with the Angular Package Format (APF). It includes features such as incremental compilation, watch mode, asset copying, secondary entry point resolution, and package.json generation. The review feedback highlights a few critical areas for improvement: ensuring the package name is updated in options when package.json changes in watch mode, optimizing startup by avoiding redundant reads of package.json, and capturing and propagating stylesheet compilation warnings to the user.
There was a problem hiding this comment.
Code Review
This pull request introduces a new library builder for Angular, enabling the compilation, bundling, and packaging of libraries in accordance with the Angular Package Format (APF). The changes include the core builder logic, a dependency graph scanner for entry points, an incremental compilation pipeline, and support for secondary entry points. My review highlights performance optimizations for the dependency predicate and file change detection logic, which are critical for maintaining build speed in larger projects.
7239409 to
4ee7685
Compare
5ef0ac4 to
b19ab2c
Compare
a84e8ef to
5579d74
Compare
bed00ba to
005e05e
Compare
|
Hi @alan-agius4, this is great! Now that TypeScript projects are growing in size and TypeScript itself is moving to the native Golang rewrite, driven by the need to optimize build times, I think that the approach to the new library builder is the way to go.
You have a very good point on incremental rebuilds in watch mode. The disk-heavy I/O in That said, optimus-ui should also be a valid reference to run benchmarks.
Fully agree. The disk-heavy I/O in I'll also agree that focusing on build times and therefore dropping auto-discovery of source files is a valid point.
Definetely. Centralizing this layout stops configuration drift across deeply nested directories. I think, this is an incredible and much-needed milestone for the ecosystem! I’ve been heavily experimenting with a similar in-memory architecture for Seeing your benchmarks, especially the incremental TS/SCSS rebuild times hitting <250ms compared to legacy chains, completely validates that memory-bound compilation is the way forward for large-scale source repositories. |
|
Thanks for the feedback, @dherges! Also, thanks for pointing out optimus-ui, I'll definitely look into running benchmarks against it as well. Just one clarification regarding the in memory aspect: The performance gains we're seeing here, especially for incremental TS and SCSS rebuilds, mainly come from tighter integration with Angular's compiler host and caching infrastructure, along with a direct async rebuild pipeline that eliminates the orchestration overhead of the reactive RxJS transform architecture and per entry point sub pipelines. |
|
@alan-agius4 about entryPoints: I put up the glob version as a draft #34127. An entry point that silently doesn't get published was the part that worried me most, so I wanted something concrete to discuss rather than just an issue. On ngwr these two lines replace the 230-line map, the output is identical to the explicit map, and the scan takes ~10ms. It's a draft since there's nothing to merge it into yet. Happy to change approach or close it if you'd rather do it differently. |
That makes total sense. I was exploring the disk I/O of the source discovery and the
So you're saying: sharing the compiler host and the stylesheet bundling across multiple entry points is the real difference. Right? To better understand the approach: is the speedup here just removing RxJS transforms, or removing RxJS transforms plus additional benefit that come along with it? |
|
Thanks for putting together #34127 so quickly, @thekhegay! Having a concrete implementation to look at makes evaluating the ergonomics much easier, and the data on @dherges That is definitely a large part of it, but the speedup comes from several specific architectural changes beyond just removing the RxJS transform layer:
|
| "entryPoints": { | ||
| "type": "object", | ||
| "description": "Map of package entry points. The '.' key represents the primary entry point; other keys define secondary subpath entry points.", | ||
| "required": ["."], | ||
| "additionalProperties": { | ||
| "oneOf": [ | ||
| { | ||
| "type": "string", | ||
| "description": "Path to the entry file (e.g. 'projects/my-lib/src/public-api.ts')." | ||
| }, | ||
| { | ||
| "$ref": "#/definitions/entryPoint" |
There was a problem hiding this comment.
Example for entry points spec:
".": "public_api.ts",
"./testing": "./testing/public_api.ts"
And:
".": { /* entry file + tsconfig */ }
In ng-packagr the entry points are specified in package.json and ng-package.json.
ng update schematic should replicate ng-packagr's discoverPackages behavior, remove the custom ng-package.json, translating entry points set to the library builder options.
Documentation says that 2nd art entry points must be specified by ng-package.json so this file can safely be removed.
Primary entry point can have both package.json and ng-package.json: the latter can safely be removed. The first should be kept intact and modified , only removing ng-package's custom properties from the package.json.
There was a problem hiding this comment.
‘ng update` is out of scope for this particular PR, but it is on our radar for the near future (most of the work for it is actually already done).
There was a problem hiding this comment.
Good to know someone from the team is already on it!
Aligning documentation of Angular Package Format (APF) with angular/angular-cli#34106 and ng-packagr/ng-packagr#3360
|
@alan-agius4 Understood on patterns, happy to leave #34127 parked until the builder itself lands. Meanwhile I ran the builder against ng-zorro-antd (105 entry points, same layout as ngwr: one folder per entry point with
No OOM on this one, on the default heap or the 14 GB one the repo sets. Watch memory matches ng-packagr because watch doesn't create the worker pool; the non-watch gap is 13 workers by default on a 14-core machine. Output matches closely: same 421 files, same 185 exports keys with every |
Add a new native `@angular/build:library` builder providing a modern, high-performance compilation and packaging pipeline.
005e05e to
8c58c5e
Compare
Aligning documentation of Angular Package Format (APF) with angular/angular-cli#34106 and ng-packagr/ng-packagr#3360
Aligning documentation of Angular Package Format (APF) with angular/angular-cli#34106 and ng-packagr/ng-packagr#3360 (cherry picked from commit 0006391)
Aligning documentation of Angular Package Format (APF) with angular/angular-cli#34106 and ng-packagr/ng-packagr#3360 (cherry picked from commit 0006391)
PR Checklist
Please check to confirm your PR fulfills the following requirements:
PR Type
What is the current behavior?
Currently, there is no native
@angular/build:librarybuilder in@angular/build.Issue Number: N/A
What is the new behavior?
Add a new native
@angular/build:librarybuilder providing a modern, high-performance compilation and packaging pipeline.Does this PR introduce a breaking change?
Other information