angular icon indicating copy to clipboard operation
angular copied to clipboard

Please report about circular dependencies of standalone components on "build" step

Open e-oz opened this issue 2 years ago • 7 comments

Which @angular/* package(s) are relevant/related to the feature request?

compiler

Description

If standalone component A imports standalone component B, and B imports A, then ReferenceError: Cannot access 'A' before initialization will be raised. But it will be only raised in runtime 🤷‍♂️

Proposed solution

Please do not allow to compile components with circular dependencies.

Alternatives considered

Or, allow circular dependencies 😜

e-oz avatar Feb 06 '23 18:02 e-oz

This is something that can be fixed (DX part) by the language service, that can import the component directly using the forwardRef().

eneajaho avatar Feb 07 '23 09:02 eneajaho

Not every IDE uses language service. It would be nice to get an error from a compiler on the compilation step. But a preliminary warning from language service - that would be a great addition, of course.

e-oz avatar Feb 07 '23 10:02 e-oz

There was the same error. The problem was using the static service method in the pipe. There was no circular dependency. The error indicated the module in which the pipe was declared

KutskoAnton avatar Feb 08 '23 14:02 KutskoAnton

@e-oz it sounds like it is might not be directly linked to circular dependencies between files, but rather "typical" JS / TS situation with accessing classes before their initialisation.

It is surprising since our assumption was that TS would catch it: https://www.typescriptlang.org/play?target=2#code/JYWwDg9gTgLgBAbwMIXBAdgU3TAvnAMylTgHIABAQ3QHMBXAG0qgHoBjaTUgbgChfyKNFhwAKBLzhwYmcExkAuMqQA0kuKEiwAzkoDaAIQC6a3AEpebJtu1wAgolz8rlG3AOPeQA

Would you mind sharing the exact scenario when you were bumping into this error?

pkozlowski-opensource avatar Feb 08 '23 16:02 pkozlowski-opensource

@pkozlowski-opensource it's a feature request, what reproduction? ;) Here it is: https://stackblitz.com/edit/angular-ivy-vhsjhg?file=src/app/example/some-test.component.ts Please open console and try to remove tag <some-example/> from template. I'm not sure if your assumption is correct, because this issue can be resolved by usage of forwardRef() (thanks to @eneajaho for finding this solution), and everything works when tag is not in the template.

e-oz avatar Feb 08 '23 18:02 e-oz

Thnx for the reproduction @e-oz ! The interesting bit is that the error in a stackblitz is a different from the one you've initially reported. Just trying to make sure that the stackblitz scenario is the one you've seen initially.

pkozlowski-opensource avatar Feb 09 '23 08:02 pkozlowski-opensource

@pkozlowski-opensource yes, I'm pretty sure now. I was trying to reproduce that exact error message, then I created a repo from StackBlitz code and found that I can't just run it locally - file tsconfig.app.json is missing, but StackBlitz builder still can build it - looks like it is the source of the error message difference.

https://github.com/e-oz/angular-ivy-vhsjhg

When I created tsconfig.app.json, I got that exact error message: Screenshot 2023-02-09 at 18 09 44

e-oz avatar Feb 09 '23 17:02 e-oz

got the same problem migrating from ngModules, before all worked well and now it complains about circular dependency, forwardRef() solves it tho...

bfsimoes avatar Feb 14 '23 18:02 bfsimoes

I've been struggling with this issue for the last 24h. It's so hard to debug. What is the fix? How can I detect the circular dependency? Is there an example with forwardRef I can follow?

mparpaillon avatar Jul 05 '23 08:07 mparpaillon

@mparpaillon Example of forwardRef usage in this case:

@Component({
    // ...
    imports: [
        CommonModule,
        forwardRef(() => ExampleComponent)
    ],
    // ...
})

e-oz avatar Jul 05 '23 10:07 e-oz

@pkozlowski-opensource TS doesn't pick the issue when the classes are in a different file and the exception is raised when the circularity is expressed the in templates.

@mparpaillon replace one import in the circularity for example imports: [FooComponent] by imports:[forwardRef(() => FooComponent)]

JeanMeche avatar Jul 05 '23 10:07 JeanMeche

Thanks a lot. At this point I just don't know which components are causing the issue. In a big codebase that's very time consuming to find them. The error is thrown next to the lazy loaded module in the routing but doesn't tell me which component is causing it. Any tip for that?

mparpaillon avatar Jul 05 '23 13:07 mparpaillon

@mparpaillon In devmode the error should be quite explicit which component throws and which component isn't available yet.

JeanMeche avatar Jul 05 '23 13:07 JeanMeche

I guess I'm missing something then

Capture d’écran 2023-07-05 à 15 28 49

layout.module.ts:77 is just a lazy loaded route (see below)

Capture d’écran 2023-07-05 à 15 29 22

EDIT: I fixed my issue but the bug was quite specific with my codebase. Long story short I have "stores" (providers) that allows me to prevent too much props drilling (kinda like scoped global variables). Anyway, I managed to fix my issued by using inject() instead of standard constructor dependency injection.

mparpaillon avatar Jul 05 '23 13:07 mparpaillon