Buildtime increased by 50% in v12

🐞 Bug report
Command (mark with an x)

[x] build

Description
This is v11.2.13:
$ ng build --prod
√ Browser application bundle generation complete.
√ Copying assets complete.
√ Index html generation complete.

Initial Chunk Files                   | Names         |      Size
main.1bbe17e891e0e81a6bae.js          | main          |   3.20 MB
scripts.5b3322e07a3cdcf6af69.js       | scripts       |   1.48 MB
styles.19406af932cc90ae2667.css       | styles        | 152.44 kB
polyfills-es5.2cb7395a5fd592fe7443.js | polyfills-es5 |  85.88 kB
runtime.23c71f07ba7ec5c3766a.js       | runtime       |   1.51 kB

                                      | Initial Total |   4.92 MB

Build at: 2021-05-14T11:00:10.476Z - Hash: 034e3176df64cbc0b60a - Time: 88357ms

Verbose log (logging itself causes slowdown, unfortunately...):
angular11.txt
Angular CLI: 11.2.13
Node: 14.17.0
OS: win32 x64

Angular: 11.2.13
... animations, cli, common, compiler, compiler-cli, core, forms
... language-service, platform-browser, platform-browser-dynamic
... router
Ivy Workspace: Yes

Package                         Version
---------------------------------------------------------
@angular-devkit/architect       0.1102.13
@angular-devkit/build-angular   0.1102.13
@angular-devkit/core            11.2.13
@angular-devkit/schematics      11.2.13
@angular/cdk                    11.2.12
@angular/material               11.2.12
@schematics/angular             11.2.13
@schematics/update              0.1102.13
rxjs                            6.6.7
typescript                      4.1.5

This is v12 with yarn.lock  and node_modules removed and reinstalled:
$ ng build --configuration production
Warning: Support was requested for IE 11 in the project's browserslist configuration. IE 11 support is deprecated since Angular v12.
For more information, see https://angular.io/guide/browser-support
√ Browser application bundle generation complete.
√ Copying assets complete.
√ Index html generation complete.

Initial Chunk Files                   | Names         |      Size
main.25755cb56d908f1ffa0c.js          | main          |   3.19 MB
scripts.5b3322e07a3cdcf6af69.js       | scripts       |   1.48 MB
styles.51baf6c2a9fbe6837aa1.css       | styles        | 154.28 kB
polyfills-es5.b787b17c5e8d81a4b18e.js | polyfills-es5 |  90.75 kB
runtime.bf3db8034d6e10a74a56.js       | runtime       |   1.20 kB

                                      | Initial Total |   4.92 MB

Build at: 2021-05-14T11:18:16.175Z - Hash: 8806f0a3a3b1271495e0 - Time: 157125ms

Verbose log (logging itself causes slowdown, unfortunately...):
angular12.txt
Angular CLI: 12.0.0
Node: 14.17.0
Package Manager: yarn 1.22.5
OS: win32 x64

Angular: 12.0.0
... animations, cdk, cli, common, compiler, compiler-cli, core
... forms, language-service, material, platform-browser
... platform-browser-dynamic, router

Package                         Version
---------------------------------------------------------
@angular-devkit/architect       0.1200.0
@angular-devkit/build-angular   12.0.0
@angular-devkit/core            12.0.0
@angular-devkit/schematics      12.0.0
@schematics/angular             12.0.0
rxjs                            6.6.7
typescript                      4.2.4

We have a single small *.scss file (overriding some material colors) and it was updated by migration. The application has only one module. I tried removing scss and css from angular.json, but it is still slower than v11.
On average it is 50% slower.
-------------------------------------------------------------------------------
Language                     files          blank        comment           code
-------------------------------------------------------------------------------
TypeScript                    1011          10391           2652          54543
HTML                           311            629              7           7832
CSS                             66            344             30           2109
Sass                             1             15             14             63
JavaScript                       1              9              3             55
JSON                             1              0              0              3
-------------------------------------------------------------------------------
SUM:                          1391          11388           2706          64605
-------------------------------------------------------------------------------

Recorded profile using node 12:
https://link.nithins.me/s2Uca0Ti

I am having little luck with loading the profiling events into chrome://tracing (it stays empty).
@kemsky if you are able to run with a debugger and then record a profiling session, that would be very helpful.

@JoostK, I was not able to load it either. I tried recording on node 14.17 but it crashes at the very beginning. Ok, will try to do it using a debugger.

After some debugging of Chrome's tracing tool, it appears that the +600MB of tracing data exceeds the maximum string length 🤣 https://github.com/v8/v8/commit/ea56bf5513d0cbd2a35a9035c5c2996272b8b728. Importing the file itself just results in an empty string, whereas loading the zip crashes during decompression when all uncompressed bytes are converted into a single string.

@JoostK, JSON contains a simple array, so you can cut it if necessary into two parts.

I'm having the same issue with build times, the initial report looks to be fairly thorough but feel free to @ me if you would like further  tracing / info.

With some sed magic to remove the common path prefix I managed to get the trace size down to fit:

Unfortunately I can't make a comparison with 11 as I don't have a trace for that run, but Webpack processing itself is now longer than the full build took before.
The pruned trace can be downloaded here (only available for a week).

I am not sure how to proceed here. We'd likely still need some runnable reproduction in order to establish what can be done to improve the situation here. If anyone can share a repro privately that would be super helpful.

@JoostK - Mine is a fairly large monorepo, I'll get to work on a repo you can access that is a bit more focused. Give me a hour or two

@JoostK - Mine is a fairly large monorepo, I'll get to work on a repo you can access that is a bit more focused. Give me a hour or two

Thanks. Also take your time as it's almost 2 AM for me so I'm calling it a day!

@JoostK, this is v11 profile: https://link.nithins.me/9NfVUS9T
I'm not sure if these are comparable...

@kemsky - You can either give m8 more memory globally or chrome itself.
Globally ( imo the useful way ): NODE_OPTIONS=--max_old_space_size=8192
To Chrome: Chrome.app --args --js-flags="--max_old_space_size=8192"

@JoostK - I threw a new v11 CLI app up, added material and a basic component so it imports some styles. It's super minimal but should work for a reproduction, if not i'll just get you collab access to my work repo to poke around.
Main branch is cli v11.2.13 (6096ms prod build) and upgrade-v12 is that branch upgraded. (13245ms prod build)
https://github.com/EasyMetrics/v12-upgrade-performance

@JoostK, this is v11 profile: https://link.nithins.me/9NfVUS9T
I'm not sure if these are comparable...
Devtools are crashing also, I can only take a partial profile.

Not sure how to interpret those results. The angular-compiler block stays the same across v11 vs v12 which is to be expected, but what follows is so vastly different that I can't say what the real problem is. Terser is reported surprisingly differently in a way that in v12 it spans 60s vs just 10s in v11, but that may just be because the profiling events are generated differently. Additionally, the v11 trace spans almost 6 minutes vs 3.5 minutes in the v12 trace, so that's suspicious as well (especially because the angular-compiler trace has stayed consistent)

@JoostK - I threw a new v11 CLI app up, added material and a basic component so it imports some styles. It's super minimal but should work for a reproduction, if not i'll just get you collab access to my work repo to poke around.
Main branch is cli v11.2.13 (~6000ms --prod) and upgrade-v12 is that branch upgraded. (~13200ms --prod).
https://github.com/EasyMetrics/v12-upgrade-performance

Okay so I tried this and I'm actually getting similar times for v11 and v12, however in v11 the Terser processing is cached whereas in v12 it doesn't appear to be. This results in inconsistent results for v11, as cold runs are ~12s vs ~7s for cached runs; unlike v12 which always takes ~12s.

terser-webpack plugin will only cache to disk when using webpack 4. With webpack 5 it uses webpacks’ caching API and is dependent on this being set to filesystem to benefit 2nd cold builds.
I am currently experimenting with this and hoping to enable file system caching in the CLI in the near future.
Webpack 4, code path
https://github.com/webpack-contrib/terser-webpack-plugin/blob/version-2/src/Webpack4Cache.js
Webpack 5, code path
https://github.com/webpack-contrib/terser-webpack-plugin/blob/version-2/src/Webpack5Cache.js

Is it possible to turn off caching in v11?

Yeah, you can use  the NG_BUILD_CACHE environment variable.
Ex: NG_BUILD_CACHE=0 ng build

If I don't cache my v11 builds in my big monorepo, the build times are almost identical.
tl&dr here is CLI v12 is using Webpack 5, terser-webpack-plugin isn't caching like it does in CLI v11 using Webpack v4 and it just sort of "is what it is" for the moment.

Same increase of the build time after migrating from v11 to v12.
But here we can see more than 100% of time difference.
Before:

After:

Same here. For a pretty small project. (2 pages with a couple of components)
V11 was slow.. But v12 is even slower atm.

@JoostK, @alan-agius4, I removed all scss files and set NG_BUILD_CACHE=0, results are below:
v11.2.13
>".\node_modules\.bin\ng.cmd" build --prod
√ Browser application bundle generation complete.
√ Copying assets complete.
√ Index html generation complete.

Initial Chunk Files                   | Names         |     Size
main.a383d4343fc769770869.js          | main          |  3.20 MB
scripts.5b3322e07a3cdcf6af69.js       | scripts       |  1.48 MB
polyfills-es5.66ac62d089ac586e9220.js | polyfills-es5 | 85.88 kB
runtime.76277ef9655d34c2d937.js       | runtime       |  1.51 kB

                                      | Initial Total |  4.77 MB

Build at: 2021-05-16T12:08:41.073Z - Hash: 6acba3c73318a8cd5749 - Time: 159782ms

v12.0.0
>".\node_modules\.bin\ng.cmd" build --prod
Option "--prod" is deprecated: Use "--configuration production" instead.
Warning: Support was requested for IE 11 in the project's browserslist configuration. IE 11 support is deprecated since Angular v12.
For more information, see https://angular.io/guide/browser-support
√ Browser application bundle generation complete.
√ Copying assets complete.
√ Index html generation complete.

Initial Chunk Files                   | Names         |     Size
main.1bd8f29d9fb0ec7900b5.js          | main          |  3.22 MB
scripts.5b3322e07a3cdcf6af69.js       | scripts       |  1.48 MB
polyfills-es5.b787b17c5e8d81a4b18e.js | polyfills-es5 | 90.75 kB
runtime.bf3db8034d6e10a74a56.js       | runtime       |  1.20 kB

                                      | Initial Total |  4.79 MB

Build at: 2021-05-16T12:02:59.182Z - Hash: a899c8b10f7d6415a015 - Time: 163759ms

After several runs +/- the same time.
Styles processing is slightly slower on v12.

Same here, taking ~26s to compile every time I change 1 line of code whereas before in v11 it used to take only 5-10s max.
I might revert the upgrade in the meantime, its making coding a pain

