4

This new @NgModule crap has got me stumped. Before, I was able to cleanly specify a @Component's directive dependencies via the directives: [] attribute of the @Component meta object. So:

@Component({ /* ... */ })
export class Cmp1 {}

@Component({ /* ... */ })
export class Cmp2 {}

@Component({
  /* ... */
  directives: [Cmp1]
})
export class Cmp3 {}

@Component({
  /* ... */
  directives: [Cmp2, Cmp3]
})
export class Cmp4 {}

Now, under the guise of "convenience" it appears I have to now declare an @NgModule with all four of these components in a single array, like this:

@NgModule({
  declarations: [Cmp1, Cmp2, Cmp3, Cmp4],
  exports: [Cmp4],
  imports: [Cmp1, Cmp2, Cmp3, Cmp4]
})
export class YetAnotherWrapperClass {}

Doesn't that obscure the true dependency graph of my components? If I do that, how do I know that it is actually Cmp3 that depends on Cmp1? Oh sure, I get to omit some import statements here and there, but it seems like the cost is losing explicit dependencies for each component.

I read through the migration guide and the angular modules guide, but I feel as if I fundamentally disagree with the @NgModule design decision. Am I missing something?

AndyPerlitch
  • 4,539
  • 5
  • 28
  • 43

1 Answers1

2

The purpose of introducing @NgModule() was to allow lazy loading with the router, not to introduce a different way for declaring component dependencies. This is just a side effect.

It's true, you don't get a clear dependency graph for components or directives anymore, but you get a clear dependency graph for features if you split your applications to a feature per NgModule which is IMHO more meaningful.

Imports is only for NgModules, not for component or directives. This line is therefore not valid

imports: [Cmp1, Cmp2, Cmp3, Cmp4]

and should be like

imports: [Feature1Module, Feature2Module]

Günter Zöchbauer
  • 623,577
  • 216
  • 2,003
  • 1,567
  • Thanks for the clarification on the imports and on the feature-centric design philosophy, Günter. I can certainly appreciate the benefits of AoT and lazy-loading. I was hoping that ng2 would address the name-conflict issue that ng1 had, e.g. not being able to use same-name services or directives in the same project. I suppose this is a slight improvement: different features encapsulate their own dependencies with no naming conflicts to worry about. – AndyPerlitch Sep 27 '16 at 15:43
  • Naming conflicts can only occur with directive- , component-, and pipe selectors if two with the same selector are imported into one module (where it is used). Otherwise TS imports are enough to distinguish two classes with the same name. – Günter Zöchbauer Sep 27 '16 at 15:46
  • Understood. Again, thanks for the quick follow-up. As an aside, my apologies if my frustration comes off as thankless. Sometimes I forget that the internet isn't such a big place. You guys do great work and provide devs like me the tools to get work done faster, keep it up! – AndyPerlitch Sep 27 '16 at 15:54
  • @AndyPerlitch I didn't perceive any frustration. Did you post the comment because you read my comments on the other question that was asked a few minutes ago? I understand when people discuss whether they like or dislike some "feature" but the mentioned question was going on about 10 lines about how it can happen that docs of a fast-moving project are not 100% accurate, instead of making the actual question as clear as possible. That's just wasting everybodys time who has to read it before reaching the actual question. I'm also not a Googler. – Günter Zöchbauer Sep 27 '16 at 16:04
  • 1
    Haha, no actually I was not aware of the question you mentioned. Weird... I swear that I had seen you high up on the list of angular2 contributors, but looking now I see that this is not the case. Kindly disregard my previous comment (though I'm sure you do great work, at the very least answering questions on SO). I do agree with you about the futility of complaining about docs for a fast-moving, early-stage project... that comes with the territory. – AndyPerlitch Sep 27 '16 at 16:36