You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[Feature Request] Recursive component discovery and injection #17267
Right now we need to import all the components into a module's declarations array. It would be great if we could substitute this with declaring component children directly on the component. So suppose we are creating an <app-component> that delegates to children that we are creating as we are iterating.
If we import the child components (Either from the NPM node_modules) or a relative location then they can be automatically discovered and injected into the container (Meta data for this automatically generated).
So within the app.component.ts directly import the ./hero-detail.component.ts file, instead of doing it at the app.module.ts level.
This should eliminate the declarations array. I think it will cascade into other requirements such as having to explicitly import things like RouterLink inside a component that does routing, but I think that's a good thing.
It's pretty amazing right now and I'm sure it will just keep getting better. Just throwing out a few thoughts as I move through the documentation and related projects such as ngx-charts.
@tytskyi I think most devs also prefer to use a more declarative and visually straightforward approach to wiring things up in order. It's easier to see how things are working this way. Then once everything is stable start improving developer efficiency by removing boilerplate and improving the container design. Spring Framework used to have massive XML configuration files, and now it's down to almost 0 boilerplate.
I think most devs also prefer to use a more declarative and visually straightforward approach to wiring things up in order.
It happens that for me - using of NgModule is less boilerplate.
It looks easier to wire-up components directly when you build application from the scratch, but does not play well when you refactor existing application, remove unused code, or copy-paste code from 1 project to another.
I am trying to make modules as small as possible, ideally for each small feature that can be re-used or can be deleted completely.
A Zero boilerplate, zero repetition, DRY design is doable. We just have to look at it carefully. There are still 1405 open issues on the issue log. The simpler Angular gets the smaller the issue stack gets and the more time we can spend building meaningful things.
Consider example: you have a module for custom datepicker component - it contains only 1 component, nothing more. Then to use it in a new project - just copy the module and connect it to the shared module. That's it. No need to connect it to every component where you want to use it.
We can still do exactly what you are saying and eliminate boilerplate. Here's what I'm suggesting:
Declare that the component uses the date picker and import the date picker into that component
Do nothing because angular generates the necessary meta data to include the date picker from now on.
So for the people that only wish to declare the date picker in one place within the app, they can just declare it in the main app shell, and they are good to go. The only difference then is that all the need to do is:
import DatePicker from 'cherry-picker`;
And that's it. Finito! Go grab a beer. Don't worry about the declarations array. Angular has got this!
Suppose we also have a calendar card within the application that also uses a date picker. It imports a date picker, but the version is incompatible with the date picker in the main app shell. Angular can read the package.json file and inject the date picker that the calendar component needs, and this can all be automated.
Angular can also generate a nice dependency graph showing you exactly what the NgModule current provides and use this type of feature to warn you of things that might be silly. Less work. More productivity. More living la vida loca!!
The other benefit to direct import of date-picker where it is needed is refactoring. If the data picker component import declaration is at the top of every file that needs this component (Not that it should be mandatory) then that file becomes self descriptive and can be moved around, possibly to a completely different project module, more easily.
See any boilerplate? The designers have to repeat the name of every single component 3 times. I imagine that's because all of the components should have access to the common, but which ones. If want to move the YAxisTicksComponent to a completely different project do I actually need the CommonModule or is this just something that is thrown in here for the sake of development flow?
The CommonModule is only needed when declared components use ngIf, ngFor, built in pipes.
I have modules in my app where i do not import CommonModule this is normal situation.
I think in general you want angular to be more than framework - you want it to be complete development platform. But it is framework, it does not invent new platform or language, it uses what already exists.
You maybe would like to check AngularDart https://webdev.dartlang.org/angular - they propose api you like: no modules, routing defined per component. Plus Dart is the complete development platform.
The CommonModule is only needed when declared components use ngIf, ngFor, built in pipes.
I have modules in my app where i do not import CommonModule this is normal situation.
I understand. I did not write the ngx-charts library / component set. Some obviously very intelligent people did though, yet you see how the module is been authored. Even with the rewrite a lot of people would look at that and go "OK - what did we really gain from this?". And maybe we gained something, but could that have been simpler?
You are also missing my point. Which one of the chart files depend on common and which don't? It's not clear from the current module format, therefore this code can not be easily refactored.
I don't really want it to be a framework or a development platform. Saying that someone is looking for a certain label does not help reduce the issue stack. When code is simple and easy to read the end result of what we build with it will be easy to maintain and refactor. I'm trying to show you that this is not the case ATM. It's not complicated, but not as simple as possible either.
We should be focused on whether it can be made more simple. Right now I'm telling you that if you chop the carrots this way you can chop them in one minute, instead of two, and you are telling me that "If I want a vegetable stew, then maybe I should consider this restaurant".
The CommonModule is only needed when declared components use ngIf, ngFor, built in pipes.
I have modules in my app where i do not import CommonModule this is normal situation.
One more point about this. Right now I suspect that the above explanation will be one of many explanations ng module related explanations that will be given over and over and over. That's because it's not clear what common-module provides and the library does not explicity give us an option to get a grasp on it. This is going to lead to a lot of developers attempting to follow along with examples and cut and paste stuff.
On the flip side if they explicitly have to import what they use within the component, even directives within templates, then the code becomes clearer and easier to follow. The suggestion here would allow for both approaches. For example if the developer could turn on tooling that tells the to import ngIf from the common module, if they wish to follow the more explicit approach. If they do this then it becomes obvious what parts of the library the component depends on.
Also with the alternate approach it becomes very easy to leave NgModule configuration dependencies that are no longer needed intact, because there's nothing that directly links the module to the corresponding components, so tooling warning about this cannot be developed ... well I should never say never ... but without explicit imports it's much more complicated.
Another question is suppose we depend on ngIf only from the common-module. Can we tree shake the rest of that module, since we are not using any of the other directives?
Angular documentation has done a whole FAQ about NgModules, but it’s still quite a mess to teach this during courses, students are often confused, so I decided to sum it up in this post for everyone.
So if we can make NgModules simpler and more DRY that should be a big win or everyone.
This would solve #10646 (which, imo, was prematurely closed).
@tytskyi - this feature would be able to generate minimal dependency graphs at compile time for modules without any configuration, and thus ngc could inject those declarations into the module, and bundle any shared dependencies intelligently into generated shared modules as it builds the dependency graphs of multiple root modules.
And, it's natural to import the components used in a template (I did that initially, not realizing I didn't need to do that, and that the declaration array of my root module was the source of truth in this regard).
I am strongly in favor of this! It would eliminate a confusing class of modules that doesn't need to exist (internal-only shared modules), and promote modules as a way to define the exposed components of your public module (API of components).
Thank you for submitting your feature request! Looks like during the polling process it didn't collect a sufficient number of votes to move to the next stage.
We want to keep Angular rich and ergonomic and at the same time be mindful about its scope and learning journey. If you think your request could live outside Angular's scope, we'd encourage you to collaborate with the community on publishing it as an open source package.
You can find more details about the feature request process in our documentation.
Activity
tytskyi commentedon Jun 6, 2017
What you describe it was exactly before stable Angular.
oleersoy commentedon Jun 7, 2017
It's pretty amazing right now and I'm sure it will just keep getting better. Just throwing out a few thoughts as I move through the documentation and related projects such as ngx-charts.
oleersoy commentedon Jun 7, 2017
@tytskyi I think most devs also prefer to use a more declarative and visually straightforward approach to wiring things up in order. It's easier to see how things are working this way. Then once everything is stable start improving developer efficiency by removing boilerplate and improving the container design. Spring Framework used to have massive XML configuration files, and now it's down to almost 0 boilerplate.
tytskyi commentedon Jun 7, 2017
It happens that for me - using of NgModule is less boilerplate.
It looks easier to wire-up components directly when you build application from the scratch, but does not play well when you refactor existing application, remove unused code, or copy-paste code from 1 project to another.
I am trying to make modules as small as possible, ideally for each small feature that can be re-used or can be deleted completely.
oleersoy commentedon Jun 7, 2017
A Zero boilerplate, zero repetition, DRY design is doable. We just have to look at it carefully. There are still 1405 open issues on the issue log. The simpler Angular gets the smaller the issue stack gets and the more time we can spend building meaningful things.
tytskyi commentedon Jun 7, 2017
Consider example: you have a module for custom datepicker component - it contains only 1 component, nothing more. Then to use it in a new project - just copy the module and connect it to the shared module. That's it. No need to connect it to every component where you want to use it.
I recommend you to check this one: https://angular.io/docs/ts/latest/guide/ngmodule.html
oleersoy commentedon Jun 7, 2017
We can still do exactly what you are saying and eliminate boilerplate. Here's what I'm suggesting:
So for the people that only wish to declare the date picker in one place within the app, they can just declare it in the main app shell, and they are good to go. The only difference then is that all the need to do is:
And that's it. Finito! Go grab a beer. Don't worry about the
declarationsarray. Angular has got this!Suppose we also have a
calendar cardwithin the application that also uses adate picker. It imports adate picker, but the version is incompatible with thedate pickerin the mainapp shell. Angular can read the package.json file and inject the date picker that the calendar component needs, and this can all be automated.Angular can also generate a nice dependency graph showing you exactly what the NgModule current provides and use this type of feature to warn you of things that might be silly. Less work. More productivity. More living la vida loca!!
oleersoy commentedon Jun 9, 2017
The other benefit to direct import of
date-pickerwhere it is needed is refactoring. If the data picker component import declaration is at the top of every file that needs this component (Not that it should be mandatory) then that file becomes self descriptive and can be moved around, possibly to a completely different project module, more easily.oleersoy commentedon Jun 9, 2017
Take a look at this axes module from ngx-charts (https://github.com/swimlane/ngx-charts/blob/master/src/common/axes/axes.module.ts):
See any boilerplate? The designers have to repeat the name of every single component 3 times. I imagine that's because all of the components should have access to the common, but which ones. If want to move the
YAxisTicksComponentto a completely different project do I actually need theCommonModuleor is this just something that is thrown in here for the sake of development flow?I also don't think this module format follows the current recommendations for Angular (One module per component - https://www.youtube.com/watch?v=unICbsPGFIA&t=1141s)?
tytskyi commentedon Jun 9, 2017
The
CommonModuleis only needed when declared components usengIf,ngFor, built in pipes.I have modules in my app where i do not import
CommonModulethis is normal situation.I think in general you want angular to be more than framework - you want it to be complete development platform. But it is framework, it does not invent new platform or language, it uses what already exists.
You maybe would like to check AngularDart https://webdev.dartlang.org/angular - they propose api you like: no modules, routing defined per component. Plus Dart is the complete development platform.
oleersoy commentedon Jun 9, 2017
I understand. I did not write the ngx-charts library / component set. Some obviously very intelligent people did though, yet you see how the module is been authored. Even with the rewrite a lot of people would look at that and go "OK - what did we really gain from this?". And maybe we gained something, but could that have been simpler?
You are also missing my point. Which one of the chart files depend on common and which don't? It's not clear from the current module format, therefore this code can not be easily refactored.
I don't really want it to be a framework or a development platform. Saying that someone is looking for a certain label does not help reduce the issue stack. When code is simple and easy to read the end result of what we build with it will be easy to maintain and refactor. I'm trying to show you that this is not the case ATM. It's not complicated, but not as simple as possible either.
We should be focused on whether it can be made more simple. Right now I'm telling you that if you chop the carrots this way you can chop them in one minute, instead of two, and you are telling me that "If I want a vegetable stew, then maybe I should consider this restaurant".
oleersoy commentedon Jun 10, 2017
One more point about this. Right now I suspect that the above explanation will be one of many explanations ng module related explanations that will be given over and over and over. That's because it's not clear what common-module provides and the library does not explicity give us an option to get a grasp on it. This is going to lead to a lot of developers attempting to follow along with examples and cut and paste stuff.
On the flip side if they explicitly have to import what they use within the component, even directives within templates, then the code becomes clearer and easier to follow. The suggestion here would allow for both approaches. For example if the developer could turn on tooling that tells the to import
ngIffrom the common module, if they wish to follow the more explicit approach. If they do this then it becomes obvious what parts of the library the component depends on.Also with the alternate approach it becomes very easy to leave NgModule configuration dependencies that are no longer needed intact, because there's nothing that directly links the module to the corresponding components, so tooling warning about this cannot be developed ... well I should never say never ... but without explicit imports it's much more complicated.
oleersoy commentedon Jun 10, 2017
Another question is suppose we depend on
ngIfonly from thecommon-module. Can we tree shake the rest of that module, since we are not using any of the other directives?oleersoy commentedon Jul 13, 2017
Just referencing in this article
Quote:
So if we can make NgModules simpler and more DRY that should be a big win or everyone.
snewell92 commentedon Aug 9, 2017
This would solve #10646 (which, imo, was prematurely closed).
@tytskyi - this feature would be able to generate minimal dependency graphs at compile time for modules without any configuration, and thus ngc could inject those declarations into the module, and bundle any shared dependencies intelligently into generated shared modules as it builds the dependency graphs of multiple root modules.
And, it's natural to import the components used in a template (I did that initially, not realizing I didn't need to do that, and that the declaration array of my root module was the source of truth in this regard).
I am strongly in favor of this! It would eliminate a confusing class of modules that doesn't need to exist (internal-only shared modules), and promote modules as a way to define the exposed components of your public module (API of components).
angular-robot commentedon Jun 4, 2021
Just a heads up that we kicked off a community voting process for your feature request. There are 20 days until the voting process ends.
Find more details about Angular's feature request process in our documentation.
angular-robot commentedon Jun 25, 2021
Thank you for submitting your feature request! Looks like during the polling process it didn't collect a sufficient number of votes to move to the next stage.
We want to keep Angular rich and ergonomic and at the same time be mindful about its scope and learning journey. If you think your request could live outside Angular's scope, we'd encourage you to collaborate with the community on publishing it as an open source package.
You can find more details about the feature request process in our documentation.
JoostK commentedon Oct 6, 2021
Expect and RFC out soon around the concept of standalone components.
angular-automatic-lock-bot commentedon Nov 6, 2021
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.