@mebibou That sounds like a different problem than the Terser cache that was being discussed above. Incremental rebuilds typically don't run production optimizations. I might have an idea of where extra time is spent (but 15-20s is more than I'd though, so may be something else at play) and I'd love to investigate, but I'd need at least profiling sessions to do so.

For me it's even worse! Build time for our example repo (available for public, but stripped of most content) is up almost 500%.
Angular v11: webpack 5.37.0 compiled with 3 warnings in 12455 ms
Angular v12: webpack 5.37.0 compiled with 5 warnings in 49177 ms

@JonWallsten Can you share that repo, as you mention it's public?

@JoostK: Yeah, sorry, I forgot to make it public after I wrote that:
https://github.com/JonWallsten/monorepo-new
I'm building with detailed stats in Webpack as we speak. Will paste them ASAP.

This started failing on hot reload rebuilding, while on ng serve.
This is what I got almost 5 times during a ~5 hours work session.
⠴ Generating browser application bundles (phase: building)...
<--- Last few GCs --->

[58819:0x102d61000]  9811769 ms: Scavenge 2032.2 (2052.4) -> 2031.6 (2052.4) MB, 251.4 / 0.0 ms  (average mu = 0.221, current mu = 0.136) allocation failure
[58819:0x102d61000]  9811787 ms: Scavenge 2032.4 (2052.4) -> 2031.7 (2052.4) MB, 14.4 / 0.0 ms  (average mu = 0.221, current mu = 0.136) allocation failure
[58819:0x102d61000]  9812638 ms: Mark-sweep 2032.6 (2052.6) -> 2031.6 (2052.6) MB, 845.2 / 0.0 ms  (average mu = 0.243, current mu = 0.271) allocation failure scavenge might not succeed

<--- JS stacktrace --->

==== JS stack trace =========================================

    0: ExitFrame [pc: 0x1009dcb79]
    1: StubFrame [pc: 0x100a46574]
