When profiling ngcc it is notable that a large amount of time is spent dealing with an exception that is thrown (and handled internally by fs) when checking the existence of a file. We check file existence a lot in both finding entry-points and when TS is compiling code. This commit adds a simple cached `FileSystem`, which wraps a real `FileSystem` delegate. This will reduce the number of calls through to `fs.exists()` and `fs.readFile()` on the delegate. Initial benchmarks indicate that the cache is miss to hit ratio for `exists()` is about 2:1, which means that we save about 1/3 of the calls to `fs.existsSync()`. Note that this implements a "non-expiring" cache, so it is not suitable for a long lived `FileSystem`, where files may be modified externally. The cache will be updated if a file is changed or moved via calls to `FileSystem` methods but it will not be aware of changes to the files system from outside the `FileSystem` service. For ngcc we must create a new `FileSystem` service for each run of `mainNgcc` and ensure that all file operations (including TS compilation) use the `FileSystem` service. This ensures that it is very unlikely that a file will change externally during `mainNgcc` processing. PR Close #30525
Angular Compatibility Compiler (ngcc)
This compiler will convert node_modules compiled with ngc, into node_modules which
appear to have been compiled with ngtsc.
This conversion will allow such "legacy" packages to be used by the Ivy rendering engine.
Building
The project is built using Bazel:
yarn bazel build //packages/compiler-cli/ngcc
Unit Testing
The unit tests are built and run using Bazel:
yarn bazel test //packages/compiler-cli/ngcc/test
Integration Testing
There are tests that check the behavior of the overall executable:
yarn bazel test //packages/compiler-cli/ngcc/test:integration