Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(@ngtools/webpack): invalidate ngcc processor cache #16424

Merged
merged 1 commit into from
Dec 13, 2019

Conversation

filipesilva
Copy link
Contributor

Fix #16397

@filipesilva filipesilva added the target: patch This PR is targeted for the next patch release label Dec 11, 2019
@filipesilva
Copy link
Contributor Author

@clydin highlighted that a risk in these cache-related cases is to end up having stale or incorrect modules being used, but that letting this fix sit in RC for a while will help and we can always pull it.

@@ -54,15 +54,16 @@ export class NgccProcessor {
resolvedModule: ts.ResolvedModule | ts.ResolvedTypeReferenceDirective,
): void {
const resolvedFileName = resolvedModule.resolvedFileName;
if (!resolvedFileName || moduleName.startsWith('.') || this._processedModules.has(moduleName)) {
if (!resolvedFileName || moduleName.startsWith('.')
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will cause a module to be processed multiple times which might slow down the compilation a bit, unless the typings are not flattened, example RxJs.

This is because this method will be called for every dts file resolved.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will ngcc actually process the module or skip it because it can see it's processed already? I think it skips it because the logs I saw only showed the ngcc logging messages once.

We could probably make cache take into account the relation between moduleName and resolvedFileName but I think it would introduce some extra risk actually. That's because the authority isn't this cache, but the ngcc cache. And it can actually happen that the whole module is already compiled but our cache doesn't know, since ngcc will compile a module dependencies anyway.

If we could instead invalidate whole modules directly, instead of filenames, I don't think there would be much risk. We can do that using ts.resolveModuleName, which is what the compiler host resolveModuleNames method that calls processModule does anyway. But this now means module resolution is invoked for file invalidations.

I'm not super keen on trying to make this cache much smarter in general because of the risks @clydin pointed out. The perf improvement seems a tradeoff too, unless we made it smarter. @alan-agius4 do you think it's worth it?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@filipesilva it does skip it, however it will try to read the module and check that it is not already processed multiple times for each module causing quite a number of addition IO ops.

That said, I think we can leave it for now, and tackle it afterwards if we see a big slow down with a lot of dependencies.

Copy link
Member

@clydin clydin Dec 12, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it is also important to note that resolveModuleName resolves to .d.ts files. Are all the relevant .d.t.s files watched in this situation? Libraries that don't fully adhere to the Angular package format for instance.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I saw that .d.ts files for direct dependencies were being invalidated, but did not verify those other cases.

@petebacondarwin are there cases where the .d.ts resolved by ts.resolveModuleName is not the .d.ts file processed by ngcc?

@vikerman vikerman merged commit 6d422b3 into angular:master Dec 13, 2019
@filipesilva filipesilva deleted the ngcc-invalidate branch December 13, 2019 13:03
@angular-automatic-lock-bot
Copy link

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

This action has been performed automatically by a bot.

@angular-automatic-lock-bot angular-automatic-lock-bot bot locked and limited conversation to collaborators Jan 13, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
target: patch This PR is targeted for the next patch release
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Adding a dependency with yarn while serving the app breaks ngcc generated files import
5 participants