Security context: 0x0ceb671008d1 <JSObject>
    2: /* anonymous */(aka /* anonymous */) [0xcebd79906d1] [.../node_modules/webpack/lib/NormalModuleFactory.js:1] [bytecode=0xceb9482b759 offset=0](this=0x0cebab9c04b1 <undefined>,0x0ceb3b432869 <Object map = 0xceb1a889859>,0x0ceb272e61b9 <JSFunction (sfi = 0xcebfec50c51)>)
    3: /* anonymo...

FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory
 1: 0x1011d1c65 node::Abort() (.cold.1) [/usr/local/bin/node]
 2: 0x10009f919 node::Abort() [/usr/local/bin/node]
 3: 0x10009fa7f node::OnFatalError(char const*, char const*) [/usr/local/bin/node]
 4: 0x1001e3867 v8::Utils::ReportOOMFailure(v8::internal::Isolate*, char const*, bool) [/usr/local/bin/node]
 5: 0x1001e3807 v8::internal::V8::FatalProcessOutOfMemory(v8::internal::Isolate*, char const*, bool) [/usr/local/bin/node]
 6: 0x10036b995 v8::internal::Heap::FatalProcessOutOfMemory(char const*) [/usr/local/bin/node]
 7: 0x10036d20a v8::internal::Heap::RecomputeLimits(v8::internal::GarbageCollector) [/usr/local/bin/node]
 8: 0x100369c3c v8::internal::Heap::PerformGarbageCollection(v8::internal::GarbageCollector, v8::GCCallbackFlags) [/usr/local/bin/node]
 9: 0x100367a3e v8::internal::Heap::CollectGarbage(v8::internal::AllocationSpace, v8::internal::GarbageCollectionReason, v8::GCCallbackFlags) [/usr/local/bin/node]
10: 0x10037390a v8::internal::Heap::AllocateRawWithLightRetry(int, v8::internal::AllocationType, v8::internal::AllocationOrigin, v8::internal::AllocationAlignment) [/usr/local/bin/node]
11: 0x100373991 v8::internal::Heap::AllocateRawWithRetryOrFail(int, v8::internal::AllocationType, v8::internal::AllocationOrigin, v8::internal::AllocationAlignment) [/usr/local/bin/node]
12: 0x10034135a v8::internal::Factory::NewFillerObject(int, bool, v8::internal::AllocationType, v8::internal::AllocationOrigin) [/usr/local/bin/node]
13: 0x100693768 v8::internal::Runtime_AllocateInYoungGeneration(int, unsigned long*, v8::internal::Isolate*) [/usr/local/bin/node]
14: 0x1009dcb79 Builtins_CEntry_Return1_DontSaveFPRegs_ArgvOnStack_NoBuiltinExit [/usr/local/bin/node]
15: 0x100a46574 Builtins_CreateFunctionContextHandler [/usr/local/bin/node]
16: 0x100962524 Builtins_InterpreterEntryTrampoline [/usr/local/bin/node]
17: 0x100962524 Builtins_InterpreterEntryTrampoline [/usr/local/bin/node]
error Command failed with signal "SIGABRT".

@anton-white, please keep this issue related to rebuild times. You issue is related to https://github.com/angular/angular-cli/issues/20801

@JonWallsten It looks like that project is not using the CLI but rather Webpack directly with @ngtools/webpack.  From looking at the Webpack configuration, the performance difference is probably due to the use of AOT instead of JIT.  The old AngularCompilerPlugin used JIT mode by default whereas the new AngularWebpackPlugin uses AOT by default. JIT mode can be enabled within AngularWebpackPlugin by setting the jitMode option to true.

@clydin: That's interesting. I really thought we where used AOT. Is there anyway I can confirm this in my output?

Sorry, I was mixing different issues.  The JIT/AOT area should not actually be an issue in this case.  If using the the plugins directly (outside the CLI), they should both be using AOT.

I did a profile after speaking to @JoostK:

sass-dart has gone haywire.

Was also just about to comment that something to try was to remove all Sass files.  But the above profile image appears to confirm the problem.

@clydin Let me know if you need anything else from me.

@JonWallsten  The next patch release of the CLI will include two substantial performance improvements for Sass compilation (https://github.com/angular/angular-cli/pull/20740 & https://github.com/angular/angular-cli/pull/20771) to mitigate the longer dart-sass rendering.  Unfortunately, since sass-loader is being used directly, the project won't benefit.  You could try to manually integrate that code into the the custom Webpack setup.  However, I think the from a performance perspective trying to transition to using the CLI's build system would be ideal as it attempts to adjust the Webpack configuration and compilation in a variety of ways to optimize performance.

@clydin: I see. What happened to the sass implementation in Angular 12 to cause an almost 1000% (in my case) increase in build time?
We use AngularCompilerPlugin (or AngularWebpackPlugin) because we have a monorepo with both Angular.JS, Angular and agnostic application as libraries of all those three kinds. I'm not sure how to incorporate Angular CLI into that mix. Especially since we also have build tools that make sure each lib is built in order and then the applications, even for rebuilds. It would probably really hard to do that with Angular CLI involved.

This material issue provides some more details regarding the performance and is most likely related to your issue (changes to both the new and legacy theming APIs occurred in v12): https://github.com/angular/components/issues/22676

In v12 I can't even get past the initial build ⠋ Generating browser application bundles (phase: building)... phase.

Build time is now on Windows more than 15 min with Angular 12. Before with Angular 11 it was around one minute.
So, we need to go back to 11...

In v12 I can't even get past the initial build ⠋ Generating browser application bundles (phase: building)... phase.

I have the same problem. I had to go back to v11.

Who is having issues please either share a reproduction or the project (even privately) or CPU profile, without any of this we cannot find the root cause of your problem, also kindly provide clear instructions to which command you are running and the relative settings in angular.json.
While I understand you might be experiencing the same problem, but by posting me too or anything along these lines without providing any meaningful information, you are not contributing to fixing the problem, but just adding no noise which makes it harder for users and contributors to find important messages which might be crucial to get to the bottom of the problem.
Back to how you can help, to generate a profile use the below steps

node --inspect-brk<EMAIL_ADDRESS>build
Open Chrome and type chrome://inspect -> Open dedicated DevTools for Node -> Profiler tab ->Record (this will resume from the halted debugger in profiling mode). Wait until the process is finished and then stop recording and save the profile and upload it here.

Thanks before hand.

@alan-agius4 thanks for your reply and for good instructions.
I have a pretty big project and today I have upgraded it step by step from ng9 to ng12.
Unfortunately I also was faced with ng12 build time issue and it works for build and for server as well.
My build time's:
ng9 - ~2m
ng11 - ~2m 15 sec
ng12 - ~ 4m 25sec
All these benchmarks were made after npm i and it was second time builds. It means that I passed first build after npm install to give angular prepare some caches/ivy entry points and everything what can blur the picture of benchmark.
Project files were 100% same between benchmarks. Everything I did is just ng update.
Here is my angular.json files for benchmarks v9, 11, 12 and also profile files. Link to Google Drive
Hope it will help you and Angular team to find bottle neck.
Feel free to ask me any additional info.

@basters Thank you so much! I have successfully opened the v9 and v12 profile (which took several minutes to load, then several minutes to actually show up) and it appears to confirm the findings in other projects as well:
v9:

v12 (note: image does not have the same scale as the v9 screenshot!)

That orange/yellow-ish in the centre is dart-sass, which wasn't there before.

@basters It's also striking that source-map processing is taking significantly more time in v12: 44s versus 8s in v9. I don't know why this is because source-map processing hasn't changed much. It could be that something in the pipeline is producing larger source maps, such that processing them takes a lot longer.
The Babel processing on the other is 20% faster in v12, from 40s to 32s (the block with the gazillion colours towards 2/3 of the trace).
Looking at it further, I'm doubting if the exact same sources are being compiled? createProgram takes 17s in v9 versus 27s in v12 and type-checking went from ~10s to ~42s. I am not sure where these large differences come from.

@JoostK Yep, I'm 100% sure that exact same sources are being compiled. Just double checked and what I can say: only ngx-toastr and ngx-cookie-service were updated to latest versions. Everything else remains the 100% same.
If ngx-cookie-service & ngx-toastr can blur the picture - I can revert them to previous versions and record ng12 build profile again, just let me know.
Its important to note that those libraries were updated for ng11 build as well to<EMAIL_ADDRESS>and<EMAIL_ADDRESS>For ng12 build it is<EMAIL_ADDRESS>and<EMAIL_ADDRESS>

@basters, are you using @angular/material? if so for is this referenced in SCSS?

@alan-agius4 yes, I'm using @angular/material and it was updated with ng update as well as angular and it has references in SCSS. Here is a link to theme&palette setup

Looking at it further, I'm doubting if the exact same sources are being compiled? createProgram takes 17s in v9 versus 27s in v12 and type-checking went from ~10s to ~42s. I am not sure where these large differences come from.

@JoostK, this is likely coming from the fact that in v9 the build was in JIT mode.

Looking at it further, I'm doubting if the exact same sources are being compiled? createProgram takes 17s in v9 versus 27s in v12 and type-checking went from ~10s to ~42s. I am not sure where these large differences come from.

@JoostK, this is likely coming from the fact that in v9 the build was in JIT mode.

I don't think that's the case; there's Angular analysis and template type-checking in both versions, so they are both using AOT.

@JoostK, you are right.

I wrote a small tool that uses both sass-migrator and migrateFileContent from  @angular/material/schematics/ng-update/migrations/theming-api-v12/migration to migrate all scss files to use modules instead.
Build times is now "only" increased ~15%.

@basters, I realized you mentioned All these benchmarks were made after npm i and it was second time builds.
In version 12, terser optimizations are not cached for seconds runs see https://github.com/angular/angular-cli/issues/20792#issuecomment-841647788
So, there would definitely be some difference there, to test like with like you need to delete terser cache after each run using;
rm -rf node_modules/.cache/terser-webpack

❯ nx report
  Node : 14.17.0
  OS   : darwin x64
  npm  : 6.14.13

  @nrwl/angular : 12.3.3
  @nrwl/cli : 12.3.3
  @nrwl/cypress : 12.3.3
  @nrwl/devkit : 12.3.3
  @nrwl/eslint-plugin-nx : 12.3.3
  @nrwl/express : 12.3.3
  @nrwl/jest : 12.3.3
  @nrwl/linter : 12.3.3
  @nrwl/node : 12.3.3
  @nrwl/tao : 12.3.3
  @nrwl/workspace : 12.3.3
  typescript : 4.2.4

Using Angular Material with "sass": "1.32.13",
And using a component lib (tkp-ddm-lib) with Customised Angular Material components (NG 11 non Ivy)

gupo_ng12.cpuprofile.zip

@the-ult, from the profiler at appears that it might be caused by NX. Can you replicate using only the Angular CLI?

Don't know how atm. Since it automatically uses the nx build command. 🤔

Build is indeed faster (more the as V11) 👍
Now: 49.728mswas 156.175ms with v12.0.0

I've just upgraded a project to 12.0.1 and I'm seeing significant increases in serve/build times. I've recorded profiles of both v11 and v12 and I'm seeing a suspicious gap in v12 where the process is mostly idle .
Angular 12 profile: https://www.file.io/download/tr8wrukOKzKh

Here's I've zoomed in on a bit in the mostly empty gap section:

Angular 11 profile for comparison: https://www.file.io/download/3t39VkJLfeat

@cypressious, can you please re-upload the files? I am trying to look into this but I am getting the following error file.io The file you requested has been deleted

@alan-agius4 please try https://filehorst.de/d/dvgbldhr. Sorry for the crappy file hoster, don't know where else to upload the file.

I've just upgraded a project to 12.0.1 and I'm seeing significant increases in serve/build times. I've recorded profiles of both v11 and v12 and I'm seeing a suspicious gap in v12 where the process is mostly idle .
Angular 12 profile: https://www.file.io/download/tr8wrukOKzKh

Here's I've zoomed in on a bit in the mostly empty gap section:

Angular 11 profile for comparison: https://www.file.io/download/3t39VkJLfeat

Still really slow with 12.0.1 and a breaking Issue with zIndex CSS Parsing

@alan-agius4 please try https://filehorst.de/d/dvgbldhr. Sorry for the crappy file hoster, don't know where else to upload the file.
Alternative link that expires in 7 days: https://www.dropbox.com/t/35SR07Q2zYOTWIYa

Is that the full profile? I am seeing a different from the one shown above. Pretty much I am not seeing anything in the first 4 seconds.

@alan-agius4 Yet, that's the one. This is how it looks when I load it in Chrome's Node.js DevTools:

Which tool are you using?

Chrome’s profiler

I'm doing the following:

Open chrome://inspect
Click the Open dedicated DevTools for Node link
Click Load and select the file

@cypressious, I re-downloaded the file from Dropbox and now I can see the same thing.  Will investigate this more tomorrow.

That gap is the time taken by terser (the JS optimizer). Webpack runs terser in workers which causes the main thread to remain idle while the optimizer works since there is nothing left for the build process to do at that point (barring the final write to disk).

Why do we need optimization in dev mode?

Why do we need optimization in dev mode?

So I have been wondering whether the switch to prod builds by default could have affected development builds. I believe that the CLI performs a migration of angular.json to switch the builder options to be targeting development mode as before, but maybe there are cases where the project ends up being misconfigured.

A production (or development) build is defined purely by the options present in the configuration section.  If the above build was not intended to be a production build then the project configuration may be incorrect.

Are you using 3rd party builders by any chance?

Thank you for ideas.
I didn't run ng-update on the project in question. I was under the impression that upgrading the dependencies in the package.json was enough. My bad. I'll try reverting and running ng-update and will report back if it helped.

The https://update.angular.io site can provide update instructions and guidance when updating between Angular versions.

When doing the ng update, I also noticed that it added production by default but it never added these to build/serve and I had to add them myself:
"defaultConfiguration": "development"

production by default is an optional migration.  The migration that is run automatically adjusts the options to maintain the previous development by default behavior because several of the options had default values swapped.

As for the source mapping performance regression: I tracked it down to a change in Webpack 5 and opened webpack/webpack-sources#109, which implements a proposal to resolve the regression. I'm not sure if the changes in that PR are entirely desirable so we'll see where it gets us.

Can anyone show me how to use NG_BUILD_CACHE=0, where to add this parameter?  I am also getting crashes after upgrading to 12.0.1, build time is much longer and getting crashes due to memory issue.

I can confirm that following the upgrade instructions migrated the angular.json and fixed the problem.
For those interested, it added
"aot": false,
"vendorChunk": true,
"extractLicenses": false,
"buildOptimizer": false,
"sourceMap": true,
"optimization": false,
"namedChunks": true

to projects.app.architect.build.options.

I can confirm that following the upgrade instructions migrated the angular.json and fixed the problem.
For those interested, it added
"aot": false,
"vendorChunk": true,
"extractLicenses": false,
"buildOptimizer": false,
"sourceMap": true,
"optimization": false,
"namedChunks": true

to projects.app.architect.build.options.

I had the same config except aot:false , aot is defaulted to true, and it worked no problem in V11, why should we turn it off in V12?

The migration adjusts the options to provide equivalent behavior from prior to the update.  The set of options and their values may be different for each project depending on the starting options.

The recommended way is "aot": true
Right?

When I migrated my AOT was true before and set to false. I had to manually set to back to true

Running that "optional" migration didn't improve anything for my app in CI but changing to use an Ubuntu build agent vs the windows build agent did improve time a bit, but the builds are still considerably slower for my azure devops pipelines on 12.0.1 than 11.x

The migration run during the recommended update process is not the optional migration.  There is also an optional production-by-default migration available in v12 that changes the configuration to cause ng build to build for production and ng serve to build for development.  This optional migration can be executed via:
ng update @angular/cli --migrate-only production-by-default

I tried to adjust all possible parameters and didn't help much on the memory usage for V12. I had to revert back to V11 for my project. Hoping there will be a solution for the next release

With the "@angular-devkit/build-angular": "12.0.1", (and 12.0.2) somehow the build fails on gitlab when using NX
@see https://github.com/nrwl/nx/issues/5729

Yes. That migration is not idempotent.  However, that would only apply if the project was previously using prerelease versions of v12 or the automatic migration was specifically rerun with the “—migrate-only” option.  The former requires special care regardless due to migration changes (potentially breaking) prior to a stable release; and the later is only recommended if “ng update” was not used to update the package versions.

v12.0.3 does have a slight improvement now (i guess because of the fix in webpack about the sourcemaps?)
but the improvement is like 5%, for the testcase in #20989 (v12: 100s -> 95s, v11: 50s)
The double compile in watch mode is gone but still the watch mode itself, when changing a file, is much slower
it seems that the "sealing" phase is the one that really takes a lot of time for me.

@jcompagner,
I looked at your repo and I don't see that much of gap between v11 and v12, in rebuilds I did see a big difference, but not as described. What I noticed was that re-builds were faster in v12.

First build without any disk cache rm -rf node_modules/.cache took ~121s in v11 and ~134s v12.
Second cold build took ~53s in v11, ~58s in v12.
Incremental re-build in v11 took 16.5s, in v12 the same change takes ~7.7s. (Note: my change was something that effects the output such as changing a string value)

right you are correct with incremental build when you actually are inserting code..
but for the rest, i did do a retest: (now with 12.0.3)
"
V12
12.zip
: i start with
npm install
npm run build (with ngcc compile): 158s
npm run build (second time): 94s
npm run build (third time): 94s
npm run build_debug: 111s
adding "console.log("test");" to src\sablo\sablo.service.ts  constructor: 10s
removing "console.log("test");" to src\sablo\sablo.service.ts  constructor: 7.4s
npm run build_debug (second time): 46s
adding "console.log("test");" to src\sablo\sablo.service.ts  constructor: 9.6s
removing "console.log("test");" to src\sablo\sablo.service.ts  constructor: 7.0s
V11:
11.zip
i start with
npm install
npm run build (with ngcc compile): 159s
npm run build (second time): 46s
npm run build (third time): 47s
npm run build_debug: 106s
adding "console.log("test");" to src\sablo\sablo.service.ts  constructor: 17s (for some reason it also generated styles again)
removing "console.log("test");" to src\sablo\sablo.service.ts  constructor: 14s
npm run build_debug (second time): 45s
adding "console.log("test");" to src\sablo\sablo.service.ts  constructor: 18s  (for some reason it also generated styles again)
removing "console.log("test");" to src\sablo\sablo.service.ts  constructor: 16s
"
so yes adding a console.log() statement is slower in v11, and an empty line is for some reason a lot faster..
But still the actual production build is way slower for me. (after ngcc because the it seems to be the same)
i see you are on linux, i am on windows. could that be the big difference?
i will ask a co worker to have the same test for me also on linux

Can you run those production cases with the environment variable NG_BUILD_CACHE set to 0?

that doesn't matter for me
tested this now also on Ubuntu on WSL2 under windows 10 but the numbers also there are the same (with our without that NG_BUILD_CACHE)

v11 caches the result of the optimizer (terser) but v12 (with Webpack 5) does not. There should definitely be a difference with the v11 numbers.

ah you want to slow down 11
yes by using that 11 is as slow as 12
same under linux:
11:
Build at: 2021-06-03T13:08:11.899Z - Hash: 70cb17ecb1f07c22904b - Time: 197106ms
Build at: 2021-06-03T13:09:50.550Z - Hash: 70cb17ecb1f07c22904b - Time: 55809ms
Build at: 2021-06-03T13:12:58.205Z - Hash: 70cb17ecb1f07c22904b - Time: 53705ms
12:
Build at: 2021-06-03T13:16:39.392Z - Hash: 3891f04b7906cecddb79 - Time: 195291ms
Build at: 2021-06-03T13:18:59.888Z - Hash: 3891f04b7906cecddb79 - Time: 119048ms
Build at: 2021-06-03T13:21:28.220Z - Hash: 3891f04b7906cecddb79 - Time: 119192ms
with NG_BUILD_CACE=0
11:
Build at: 2021-06-03T13:31:57.442Z - Hash: 70cb17ecb1f07c22904b - Time: 121182ms
12:
Build at: 2021-06-03T13:26:28.629Z - Hash: 3891f04b7906cecddb79 - Time: 124241ms

If you still have Problems, try to run:
ng update @angular/cli --migrate-only --from 11 --to 12

I ended upp generating a new v12 app and migrated all the app code manually. Took a while but now build-times are better than ever.

If you still have Problems, try to run:
ng update @angular/cli --migrate-only --from 11 --to 12

i don't get this, should i do that?
on what an already converted to 12? if i do that then aot:false  is added and nothing more
which is just bogus (i thought this was fixed but i am using 12.03 and i still get that)

For anyone struggling with ng serve times the following may help if you're only working on a subset of your application at a time.
Create a new build configuration architect/build/configurations/quick in angular.json
     "quick": {

          "aot": false,

          "styles": [
            "src/styles.min.css"
          ],

          "sourceMap": false,

          "fileReplacements": [
            {
              "replace": "src/app/app-routing.module.ts",
              "with": "src/app/app-routing.module.quick.ts"
            }
          ]
        }

Under architect/serve/configurations add:
        "quick": {
            "browserTarget": "DEFENDER:build:development,quick"
        }

Notice that this targets both development and quick.
Then pick and choose from the options shown above:

aot - disable for a faster build. I strongly recommend testing with a normal development build regularly to avoid surprises.
styles - create a styles file to avoid having to compile your sass every time (this only saved me a couple seconds). More important if you're using something like Material components.
sourceMap - disable sourceMap for much faster build

Then the biggest saving:

fileReplacements - this replaces your app.routing with a cut down copy containing only the routes you're working on. It's a copy so you don't accidentally deploy it! Copy your main file, comment out the routes and comment out obsolete includes. This halved the time of my build and is very useful when working only on a small subset of my site. *

Run it with:
`ng serve -c quick`

I like explicitly calling it a quick build so as not mess with development settings.
And before anyone says 'but it's just the first build that is slow' - I know, but I have to do first builds frequently enough. Also I'm aware of nx which I tried, but it doesn't seem to help my case which is a single large project.

Tip:

It is quite likely that you will see a lot of compiler warnings if you comment out many routes in your file. This is to be expected, and is actually desirable. What it means is your dependency tree isn't optimal. It took me a few hours to fix mine. The primary problem was I'd often define an interface in the same file as a component and then reference that interface from another component in a different module (route). When typescript pulls in the interface for the second module it compiles the whole component file, which is not only unnecessary but results in errors since the component isn't imported in a module that is known. Took some time to fix, but I'm much happier with my file structure and build time after doing this.
Still hoping for webpack 5 and typescript improvements!!

If you still have Problems, try to run:
ng update @angular/cli --migrate-only --from 11 --to 12
If the Migration does not work:
angular.json -> projects -> app -> architect -> build-> options

            "scripts": [],
            "aot": false,
            "vendorChunk": true,
            "extractLicenses": false,
            "buildOptimizer": false,
            "sourceMap": true,
            "optimization": false,
            "namedChunks": true

Please note that the migration would not have set "aot: false"; I'd recommend keeping that turned on if at all possible.

Turning aot to false is not a good solution, that simply removes an important feature of CLI. If you had aot turned on with v11 and should keep it on for v12. The performance issue with ng serve is a separate issue.

It's this commit a fix (or possible could have positive impact) for this case?
https://github.com/angular/angular-cli/commit/f90a8324b46bd96e87a7b889a74aab432a391015
But what does it exactly mean that node modules just be immutable? Because angular will change it on the first build (ngcc compile) but will that be a problem ? Because this will be done already before webpack really starts to do it's thing right?

Version 12.1.0 has been released which contains several performance improvements. We also introduced an experimental file system cache which should improve cold builds quite a lot. You can opt-in using the NG_PERSISTENT_BUILD_CACHE=1 environment variable.
Please update using ng update @angular/cli @angular/core.
If the issue persist please report back providing one of the following;

CPU profile, memory snapshots and angular.json configuration
Reproduction (Even shared privately).

@alan-agius4 NG_PERSISTENT_BUILD_CACHE makes it a lot faster. Why isn't this the default? Are you waiting for a new major version release to enable it by default?

@alan-agius4 I'm seeing reductions from 40 > 30 seconds for my build with this change.
Given that this is experimental I'm assuming once in a while we might need to clear the cache.
Do you have any thoughts on how stable this feature is at this time?
For anyone curious, the cache is stored in node_modules\.cache\angular-webpack
Also for anybody on Windows this is the correct way to set environmental variables in Powershell.
$env:NG_PERSISTENT_BUILD_CACHE=1
ng serve

I am not seeing much improvement after upgraded to 12.1.0 comparing to 12.0.5. It's still slow if you compare to V11. However, hasn't crashed with OOM yet, will keep monitoring.  I am using cross env to set environment variable "cross-env NG_PERSISTENT_BUILD_CACHE=1 ng serve"

@zwjohn, if it’s still noticeable slower compared to v11, please provide one of the below as otherwise we’ll be unable to look into your issue.

CPU profiles for v11 and v12) and angular.json configuration
Reproduction (even shared privately).

@alan-agius4
For starter, here is a component that I removed a space from the ts file, it took 15-16 seconds to recompile for the first change while running ng serve, and around 10-11 seconds after first time. Note that all tests were just to remove a space from ts file. It was less than 5 seconds in V11. The reproduction for OOM is pretty hard to do, since there is no specific trigger I noticed, it happened a few times while making changes to the project during local development , it just crashed, however, it was with 12.05, not yet crashed for 12.1. I will continue to monitor.
My problem is with ng serve , the slow recompilation of ng serve is impacting development speed.
node v14.17.0
npm  v6.14.13
Lazy Chunk Files                                         | Names |      Size
****_module_ts.js | -     | 132.76 kB
60 unchanged chunks
Build at: 2021-06-26T02:07:18.541Z - Hash: f27b25b4ae1c532eca8b - Time: 15864ms
√ Compiled successfully.
Build and Serve configuration in angular.json, I will monitor about OOM crash.
                           "build": {
                           "builder": "@angular-devkit/build-angular:browser",
                           "options": {
                               "aot": true,
                               "outputPath": "dist",
                               "index": "src/index.html",
                               "main": "src/main.ts",
                               "polyfills": "src/polyfills.ts",
                               "tsConfig": "tsconfig.app.json",

                               "assets": [
                                   "src/assets/favicon/favicon.ico",
                                   "src/assets/favicon/favicon-16x16.png",
                                   "src/assets/favicon/favicon-32x32.png",
                                   "src/assets/favicon/favicon.ico",
                                   "src/assets",
                                   {
                                       "glob": "_redirects",
                                       "input": "src",
                                       "output": "/"
                                   },
                                   "src/manifest.webmanifest"
                               ],
                               "styles": [
                                   "src/styles.scss",
<EMAIL_ADDRESS>                              ],
                               "scripts": [],
                               "allowedCommonJsDependencies": [
                                   "lodash",
                                   "@swimlane/dragula",
                                   "chart.js",
                                   "angular-calendar",
                                   "calendar-utils/date-adapters/date-fns",
                                   "contra/emitter",
                                   "crossvent",
                                   "dom-plane",
                                   "dom-set",
                                   "@mattlewis92/dom-autoscroller",
                                   "dragula"
                               ]
                           },
                           "configurations": {
                               "production": {
                                   "budgets": [
                                       {
                                           "type": "initial",
                                           "maximumWarning": "5mb",
                                           "maximumError": "8mb"
                                       },
                                       {
                                           "type": "anyComponentStyle",
                                           "maximumWarning": "150kb",
                                           "maximumError": "200kb"
                                       }
                                   ],
                                   "fileReplacements": [
                                       {
                                           "replace": "src/environments/environment.ts",
                                           "with": "src/environments/environment.prod.ts"
                                       }
                                   ],
                                   "outputHashing": "all",
                                   "serviceWorker": true,
                                   "ngswConfigPath": "ngsw-config.json",
                                   "optimization": true,
                                   "sourceMap": false,
                                   "extractCss": true,
                                   "namedChunks": false,
                                   "extractLicenses": true,
                                   "vendorChunk": false,
                                   "buildOptimizer": true
                               },

                               "development": {
                                   "buildOptimizer": false,
                                   "optimization": false,
                                   "vendorChunk": true,
                                   "extractLicenses": false,
                                   "sourceMap": true,
                                   "namedChunks": true
                               }
                           },
                           "defaultConfiguration": "production"
            },
           "serve": {
                "builder": "@angular-devkit/build-angular:dev-server",
                "options": {
                    "browserTarget": "build"
                },
                "configurations": {
                    "production": {
                        "browserTarget": "build:production"
                    },
                    "development": {
                        "browserTarget": "build:development"
                    }
                },
                "defaultConfiguration": "development"
            },

package.json Angular related libs
"dependencies": {
"@angular-eslint/schematics": "12.1.0",
"@angular-material-components/datetime-picker": "6.0.3",
"@angular-material-components/moment-adapter": "6.0.0",
"@angular/animations": "12.1.0",
"@angular/cdk": "12.1.0",
"@angular/common": "12.1.0",
"@angular/compiler": "12.1.0",
"@angular/core": "12.1.0",
"@angular/flex-layout": "12.0.0-beta.34",
"@angular/forms": "12.1.0",
"@angular/material": "12.1.0",
"@angular/material-moment-adapter": "12.1.0",
"@angular/platform-browser": "12.1.0",
"@angular/platform-browser-dynamic": "12.1.0",
"@angular/router": "12.1.0",
"@angular/service-worker": "12.1.0",
}
"devDependencies": {
"@angular-devkit/build-angular": "12.1.0",
"@angular/cli": "12.1.0",
"@angular/compiler-cli": "12.1.0",
"@angular/language-service": "12.1.0",
"@angularclass/hmr": "3.0.0",
"@types/dompurify": "2.2.2",
"@types/jasmine": "3.7.7",
"@types/jquery": "^3.5.5",
"@types/lodash": "4.14.170",
"@types/node": "15.12.2",
"@types/prismjs": "1.16.5",
"codelyzer": "6.0.2",
"cross-env": "7.0.3",
"jasmine-core": "3.7.1",
"jasmine-spec-reporter": "7.0.0",
"karma": "6.3.4",
"karma-chrome-launcher": "3.1.0",
"karma-jasmine": "4.0.1",
"karma-jasmine-html-reporter": "1.6.0",
"protractor": "7.0.0",
"replace-in-file": "6.2.0",
"ts-node": "10.0.0",
"tslint": "6.1.3",
"typescript": "4.2.4",
"webpack-bundle-analyzer": "4.4.2"
}
I tried to generate CPU profile by using NG_BUILD_PROFILING=1 and kept getting errors, and it builds fine without setting this environment variable
Option "extractCss" is deprecated: Deprecated since version 11.0. No longer required to disable CSS extraction for HMR.

Generating browser application bundles (phase: setup)...(node:33576) [DEP_WEBPACK_COMPILATION_NORMAL_MODULE_LOADER_HOOK] DeprecationWarning: Compilation.hooks.normalModuleLoader was move
d to NormalModule.getCompilationHooks(compilation).loader
(Use node --trace-deprecation ... to show where the warning was created)
Generating browser application bundles (phase: building)...npm ERR! code ELIFECYCLE
npm ERR! errno<PHONE_NUMBER>
18 verbose stack     at EventEmitter. (C:\Users\zwjoh\AppData\Roaming\nvm\v14.17.0\node_modules\npm\node_modules\npm-lifecycle\index.js:332:16)
18 verbose stack     at EventEmitter.emit (events.js:376:20)
18 verbose stack     at ChildProcess. (C:\Users\zwjoh\AppData\Roaming\nvm\v14.17.0\node_modules\npm\node_modules\npm-lifecycle\lib\spawn.js:55:14)
18 verbose stack     at ChildProcess.emit (events.js:376:20)
18 verbose stack     at maybeClose (internal/child_process.js:1055:16)
18 verbose stack     at Process.ChildProcess._handle.onexit (internal/child_process.js:288:5)

To generate a build profile you can you use the below.
node -—cpu-proof<EMAIL_ADDRESS>serve

If are are comparing rebuild times, try to do something meaningful such as changing a string value adding a console.log or something that effects the final bundle, adding only a space in a file will indeed be slower in v12.
Also, the first rebuild will always be slower than later rebuilds.
Side note: it appears that you are experiencing a different issue from the original reported were it was related to increase in non incremental build times. Therefore, I do suggest to open an new issue to for your problem and provide all the necessary info and keep this issue focused on the original reported problem.

Still can't build in prod mode on my project ... JS heap out of memory, works in v11.
How can I help you ? This is a private project for a company I'm working for, I am unable to share it with you unfortunately.

Version 12.1.0 has been released which contains several performance improvements. We also introduced an experimental file system cache which should improve the second/warm build quite a lot. You can opt-in using the NG_PERSISTENT_BUILD_CACHE=1 environment variable.
Please update using ng update @angular/cli @angular/core.
If the issue persist please report back providing one of the following;

CPU profile, memory snapshots and angular.json configuration
Reproduction (Even shared privately).

I'm seeing a regression(?) with 12.1 and I'm not sure if I should open that separately or if it might be related to this. With 12.0 I was able to build whatever V8 decided was appropriate for a machine with 4GB of RAM, but with 12.1 I had to bump --max_old_space_size up to 3GB. It's possible we were almost at that line and an unrelated package update is what actually pushed us over the limit.
I have the CI running with NG_BUILD_CACHE=1 already (hopefully that makes sense). Is there something that NG_PERSISTENT_BUILD_CACHE=1 would provide over the other option?
I can try profiling, but I'll have to see when I'd have time to do that since bumping the memory is the bandaid I have time for right now :sweat_smile:

NG_BUILD_CACHE is enabled by default, and is mainly used to opt-out all build caching, this supersedes NG_PERSISTENT_BUILD_CACHE.
NG_PERSISTENT_BUILD_CACHE is disable by default, and can be used to opt-in to cache the entire build on disk, which will make the 2nd build warm.  Typically you don't want this on CI since typically the "cache" will be discarded with node_modules after every CI run.

That being said, this issue is about build times and not memory, hence if you are experiencing memory issues please file a new issue providing all the necessary profiles and/or a reproduction.

@Yohandah, let's please keep this issue on build times. If you are experiencing memory issues please file a new issue and attach the memory heap profiles for v11 and v12.
Thanks.

@alan-agius4 you closed the issue concerning build crashes and said it was now tracked here ........ ?

@Yohandah, are you referring to version 9 issue (https://github.com/angular/angular-cli/issues/16860#issuecomment-852031823)? I stated that this issue (https://github.com/angular/angular-cli/issues/20792) is for build-time performance.

@alan-agius4  Well could you reopen #16860 then ? the title says "& out of memory errors", and my issue is a memory error; or should I open a new issue ?

@alan-agius4 Well could you reopen #16860 then ? the title says "& out of memory errors", and my issue is a memory error; or should I open a new issue ?

Most of the context in #16860 is no longer relevant in version 12. Hence please open a new issue with profiles from v11 and v12. Thanks.

also for us using NG_PERSISTENT_BUILD_CACHE is a lot faster
production build goes from 80+ seconds to 20+ seconds
and also none production builds do gain like 28 seconds to 20 seconds.
so using that flag the production build are quite close to the none (debug) builds..

Unfortunately, we do not see much improvement with NG_PERSISTENT_BUILD_CACHE, I tried with and without but compared to 11.0.2 it's still much slower. I could live with production or even development build to be slower, but the much slower watch really hurts during development... :/

command
11.0.2
12.1.0
12.1.0 with NG_PERSISTENT_BUILD_CACHE 1st
12.1.0 with NG_PERSISTENT_BUILD_CACHE 2nd

develop build
~83s
~98s
~100s
~106s

production build
~180s
~270s
~240s
~225s

watch
~92s
140s + 48s*
106s + 43s*
-

recompile (main bundle**)
~13s
~22s
~21s
-

* initial watch always immediately triggers a recompile for whatever reason
** main bundle has about 6-7mb in watch mode
angular.json:
{
  "version": 1,
  "projects": {
    "app": {
      "projectType": "application",
      "schematics": {
        "@nrwl/angular:component": {
          "style": "less",
          "changeDetection": "OnPush"
        }
      },
      "root": "apps/app",
      "sourceRoot": "apps/app/src",
      "prefix": "app",
      "architect": {
        "build": {
          "builder": "@angular-builders/custom-webpack:browser",
          "options": {
            "customWebpackConfig": {
              "path": "apps/app/extra-webpack.config.js",
              "mergeStrategies": {
                "optimization.minimizer": "replace",
                "externals": "replace"
              }
            },
            "outputPath": "dist/apps/app",
            "index": "apps/app/src/index.html",
            "main": "apps/app/src/main.ts",
            "polyfills": "apps/app/src/polyfills.ts",
            "tsConfig": "apps/app/tsconfig.app.json",
            "preserveSymlinks": true,
            "aot": true,
            "allowedCommonJsDependencies": [
              "jstimezonedetect",
              "css-element-queries",
              "fastdom",
              "dragula",
              "contra/emitter",
              "crossvent",
              "dom-autoscroller",
              "dom-plane",
              "dom-set",
              "pdfjs-dist",
              "zone.js/dist/zone-error"
            ],
            "assets": [
              {
                "glob": "**/*",
                "input": "apps/app/src/assets/images",
                "output": "/images"
              },
              {
                "glob": "**/*",
                "input": "apps/app/src/assets/icons",
                "output": "/icons"
              },
              {
                "glob": "**/*",
                "input": "apps/app/src/assets/static",
                "output": "/static"
              },
              {
                "glob": "**/*",
                "input": "apps/app/src/assets/translations/messages",
                "output": "/translations"
              },
              {
                "glob": "properties.js",
                "input": "apps/app/src/assets/",
                "output": "/"
              },
              {
                "glob": "**/*",
                "input": "libs/annotations/src/assets/translations/messages",
                "output": "/translations/annotations"
              },
              {
                "glob": "**/*",
                "input": "node_modules/pdfjs-dist/cmaps",
                "output": "/worker-libs/pdf-cmaps/"
              },
              {
                "glob": "pdf.worker.min.js",
                "input": "node_modules/pdfjs-dist/build",
                "output": "/worker-libs/"
              },
              {
                "glob": "**/*",
                "input": "libs/common-components/src/assets/translations/messages",
                "output": "/translations/common"
              },
              {
                "glob": "**/*",
                "input": "libs/common-components/src/assets/images",
                "output": "/images"
              },
              {
                "glob": "**/*",
                "input": "libs/common-components/src/assets/icons",
                "output": "/icons"
              },
              {
                "glob": "**/*",
                "input": "libs/internal-components/src/assets/images",
                "output": "/images"
              }
            ],
            "scripts": [
              "node_modules/pdfjs-dist/build/pdf.min.js",
              "libs/annotations/src/assets/libs/fabric.js",
              "node_modules/systemjs/dist/s.js",
              "node_modules/systemjs/dist/extras/named-register.js",
              "node_modules/systemjs/dist/extras/amd.js"
            ],
            "stylePreprocessorOptions": {
              "includePaths": [
                "libs/common-components/src/assets/styles",
                "apps/app/src/assets/styles",
                "libs/app/shared/src/lib/assets/styles"
              ]
            },
            "styles": [
              "node_modules/quill/dist/quill.core.css",
              "node_modules/quill/dist/quill.bubble.css",
              "node_modules/quill/dist/quill.snow.css",
              "node_modules/pdfjs-dist/web/pdf_viewer.css",
              "node_modules/dragula/dist/dragula.min.css",
              "libs/common-components/src/assets/styles/material-theme-custom.less",
              "libs/common-components/src/assets/styles/app.less",
              "apps/app/src/assets/styles/styles.less",
              "apps/app/src/assets/styles/app-material.less"
            ]
          },
          "configurations": {
            "production": {
              "fileReplacements": [
                {
                  "replace": "apps/app/src/environments/environment.ts",
                  "with": "apps/app/src/environments/environment.prod.ts"
                }
              ],
              "optimization": {
                "scripts": false,
                "styles": true,
                "fonts": true
              },
              "outputHashing": "all",
              "sourceMap": false,
              "extractCss": true,
              "namedChunks": false,
              "extractLicenses": true,
              "vendorChunk": false,
              "buildOptimizer": true,
              "budgets": [
                {
                  "type": "initial",
                  "maximumWarning": "4mb"
                },
                {
                  "type": "anyComponentStyle",
                  "maximumWarning": "6kb",
                  "maximumError": "10kb"
                }
              ]
            },
            "development": {
              "buildOptimizer": false,
              "optimization": false,
              "vendorChunk": true,
              "extractLicenses": false,
              "sourceMap": true,
              "namedChunks": true
            }
          },
          "defaultConfiguration": "development"
        },
        "serve": {
          "builder": "@angular-devkit/build-angular:dev-server",
          "options": {
            "browserTarget": "app:build"
          },
          "configurations": {
            "production": {
              "browserTarget": "app:build:production"
            }
          }
        },
        "lint": {
          "builder": "@angular-devkit/build-angular:tslint",
          "options": {
            "tsConfig": [
              "apps/app/tsconfig.app.json",
              "apps/app/tsconfig.spec.json"
            ],
            "exclude": [
              "**/node_modules/**",
              "!apps/app/**/*"
            ]
          }
        },
        "test": {
          "builder": "@nrwl/jest:jest",
          "options": {
            "jestConfig": "apps/app/jest.config.js",
            "passWithNoTests": true,
            "silent": true
          }
        }
      }
    },
    "common-components": {
      "projectType": "library",
      "root": "libs/common-components",
      "sourceRoot": "libs/common-components/src",
      "prefix": "cc",
      "architect": {
        "build": {
          "builder": "@nrwl/angular:package",
          "options": {
            "tsConfig": "libs/common-components/tsconfig.lib.json",
            "project": "libs/common-components/ng-package.json"
          },
          "configurations": {
            "production": {
              "tsConfig": "libs/common-components/tsconfig.lib.prod.json"
            }
          }
        },
        "lint": {
          "builder": "@angular-devkit/build-angular:tslint",
          "options": {
            "tsConfig": [
              "libs/common-components/tsconfig.lib.json",
              "libs/common-components/tsconfig.spec.json"
            ],
            "exclude": [
              "**/node_modules/**",
              "!libs/common-components/**/*"
            ]
          }
        },
        "test": {
          "builder": "@nrwl/jest:jest",
          "options": {
            "jestConfig": "libs/common-components/jest.config.js",
            "passWithNoTests": true,
            "silent": true
          }
        },
        "storybook": {
          "builder": "@nrwl/storybook:storybook",
          "options": {
            "uiFramework": "@storybook/angular",
            "port": 4400,
            "config": {
              "configFolder": "libs/common-components/.storybook"
            }
          },
          "configurations": {
            "ci": {
              "quiet": true
            }
          }
        },
        "build-storybook": {
          "builder": "@nrwl/storybook:build",
          "options": {
            "uiFramework": "@storybook/angular",
            "outputPath": "dist/storybook/common-components",
            "config": {
              "configFolder": "libs/common-components/.storybook"
            }
          },
          "configurations": {
            "ci": {
              "quiet": true
            }
          }
        }
      },
      "schematics": {
        "@nrwl/angular:component": {
          "style": "less",
          "changeDetection": "OnPush"
        }
      }
    },
    "internal-components": {
      "projectType": "library",
      "root": "libs/internal-components",
      "sourceRoot": "libs/internal-components/src",
      "prefix": "ic",
      "architect": {
        "build": {
          "builder": "@nrwl/angular:package",
          "options": {
            "tsConfig": "libs/internal-components/tsconfig.lib.json",
            "project": "libs/internal-components/ng-package.json"
          },
          "configurations": {
            "production": {
              "tsConfig": "libs/internal-components/tsconfig.lib.prod.json"
            }
          }
        },
        "lint": {
          "builder": "@angular-devkit/build-angular:tslint",
          "options": {
            "tsConfig": [
              "libs/internal-components/tsconfig.lib.json",
              "libs/internal-components/tsconfig.spec.json",
              "libs/internal-components/.storybook/tsconfig.json"
            ],
            "exclude": [
              "**/node_modules/**",
              "!libs/internal-components/**/*"
            ]
          }
        },
        "test": {
          "builder": "@nrwl/jest:jest",
          "options": {
            "jestConfig": "libs/internal-components/jest.config.js",
            "passWithNoTests": true,
            "silent": true
          }
        },
        "storybook": {
          "builder": "@nrwl/storybook:storybook",
          "options": {
            "uiFramework": "@storybook/angular",
            "port": 4400,
            "config": {
              "configFolder": "libs/internal-components/.storybook"
            }
          },
          "configurations": {
            "ci": {
              "quiet": true
            }
          }
        },
        "build-storybook": {
          "builder": "@nrwl/storybook:build",
          "options": {
            "uiFramework": "@storybook/angular",
            "outputPath": "dist/storybook/internal-components",
            "config": {
              "configFolder": "libs/internal-components/.storybook"
            }
          },
          "configurations": {
            "ci": {
              "quiet": true
            }
          }
        }
      },
      "schematics": {
        "@schematics/angular:component": {
          "style": "less",
          "changeDetection": "OnPush"
        }
      }
    },
     "annotations": {
      "projectType": "library",
      "root": "libs/annotations",
      "sourceRoot": "libs/annotations/src",
      "prefix": "app",
      "architect": {
        "build": {
          "builder": "@nrwl/angular:package",
          "options": {
            "tsConfig": "libs/annotations/tsconfig.lib.json",
            "project": "libs/annotations/ng-package.json"
          },
          "configurations": {
            "production": {
              "tsConfig": "libs/annotations/tsconfig.lib.prod.json"
            }
          }
        },
        "lint": {
          "builder": "@angular-devkit/build-angular:tslint",
          "options": {
            "tsConfig": [
              "libs/annotations/tsconfig.lib.json",
              "libs/annotations/tsconfig.spec.json"
            ],
            "exclude": [
              "**/node_modules/**",
              "!libs/annotations/**/*"
            ]
          }
        },
        "test": {
          "builder": "@nrwl/jest:jest",
          "outputs": [
            "coverage/libs/annotations"
          ],
          "options": {
            "jestConfig": "libs/annotations/jest.config.js",
            "passWithNoTests": true,
            "silent": true
          }
        }
      }
    }
  },
  "cli": {
    "defaultCollection": "@nrwl/angular"
  },
  "schematics": {
    "@nrwl/angular:application": {
      "unitTestRunner": "jest",
      "e2eTestRunner": "cypress"
    },
    "@nrwl/angular:library": {
      "unitTestRunner": "jest"
    },
    "@nrwl/angular:component": {
      "style": "less"
    }
  }
}

