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

build: add a script to detect component ID collisions #27411

Merged
merged 1 commit into from
Jul 6, 2023

Conversation

crisbeto
Copy link
Member

@crisbeto crisbeto commented Jul 6, 2023

As of v16, the framework uses the metadata of a component to generate an ID. If two components have identical metadata, they may end up with the same ID which will log a warning. These changes add a script to detect such cases automatically.

Relates to #27163.

@crisbeto crisbeto added P3 An issue that is relevant to core functions, but does not impede progress. Important, but not urgent target: patch This PR is targeted for the next patch release labels Jul 6, 2023
@angular-robot angular-robot bot added the area: build & ci Related the build and CI infrastructure of the project label Jul 6, 2023
@andrewseguin
Copy link
Contributor

Why does Angular throw an error here? Isn't our use case valid - we are making a new version of a component.

@crisbeto
Copy link
Member Author

crisbeto commented Jul 6, 2023

tl;dr is that Angular has always had a unique ID for each component. Pre-v16 the ID was based on a counter so components were guaranteed to have a unique ID. When hydration was introduced, the counter approach didn't work anymore since different components might be executed on the server and the client so the ID algorithm was switched to use the metadata instead.

The unique ID is used in DI and when keeping track of stylesheets.

@andrewseguin
Copy link
Contributor

Could the ID generation take into account it's filepath or something unique beyond just metadata? It'd be helpful to know they intend to prevent this case otherwise

@crisbeto
Copy link
Member Author

crisbeto commented Jul 6, 2023

It can't because:

  1. JIT compilation doesn't know about the file system.
  2. This happens in the runtime, not at compilation.

@andrewseguin
Copy link
Contributor

andrewseguin commented Jul 6, 2023

Oof...well that's a bummer.

When should we run this script? Seems like it's a proactive thing that we ought to run when we change metadata?

EDIT: Or include it in a CI test?

@crisbeto
Copy link
Member Author

crisbeto commented Jul 6, 2023

There are a few failures that I want to address first before I add it to the CI.

@devversion
Copy link
Member

Two quick thoughts:

  • Should some of this check be performed in the compiler CLI itself? seems like something other libraries would need too.
  • Could we just have a runtime test that imports all components and asserts that nothing breaks?

@crisbeto
Copy link
Member Author

crisbeto commented Jul 6, 2023

Things don't necessarily break at the moment, they just log a warning and I wanted to automate catching the warnings instead of having users report it to us.

As for having it in the compiler: I think it's trickier to do it there, because compilations might be spread across different build units running in parallel and things would only conflict once they're on the same page.

@devversion
Copy link
Member

I thought we could potentially intercept logging and see if there is a matching error/or something, without having to replicate some of the serialization logic. At the same time though- adding all components is likely not super nice either

@crisbeto
Copy link
Member Author

crisbeto commented Jul 6, 2023

Yeah I feel like having it run as a part of the CI against the source code is the simplest without having to maintain even more code.

scripts/detect-component-id-collisions.ts Outdated Show resolved Hide resolved
// Create an ID for the component based on its metadata. This is based on what the framework
// does at runtime at https://github.com/angular/angular/blob/main/packages/core/src/render3/definition.ts#L679.
// Note that the behavior isn't exactly the same, because the framework uses some fields that
// are generated by the compiler based on the component's template.
Copy link
Member

Choose a reason for hiding this comment

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

Yes, and likely we are overly sensitive here, but it guarantees we are not conflicting.

As of v16, the framework uses the metadata of a component to generate an ID. If two components have identical metadata, they may end up with the same ID which will log a warning. These changes add a script to detect such cases automatically.

Relates to angular#27163.
@crisbeto crisbeto added the action: merge The PR is ready for merge by the caretaker label Jul 6, 2023
@crisbeto crisbeto self-assigned this Jul 6, 2023
@crisbeto crisbeto merged commit 27add4b into angular:main Jul 6, 2023
9 checks passed
crisbeto added a commit that referenced this pull request Jul 6, 2023
As of v16, the framework uses the metadata of a component to generate an ID. If two components have identical metadata, they may end up with the same ID which will log a warning. These changes add a script to detect such cases automatically.

Relates to #27163.

(cherry picked from commit 27add4b)
stephenrca pushed a commit to stephenrca/components that referenced this pull request Aug 2, 2023
As of v16, the framework uses the metadata of a component to generate an ID. If two components have identical metadata, they may end up with the same ID which will log a warning. These changes add a script to detect such cases automatically.

Relates to angular#27163.
@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 Aug 6, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
action: merge The PR is ready for merge by the caretaker area: build & ci Related the build and CI infrastructure of the project P3 An issue that is relevant to core functions, but does not impede progress. Important, but not urgent target: patch This PR is targeted for the next patch release
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants