Modules: when and why?
The angular style guide discusses the topic of when to use modules. Reference the Application structure and NgModules section. Better yet, see this heading to get straight to the discussion on modules. I've summarized some of the details below, but there are details that I omitted to keep my answer from being too lengthy. Use it to get a feel, but please refer to the style guide for full context.
Root
Do create an NgModule in the app's root folder, for example, in /src/app.
Why? Every app requires at least one root NgModule.
Features
Do create an NgModule for each feature area.
Why? NgModules make it easy to lazy load routable features.
Why? NgModules make it easier to isolate, test, and re-use features.
Shared
Do create a feature module named SharedModule in a shared folder; for example, app/shared/shared.module.ts defines SharedModule.
Do declare components, directives, and pipes in a shared module when those items will be re-used and referenced by the components declared in other feature modules.
Consider using the name SharedModule when the contents of a shared module are referenced across the entire application.
Why? SharedModule will contain components, directives and pipes that may need features from another common module; for example, ngFor in CommonModule.
Core
Consider collecting numerous, auxiliary, single-use classes inside a core module to simplify the apparent structure of a feature module.
Consider calling the application-wide core module, CoreModule. Importing CoreModule into the root AppModule reduces its complexity and emphasizes its role as orchestrator of the application as a whole.
Do create a feature module named CoreModule in a core folder (e.g. app/core/core.module.ts defines CoreModule).
Do put a singleton service whose instance will be shared throughout the application in the CoreModule (e.g. ExceptionService and LoggerService).
Do import all modules required by the assets in the CoreModule (e.g. CommonModule and FormsModule).
Why? CoreModule provides one or more singleton services. Angular registers the providers with the app root injector, making a singleton instance of each service available to any component that needs them, whether that component is eagerly or lazily loaded.
Why? CoreModule will contain singleton services. When a lazy loaded module imports these, it will get a new instance and not the intended app-wide singleton.
Do gather application-wide, single use components in the CoreModule. Import it once (in the AppModule) when the app starts and never import it anywhere else. (e.g. NavComponent and SpinnerComponent).
Why? Real world apps can have several single-use components (e.g., spinners, message toasts, and modal dialogs) that appear only in the AppComponent template. They are not imported elsewhere so they're not shared in that sense. Yet they're too big and messy to leave loose in the root folder.
Goals of Angular Module:
1) Consolidate components, directive, pipes into cohesive of functionality
2) Make some of component , directive, ,pipes public; so that other module component template can use them.
3)import components, directive, pipes from other module that are required by current module's component templates.
4) provide service that the other module can use.
it is answer to why?.
Ultimately the module concept came to Angular 2 because of the need for lazy loading. There needed to be a single place where the dependencies of a section of one's application could be declared and services provided.
As a result, my preference in general is to only divide the application into modules as is necessary to enable lazy loading. Personally I find any more module declarations of limited use.
Still, there is no single best practice as far as modules are concerned. Much of it is project-dependent. Some developers prefer to create a module for every component, while others have one single module for their entire application.
In favor of using large numbers of modules: there are few drawbacks to creating those modules other than code verbosity. You will have smaller sections of your application that can be rearranged and moved into other applications with ease. Dependencies for specific areas of your application are also more explicit (rather than having all of your application's directives available to all components).
In favor of using small numbers of modules: you will spend less time trying to declare the components that are shared between modules. A single root module containing all of your component declarations is the single source of truth for your application's dependencies.
In general, I would say go with your gut. Choosing to create a module is not so different from choosing to create a new folder in your application. If you find that you're uncomfortable with the size and scope of a module, the cost of refactoring is minimal.