System info:
OS Name:                   Microsoft Windows 10 Enterprise
OS Version:                10.0.19041 N/A Build 19041
OS Build Type:             Multiprocessor Free
System Type:               x64-based PC
Processor(s):              1 Processor(s) Installed.
                           [01]: Intel64 Family 6 Model 142 Stepping 10 GenuineIntel ~1792 Mhz
BIOS Version:              HP Q78 Ver. 01.06.00, 03.01.2019
Total Physical Memory:     32 611 MB

I could send the cpu profiles if needed, but I am not allowed to share them (or the repo) publicly. Just let me know where I should send them :)

@mrucelum, you are using builders which are not supported by the Angular tooling team. This causes a migration that adjusts the options to provide equivalent behavior from prior to the update not to run.  Ideally these 3rd party builders should provide their own migration.
For now you need to adjust the options to retain the existing behavior.  For more information, see the breaking changes section within the release notes: https://github.com/angular/angular-cli/releases/tag/v12.0.0

@alan-agius4 Thanks for link!
So if I understand you correctly, I have to adjust the configuration section of my angular.json manually, because I am using custom builders, right?
I checked the breaking changes and if I understand them correctly, with this addition to the angular.json:
          "configurations": {
           [...]
            "development": {
              "optimization": false,
              "buildOptimizer": false,
              "sourceMap": true,
              "extractLicenses": false,
              "namedChunks": true,
              "vendorChunk": true
            }
          },

