Repository: angular
Issue: The entire use of NgModule should be deprecated
Labels: area: core,core: NgModule,needs: discussion

The aim of this post is to create a discussion on the topic, there is also a really simple solution I offered, but I really like to hear your thoughts... 

It is my opinion that creating a module system in Angular **NgModule** in addition to the already existing  module system of Javascript is a bad idea and should be changed, or at least the developers should have a choice to work in a non NgModule mode...

Here is why I think NgModules will hold angular progress back: 
1. Bundle size - if I'm creating a library or installing a library containing a module with 10 components, I want to use one of those components in my app, but I only want to use one of them, I add the module to my imports array and my bundle will contain 9 components I'm not even using - this is incorrect with the new Ivy. 
2. Maybe this is why angular material wraps almost every component in the library in it's own module, a bit ugly in my opinion but necessary because of the NgModule system, still it requires me adding tons of stuff to my imports library. 
3. I know how to solve 2 I will just create CommonModule with the imports in one module and then every module that use them will add that module to the imports, but isn't that pattern messing my bundle size as well? 
For example let's say I have common stuff that every module is using and than a bunch of lazy loaded module that each we can divide to a group that use the common ones and another group of other common modules, I don't want to add everything to to CommonModule so I would have do to Common1Module, Common2Module, etc. for every group cause if I throw everything on the CommonModule it will effect the bundle size of every lazy loaded part of my app won't it? 
4. It's not a reason but it's a big clue that the NgModule system is not needed, there is no module system in any other frontend framework or library that i'm aware of, including React and Vue, they simply use the module system in JS. 
5. Learning curve - While it's pretty easy for people to learn that they need modules, separation of concerns is a pretty well understood concept for people and they know they should split their code to "libraries", so the angular module system is pretty simple to understand, but usually when I teach and talk to angular developers they get lost how the DI works cause the module system heavily intertwined in how the DI is searching for providers.
6. HttpClientModule is a good example here, let's say I'm creating a library which contain an NgModule. Obviously that module can be added to the imports of a lazy loaded module, I cannot add HttpClientModule to my library cause it can create another instance of HttpClient if it is used, and then I can mess up my interceptor. So now I have to worry about peerDependencies as well. Example ngrx libraries require us to add HttpClientModule. We already have a peerDependency mechanism inside javascript modules, now we have to do the same with angular

Currently I see the Ivy renderer allows us to create components without modules, but it is still heavily limited in what the component can use in terms of other directives and providers, without a module that is wrapped and supplies them. 

It somewhat seemed to me that the NgModules system is something that was taken from the Angular.js ecosystem and just moved along to the current Angular and I don't think it's needed at all, and not only that it creates more harm than good.

I think the NgModule requires a drastic change which will have to cause a drastic change in the DI, and we will not achieve the bundle size of the competitors React and Vue unless a major change here is achieved . 
I think NgModule has more cons than pros and would love to hear your thoughts.

Making a really general proposal from this post these are the changes I think should be made:
1. The DI system should not automatically create different trees for modules and for the view, rather it should be a simple solution that should be inspired from the library TypeDI. 
You import the DI and you register services to it, and if you want to create a tree structure in your DI you do it manually, you import the DI system and fork it so a certain component can have it's own dependencies. 
Or at least to support backward compatibility allow the DI to work in manual mode, just like we did with the change detection strategy. The manual mode of the DI will enable the developer to control the forking of the di to trees and thus he can choose to work in a non NgModule mode.
2. After that remove the modules entirely, every component that use a certain directive component should use the js module system and use a certain import.
Maybe this step can also somehow be integrated in the compiler in some way so based on the selector angular will know which component to integrate without using the js module system. I'm not entirely strong on the compilation process so I don't think I'm qualified to make a suggestion here.