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
Forbid orphan components #52061
Forbid orphan components #52061
Conversation
3d8d6ae
to
38cdb2d
Compare
38cdb2d
to
d7af0f9
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some initial comments.
packages/compiler-cli/src/ngtsc/annotations/component/src/handler.ts
Outdated
Show resolved
Hide resolved
@@ -163,6 +164,17 @@ export class ComponentFactory<T> extends AbstractComponentFactory<T> { | |||
injector: Injector, projectableNodes?: any[][]|undefined, rootSelectorOrNode?: any, | |||
environmentInjector?: NgModuleRef<any>|EnvironmentInjector| | |||
undefined): AbstractComponentRef<T> { | |||
// Check if the component is orphan | |||
if (ngDevMode && this.componentDef.debugInfo?.forbidOrphanRendering) { | |||
if (depsTracker.isOrphanComponent(this.componentType)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is an interesting scenario we should chat about (related to our ngDevMode/jitMode conversations). If ngJitMode
is false
but ngDevMode
is true, this will currently always yield an error IIRC because setNgModuleScope
would never be invoked?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah yeah, correct. For now I added ngJitMode
to this if statement. Also in the very first commit I added a check to ensure that the option forbidOrphanComponents
is not set without jit mode (i.e., option supportJitMode
). But these are just temporary solution, and it seems we need a better flag system. I'll write design doc soon on this. My quick thought is we may need a ngDebugMode
flag as well which causes more verbose and runtime checks to pop in (unless we want to redefine ngDevMode to do this, but seems like this flag is a bit limited IIRC)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sounds good. My first thought is that ngDebugMode
should not exist and ngDevMode
should be sufficient. We are not adding any super verbose logging/debugging as far as I know
9114f48
to
a539f4a
Compare
…orphan component Orphan component is an anti-pattern in Angular where a component is rendered while the NgModule declaring it is not installed. It is not easy to capture this scenario, specially in compile time. But it is possible to capture a special case in runtime where the component is being rendered without its NgModule even loaded into the browser. This change adds a flag in cli compiler option to enable such checking, and throwing a runtime exception if it happens. Note that such check is only done in dev mode. Currently the check requires some generated code that is behind ngJitMode flag (i.e., call to ɵɵsetNgModuleScope), and the new flag can be set only if JIT mode is enabled (i.e., supportJitMode=true) otherwise an error will be thrown. The orphan component is a main blocker for rolling out local compilation in g3. This option is needed for identifying and isolating such cases.
…mponent's debug info A new flag added to the component's debug info to determine whether to throw runtime error (in dev mode) if component is being rendered without its NgModule. This flag is only set for non-standalone components.
The flag `forbidOrphanRendering` is only set for non-standalone components, and indicates that the dev mode runtime should through error if the component is rendered without its ngModule loaded in the browser. This runtime error can help with further debugging.
… orphan A new method `isOrphanComponent` is added to the deps tracker API to check if the NgModule declaring this component, if exists, is loaded into the browser.
A runtime error will be thrown if a non-standalone component is being rendered without its NgModule loaded in the browser. This error is thrown only in dev mode and only if the Angular option `forbidOrphanComponents` is set to true. The error contains useful info to find the orphan component in the source code.
Now users can configure the option `forbidOrphanComponents` in the tsconfig's angularCompilerOptions part.
a539f4a
to
ee81a04
Compare
Caretaker note: the ci/test failed due to |
This PR was merged into the repository by commit 59ba2a6. |
A runtime error will be thrown if a non-standalone component is being rendered without its NgModule loaded in the browser. This error is thrown only in dev mode and only if the Angular option `forbidOrphanComponents` is set to true. The error contains useful info to find the orphan component in the source code. PR Close #52061
Now users can configure the option `forbidOrphanComponents` in the tsconfig's angularCompilerOptions part. PR Close #52061
This issue has been automatically locked due to inactivity. Read more about our automatic conversation locking policy. This action has been performed automatically by a bot. |
…orphan component (angular#52061) Orphan component is an anti-pattern in Angular where a component is rendered while the NgModule declaring it is not installed. It is not easy to capture this scenario, specially in compile time. But it is possible to capture a special case in runtime where the component is being rendered without its NgModule even loaded into the browser. This change adds a flag in cli compiler option to enable such checking, and throwing a runtime exception if it happens. Note that such check is only done in dev mode. Currently the check requires some generated code that is behind ngJitMode flag (i.e., call to ɵɵsetNgModuleScope), and the new flag can be set only if JIT mode is enabled (i.e., supportJitMode=true) otherwise an error will be thrown. The orphan component is a main blocker for rolling out local compilation in g3. This option is needed for identifying and isolating such cases. PR Close angular#52061
…mponent's debug info (angular#52061) A new flag added to the component's debug info to determine whether to throw runtime error (in dev mode) if component is being rendered without its NgModule. This flag is only set for non-standalone components. PR Close angular#52061
angular#52061) The flag `forbidOrphanRendering` is only set for non-standalone components, and indicates that the dev mode runtime should through error if the component is rendered without its ngModule loaded in the browser. This runtime error can help with further debugging. PR Close angular#52061
… orphan (angular#52061) A new method `isOrphanComponent` is added to the deps tracker API to check if the NgModule declaring this component, if exists, is loaded into the browser. PR Close angular#52061
…r#52061) A runtime error will be thrown if a non-standalone component is being rendered without its NgModule loaded in the browser. This error is thrown only in dev mode and only if the Angular option `forbidOrphanComponents` is set to true. The error contains useful info to find the orphan component in the source code. PR Close angular#52061
…ar#52061) Now users can configure the option `forbidOrphanComponents` in the tsconfig's angularCompilerOptions part. PR Close angular#52061
This PR adds an option to Angular compiler options which allow to produce runtime error if orphan components found. Good for identifying such cases.
PR Checklist
Please check if your PR fulfills the following requirements:
PR Type
What kind of change does this PR introduce?
What is the current behavior?
Issue Number: N/A
What is the new behavior?
Does this PR introduce a breaking change?
Other information