I have the old default values (we had "aot": true before) already in place (when it comes to develop build and watch).
But this is the exact configuration I did my tests with. So I guess I am missing something in addition? Or does the custom builder need to adapt something (I mean something I cannot influence by just adapting my angular.json)?
Thanks again :)

In the above table, you mentioned watch are you using ng build --watch?, Can you also try to replace the 3rd party builder with a supported builder @angular-devkit/build-angular:browser?
You can send the CPU profiles to alan.agius4[at]gmail.com.

It seems to be indeed the @angular-builders/custom-webpack:browser that causes the slow down 😲
ng build --watch

with @angular-devkit/build-angular:browser

Initial Chunk Files                    | Names         |      Size
vendor.js                              | vendor        |   7.86 MB
main.js                                | main          |   6.66 MB
scripts.js                             | scripts       | 677.03 kB
polyfills.js                           | polyfills     | 213.39 kB
styles.css                             | styles        | 150.33 kB
runtime.js                             | runtime       |  14.33 kB

                                       | Initial Total |  15.55 MB
Build at: 2021-07-01T11:06:38.058Z - Hash: cd684dc7fcbc67560f0f - Time: 76208ms

with @angular-builders/custom-webpack:browser

Initial Chunk Files                    | Names         |      Size
vendor.js                              | vendor        |   6.67 MB
main.js                                | main          |   6.66 MB
scripts.js                             | scripts       | 677.03 kB
polyfills.js                           | polyfills     | 213.39 kB
styles.css                             | styles        | 150.33 kB
runtime.js                             | runtime       |  13.67 kB

                                       | Initial Total |  14.36 MB

Build at: 2021-07-01T11:43:51.105Z - Hash: 34bdac20b292943b28c9 - Time: 107267ms
√ Browser application bundle generation complete.
√ Index html generation complete.

15 unchanged chunks

Build at: 2021-07-01T11:44:36.147Z - Hash: e7860c484b03f51d78f9 - Time: 43856ms

with @angular-builders/custom-webpack:browser and without custom terser config in the referenced webpack config

Initial Chunk Files                    | Names         |      Size
vendor.js                              | vendor        |   6.67 MB
main.js                                | main          |   6.66 MB
scripts.js                             | scripts       | 677.03 kB
polyfills.js                           | polyfills     | 213.39 kB
styles.css                             | styles        | 150.33 kB
runtime.js                             | runtime       |  13.67 kB

                                       | Initial Total |  14.36 MB

Build at: 2021-07-01T11:12:49.818Z - Hash: 1ac2e18b2a871e0bf8a0 - Time: 103078ms
√ Browser application bundle generation complete.
√ Index html generation complete.

15 unchanged chunks

Build at: 2021-07-01T11:13:32.438Z - Hash: b8d53eea43833e670b2b - Time: 41681ms

with @angular-builders/custom-webpack:browser with empty webpack config

Initial Chunk Files                   | Names         |      Size
vendor.js                             | vendor        |   7.86 MB
main.js                               | main          |   6.66 MB
scripts.js                            | scripts       | 677.03 kB
polyfills.js                          | polyfills     | 213.39 kB
styles.css                            | styles        | 150.33 kB
runtime.js                            | runtime       |  13.67 kB

                                      | Initial Total |  15.55 MB

Build at: 2021-07-01T11:17:38.033Z - Hash: 223bbb0d807f62d6e34f - Time: 109983ms
√ Browser application bundle generation complete.
√ Index html generation complete.

15 unchanged chunks

Build at: 2021-07-01T11:18:26.881Z - Hash: b76731d2fe86fcc023e6 - Time: 47707ms

btw this is the custom webpack config:
const webpack = require('webpack');
const TerserPlugin = require('terser-webpack-plugin');

module.exports = {
  externals: {
    'fabric': 'window'
  },

  plugins: [new webpack.ContextReplacementPlugin(/moment[\/\\]locale$/, /en|de/)],
  optimization: {
    minimizer: [new TerserPlugin({
                                   terserOptions: {
                                     ecma: undefined,
                                     warnings: false,
                                     parse: {},
                                     compress: {},
                                     mangle: true, // Note `mangle.properties` is `false` by default.
                                     module: false,
                                     output: null,
                                     toplevel: false,
                                     nameCache: null,
                                     ie8: false,
                                     keep_classnames: true,
                                     keep_fnames: false,
                                     safari10: false
                                   },
                                 })]
  }
};

Conclusion:

with the default angular builder
a. times are the same as with v11 (or even a bit better)
b. there is no immediate recompile on watch 🥳
with the custom-webpack builder
a. it takes much longer even if the custom webpack config does not contain anything
b. bundle is quite a bit smaller because of moment locale exclusion

However... we need the custom webpack config as we do not want to have all the unnecessary moment locales in our bundle and also need to be able to specify 'fabric' as external for some legacy lib we are using.
So I guess I will head over to the @angular-builders/custom-webpack:browser project and file an issue there.
Thanks a lot @alan-agius4 !

Success! I found steps to get good performance when using @angular-builders/custom-webpack
TLDR; before upgrading angular, remove all traces of custom-webpack so the migrations run in full, and then re-install custom-webpack
Here is what worked for me, starting with an Angular 11 project:

In angular.json, replaced all traces of @angular-builders/custom-webpack:browser with @angular-devkit/build-angular:browser (and delete the customWebpackConfig block)
Removed @angular-builders/custom-webpack from package.json
Deleted node_modules and package_lock.json
Ran npm install
Ran ng update @angular/cdk @angular/cli @angular/core
Added v12 of @angular-builders/custom-webpack back into package.json
Ran npm install
In angular.json, changed back to @angular-builders/custom-webpack:browser and restored the customWebpackConfig block.

I confirmed that the migrations in angular.json (that were getting skipped) make the difference (2x slower ng serve build time)
Benchmarking gives similar results as with angular 11 and markedly better results when I use NG_PERSISTENT_BUILD_CACHE=1
Like @mrucelum our project uses @angular-builders/custom-webpack to specify several packages as externals (legacy code needs the package as well, so don't want to double load them)  Is there any chance ng update could do migrations when custom-webpack is in use?  Or the ability to specify external packages without using custom-webpack?  Thanks everyone for the info that lead me to this solution!

@mrucelum Thanks for all the stats. I'm actually using @angular-builders/custom-webpack:browser too and for the exact same reason (moment.js size).  However I just ran a dozen builds and with or without the custom builder it was taking 38-40 seconds each time. And it definitely did change because it told me to remove the part of the config that was due to the custom builder.
As I was writing this though I saw you managed to get them working.
Hoever, can you confirm that running the migrations did not in fact disable AOT compilation. Depending upon your exact version of the CLI it's possible to end up disabling it when running migrations (due to a change in what was considered the default). If you in fact did disable AOT then that would explain the much faster compilation.

NG_BUILD_CACHE is enabled by default, and is mainly used to opt-out all build caching, this supersedes NG_PERSISTENT_BUILD_CACHE.
NG_PERSISTENT_BUILD_CACHE is disable by default, and can be used to opt-in to cache the entire build on disk, which will make the 2nd build warm.  Typically you don't want this on CI since typically the "cache" will be discarded with node_modules after every CI run.

That being said, this issue is about build times and not memory, hence if you are experiencing memory issues please file a new issue providing all the necessary profiles and/or a reproduction.

Thanks @alan-agius4  for the explanation and sorry you'll probably end up marking this "off topic", but maybe not since it is about NG_PERSISTENT_BUILD_CACHE and I do care about any build speed improvements I can get since my build does seem slow to me.
I reviewed https://github.com/angular/angular-cli/pull/20756 to confirm I understood and I wasn't taking a corner case that was unexpected. I use NG_BUILD_CACHE to point to a directory that is external to the node modules and in a location the CI will preserve, and this looks like it's still OK to do based on https://github.com/angular/angular-cli/blob/736a5f89deaca85f487b78aec9ff66d4118ceb6a/packages/angular_devkit/build_angular/src/utils/environment-options.ts#L70-L81 does that mean I should also be able to turn on NG_PERSISTENT_BUILD_CACHE in order to persist the webpack cache? I noticed this was said to be experimental, but any reason I might not want to turn it on in this context? It looks like the cache key is pretty comprehensive and I would think the serialized build options should probably be good :thinking:

This actually looks to really help a lot for my build time :tada: , but I've found a few errors and I'm reporting them (and fixing the one I can fix simply)

After upgrading from Angular 11 to Angular 12 the build time went up from ~1 second to 22 seconds 🤯
https://github.com/whyboris/Video-Hub-App/pull/648

@whyboris It doesn't for me:

Is there a particular change I should be making?

@JoostK thank you for testing! I was so frustrated I quit for the day, but thanks to your message I had new hope 😅
I ran rm -rf node_modules and npm install again and it looks like I'm back to fast 🚀
Build at: 2021-07-07T20:46:38.298Z - Hash: f2c33b8ef37564ec1ef0 - Time: 1713ms 🙇
Sorry for the scare 🙇

@whyboris Thanks for getting back. Good to hear it's fast again, hopefully it stays that way. If you do run into it again please report back so we can have another look.

🤦 sorry -- the reload was fast because I simply saved the file with no changes ... but when I add console.log somewhere - thereby changing the file, the compilation takes a long time again:
Build at: 2021-07-07T20:50:32.591Z - Hash: 0a430155980e29d73d08 - Time: 23324ms 😢

@whyboris Oh, it's just a misconfiguration. In Angular 12 some builder defaults have changed in support of the new production builds by default for ng build. I am not sure how you updated but I don't see any changes to angular.json in the pull request; ng update should have updated it to pin the configuration options to their prior defaults to retain the previous behavior. If I run ng update @angular/cli --migrate-only --from 11 --to 12 then the angular.json file is indeed updated. Please review the changes as I notice in your case that aot is set to false, which you may not want.

@JoostK thank you very much for the suggestion!
I went back to my main branch (before my attempt to upgrade to angular 12) and ran the command you gave:
ng update @angular/cli --migrate-only --from 11 --to 12
It updated my angular.json file and now the app recompiles quickly after every save 🚀
https://github.com/whyboris/Video-Hub-App/pull/666/files
Thank you 🤝 🙇 ❤

@whyboris it seems like you set "aot": false which should be set to true (if I'm not misstaken)

Just wanted to let you know that I did the migration again the way @DavidBowdoin suggested (remove custom builder before ng update).
Aaaand there is no slowdown anymore! 🥳
Not sure what the issue was, maybe it was actually fixed with the newest version of the custom webpack builder (as @simeyla suggested). My angular.json was not touched by the migration at all (although I removed the custom builder before the migration!), so I guess that was not the problem.
But anyway, I am happy that we can update now!
Thanks again everyone! :)

Seems this blog solved this issue https://dev.to/brandontroberts/speeding-up-the-development-serve-after-upgrading-to-angular-v12-5db5

Removing "emitDecoratorMetadata": true from tsconfig.json reduced our build time significantly.

Success! I found steps to get good performance when using @angular-builders/custom-webpack
TLDR; before upgrading angular, remove all traces of custom-webpack so the migrations run in full, and then re-install custom-webpack
Here is what worked for me, starting with an Angular 11 project:

In angular.json, replaced all traces of @angular-builders/custom-webpack:browser with @angular-devkit/build-angular:browser (and delete the customWebpackConfig block)
Removed @angular-builders/custom-webpack from package.json
Deleted node_modules and package_lock.json
Ran npm install
Ran ng update @angular/cdk @angular/cli @angular/core
Added v12 of @angular-builders/custom-webpack back into package.json
Ran npm install
In angular.json, changed back to @angular-builders/custom-webpack:browser and restored the customWebpackConfig block.

I confirmed that the migrations in angular.json (that were getting skipped) make the difference (2x slower ng serve build time)
Benchmarking gives similar results as with angular 11 and markedly better results when I use NG_PERSISTENT_BUILD_CACHE=1
Like @mrucelum our project uses @angular-builders/custom-webpack to specify several packages as externals (legacy code needs the package as well, so don't want to double load them) Is there any chance ng update could do migrations when custom-webpack is in use? Or the ability to specify external packages without using custom-webpack? Thanks everyone for the info that lead me to this solution!

This solved my issue! Thanks :)


GitLab-CI Pipeline Error with PHPUnit

Hi,
I try to build/test/deploy a project through gitlab-ci pipeline, the following is my .gitlab-ci.yml:
stages:

build
test
deploy

image: hitalos/laravel:latest
services:
  - mysql:5

variables:
  MYSQL_DATABASE: "____"
  MYSQL_ROOT_PASSWORD: "____"

composer:
  stage: build
  # cache:
  #   key: ${CI_COMMIT_REF_SLUG}-composer
  #   paths:
  #     - vendor/
  script:
      - composer install --prefer-dist --no-ansi --no-interaction --no-progress --no-scripts
      - cp .env.example .env
  artifacts:
    expire_in: 30 mins
    paths:
      - vendor/
      - fjord/
      - .env

phpunit:
  stage: test
  dependencies:
    - composer
  script:
    - php artisan key:generate
    - php artisan fjord:install
    - php artisan migrate --force
    - phpunit --coverage-text --colors=never

publish:
  stage: deploy
  image: ubuntu
  only:
    - master
  script:
    - 'which ssh-agent || ( apt-get update -y && apt-get install openssh-client -y )'
    - eval $(ssh-agent -s)
    - echo "$SSH_PRIVATE_KEY" | tr -d '\r' | ssh-add - > /dev/null
    - mkdir -p ~/.ssh
    - chmod 700 ~/.ssh
    - echo "$SSH_KNOWN_HOSTS" > ~/.ssh/known_hosts
   # shortened because not relevant

test-case is the following:
public function testBasicTest()     {         $response = $this->get('/');         dump($response->content());         $response->assertStatus(200);     }
(dump is only here to understand whats happening, normally test result is 200 != 500)
and routes/web.php is the following (shortened):
use Fjord\Support\Facades\Form; Route::get('/', function () {     return view('welcome')->with([         'data' => Form::load('pages', 'home')     ]); });
So i get the following error:
Illuminate\Contracts\Container\BindingResolutionException: Target class [fjord.form] does not exist. in file /builds/gooze/ostfjord/vendor/laravel/framework/src/Illuminate/Container/Container.php on line 807

to clear things out: I only got this Problem when running a pipeline in gitlab ci. using the same docker image locally and doing the same steps i pass all tests without any problem...

Illuminate\Contracts\Container\BindingResolutionException: Target class [fjord.form] does not exist. in file /gitlab_build/vendor/laravel/framework/src/Illuminate/Container/Container.php on line 807

#0 /gitlab_build/vendor/laravel/framework/src/Illuminate/Container/Container.php(687): Illuminate\Container\Container->build('fjord.form')

#1 /gitlab_build/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(796): Illuminate\Container\Container->resolve('fjord.form', Array, true)\n
#2 /gitlab_build/vendor/laravel/framework/src/Illuminate/Container/Container.php(633): Illuminate\Foundation\Application->resolve('fjord.form', Array)

#3 /gitlab_build/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(781): Illuminate\Container\Container->make('fjord.form', Array)

#4 /gitlab_build/vendor/laravel/framework/src/Illuminate/Container/Container.php(1280): Illuminate\Foundation\Application->make('fjord.form')

#5 /gitlab_build/vendor/laravel/framework/src/Illuminate/Support/Facades/Facade.php(198): Illuminate\Container\Container->offsetGet('fjord.form')

#6 /gitlab_build/vendor/laravel/framework/src/Illuminate/Support/Facades/Facade.php(166): Illuminate\Support\Facades\Facade::resolveFacadeInstance('fjord.form')

#7 /gitlab_build/vendor/laravel/framework/src/Illuminate/Support/Facades/Facade.php(255): Illuminate\Support\Facades\Facade::getFacadeRoot()

#8 /gitlab_build/routes/web.php(19): Illuminate\Support\Facades\Facade::__callStatic('load', Array)

#9 /gitlab_build/vendor/laravel/framework/src/Illuminate/Routing/Route.php(225): Illuminate\Routing\RouteFileRegistrar->{closure}()

#10 /gitlab_build/vendor/laravel/framework/src/Illuminate/Routing/Route.php(199): Illuminate\Routing\Route->runCallable()

#11 /gitlab_build/vendor/laravel/framework/src/Illuminate/Routing/Router.php(685): Illuminate\Routing\Route->run()

From the error message I can see that the form facade is called in a route but is not yet registered.
#8 /gitlab_build/routes/web.php(19): Illuminate\Support\Facades\Facade::__callStatic('load', Array)

The facade is registered if the namespace FjordApp exists. Actually the fjord:install command should create the namespace. You can try to manually enter composer dumpautoload to reload the namespaces. Maybe this will solve the issue.
script:
    - php artisan key:generate
    - php artisan fjord:install
    - composer dumpautoload
    - php artisan migrate --force
    - phpunit --coverage-text --colors=never

@cbl this does not fix it.... but thanks for the suggestion

okay, i'm getting forward with it:

okay, im getting forward:
  script:
    - php artisan fjord:install
    - composer dump-autoload
    - php artisan migrate:fresh --force
    - sleep 10
    - phpunit --coverage-text --colors=never

seems he's finding the facade now.now i get database error:
Illuminate\Database\QueryException: SQLSTATE[HY000]: General error: 1 no such table: form_fields (SQL: select * from "form_fields" where "collection" = pages and "form_name" = home) in file /builds/gooze/ostfjord/vendor/laravel/framework/src/Illuminate/Database/Connection.php
i think this has nothing to do with FJORD, but with gitlab-ci.... but maybe you can help ;) otherwise please just close...

okay, for the ones of you that are interested:
when you do this
Route::get('/', function () {
    return view('welcome')->with([
        'data' => Form::load('pages', 'home')
    ]);
});

in your routes file, make sure to add use RefreshDatabase; to your test file:
class ExampleTest extends TestCase
{

    use RefreshDatabase;

    /**
     * A basic test example.
     *
     * @return void
     */
    public function testBasicTest()
    {
        $response = $this->get('/');
        $response->assertStatus(200);
    }
}

otherwise you'll loose hours of time... like i did.


TextEditor.getPath only providing realpath

Currently TextEditor.getPath returns the realpath of the file. When a project directory contains symlinks somewhere under it it becomes impossible to decide which project root a specific file belongs to. Please see noseglid/atom-build#245 for a longer explanation of the use case as well as an example folder hierarchy.
The only way to make a correlation between a TextEditor and a project root requires the TextEditor to provide the non-real path of the file.
Getting the realpath from the non-real path is trivial (fs.realpath())) but the other way around is simply not possible.

@atom/feedback thoughts on this? I'm not familiar with a foolproof way to associate a TextEditor to a project path - I can see the benefit of adding a getter for something like nonRealPath / literalPath (naming is hard), or perhaps even better, a method that returns the project root, if any, that the file in the editor belongs to. My gut tells me that a lot of people are inferring project root from the file path.. i certainly have in packages before.

If we could get the project root and project-relative path (both I think would be useful in other contexts too) from a TextEditor, that should fix this issue I think?
But this is going to be a really, really deep rabbit hole, I feel. The problem is that there can be an infinite number of paths that can reach a file. Should the TextEditor instance have to know about all of them? What if one of the n paths changes after the TextEditor is created? Say one of the non-real (imaginary?) paths to the file in question is a/foo/c.txt and gets renamed to a/bar/c.txt. Do we have to have file watchers on everything to manage this?

I agree with @dirk-thomas that we should simply not compute the real path, and leave that to the caller. Does anyone know of circumstances where that would break things in a way that wasn't trivially fixable?

Does anyone know of circumstances where that would break things in a way that wasn't trivially fixable?

I'm pretty sure it was this way to begin with (because it was easier), but it changed for some reason ¯_(ツ)_/¯ I'll see if I can backtrace it.

So I devised a test just to see how consistent this is:

Created a new repository lee-dohm/test-atom-9879
Created a directory real-dir inside it
Created a symlink to real-dir named fake-dir
Created a file inside real-dir named test.md

Then I attempted to open test.md in multiple ways from both real-dir and fake-dir and recorded their getPath() result with the command: atom.workspace.getActiveTextEditor().getPath(). Here are the results:

real-dir/test.md

Open from tree-view: /Users/Lee/Source/test-atom-9879/real-dir/test.md
Open from fuzzy-finder: /Users/Lee/Source/test-atom-9879/real-dir/test.md
Open from Cmd+O: /Users/Lee/Source/test-atom-9879/real-dir/test.md
Open via drag-and-drop: /Users/Lee/Source/test-atom-9879/real-dir/test.md (New window appears)

fake-dir/test.md

Open from tree-view: /Users/Lee/Source/test-atom-9879/real-dir/test.md
Open from fuzzy-finder: Does not show up in list
Open from Cmd+O: /Users/Lee/Source/test-atom-9879/real-dir/test.md
Open from drag-and-drop: /Users/Lee/Source/test-atom-9879/real-dir/test.md (New window appears)

Ok, 100% consistent. Which tells me that the code for all of this is almost assuredly in one place ... most likely the opener mechanism.
So then I delved into the Wayback Machine and followed the opener code all the way back to November 2013. As far as I can see, the opener code (which migrated between Project and Workspace over the span) has always* called Project::resolvePath or Project::resolve on the path passed to it. And the resolve twins have always* called fs.absolute() on the path passed to them. Which you can still see here:
https://github.com/atom/atom/blob/2696f493852a265e21c6e326ca963bf947625314/src/project.coffee#L212-L219
So I was wrong and completely fabricated my previously mentioned memory.
Now, where does that leave us? Well, it appears that Project::resolvePath has never been part of the public API and Project::resolve was deprecated back on January 9th, 2015. So at least we don't have to worry about third-party packages depending on this as an API. But since TextEditors have always* returned absolute paths ... we may want to be careful about breaking that implicit contract.

For values of "always" back to November 2013

I do understand that changing the existent behavior is risky. But do we agree that we should somehow expose the non-realpath with a different method (however clumsy the name might be)?
Regarding the absolute() function in fs-plus: I find it rather unintuitive that it resolves symlinks. Based on how similar functions in other languages work (e.g. in Python: https://docs.python.org/3/library/os.path.html#os.path.abspath) I expect the function to:

prefix a relative path with a "cwd"
collapse .. within the path (normalize X/path/../Y to X/Y)
replace stuff like ~

But I would not expect the function to perform a realpath().

But do we agree that we should somehow expose the non-realpath with a different method (however clumsy the name might be)?

Sure, we should. The question is when? Is this no big deal and we can take it now? Or is it something that should wait until v2.0?

Obviously I would like to have the feature rather sooner then later :wink: in order to actually make the build commands (referenced in the description) work. Without this feature there is simply no way to make it work for projects with symlinks. Out of curiosity: what is the rough time frame for Atom 2.0?
Let me try to describe what changes would be required (also for me to understand the Atom internals a bit better) and what that might affect:

Modify Project.resolvePath() to return non-realpath but normalized absolute path instead.
Consider the current usage of the function:

Project.isPathModified() depends on what Buffer.getPath() returns. If it will return a non-realpath nothing needs to be done. Otherwise Project.isPathModified() needs to invoke realpath on the argument before passing it to findBufferForPath().
Project.bufferForPathSync() same as for the previous bullet.
Workspace.open() this is where we actually want the non-realpath since from here the uri / path gets passed throughout the pipeline until it ends up in the TextEditor.

The function also determines if the file is already open in a pane (itemForURI()). This is based on TextBuffer.getUri() which uses getPath(). If getPath() continues to return a realpath the argument to itemForURI() needs to be a realpath.

Workspace.openSync() same as for the previous bullet.
Workspace.openTextFile() calls fs.getSizeSync() which might need a realpath (?).
Is there a way to find out if other code invokes this non-public API?

Modify TextEditor.getPath() to call realpath() before returning the value and introduce a new method TextEditor.getNonRealPath().

If we ensure that existing API like TextEditor.getPath() or TextBuffer.getPath() still return the same realpath as before this might be a backward compatible change? I am happy to hear your thoughts...

It would be great if someone could provide guidance regarding my proposed changes. I am happy to work on a patch if the direction is clear.

Was going through a few old issues and noticed this one that seemed really similar: #3110.

ping :wink:

@50Wliu yep, this is exactly what #3110 is about. I'm going to close it in deference to this.

I have updated #10856 to provide additional API exposing the non-realpath. The existing API should not change behavior (except that a TextBuffer now internally stores the non-realpath). Any feedback is welcome.

This will be fixed in Atom 1.14. We'll preserve whatever path the project was initialized with. Sorry for the very very long turnaround time.

:+1: for supporting this with the current API without the need for additional API.


Update CONTRIBUTING.md and docker-compose.yaml to make it possible to have jaeger show quickwit traces

We now index our traces by default, but it is unclear how to consume them.
CONTRIBUTING.md seems to describe a way to ship traces directly to jaeger (and use jaeger as the backend)
We need to edit this, and possibly remove the associated code.

When developing locally, the 30s ingestion delay is painful, and I prefer to work with the Jaeger in-memory backend.

It is painful for all users. We should solve this by reducing the commit timeout. If we don't use it for own usage, that's a bad sign.

I suggest we make it 5s and we advertise more clearly how to connect jaeger to quickwit.
Ideally I think we should remove the "old way"

let's goooo, tutorial in progress https://github.com/quickwit-oss/quickwit/pull/2947