I find it somewhat inconvenient having to manually register my Angular MVC components and services within the root module (AppModule). It becomes even more inconvenient when working in a team. Ideally, developers should only add three files - a component, a view and a service without touching any other "infrastructure" files.
I tried to not register my services in
providersarray, and the services still worked just fine. However, I'm not sure what would be the long-term consequences of not having them there. In which cases I would want my services inprovidersarray?Then I tried to not register my components in
declarationsarray and, of course, Angular failed with a message "Component BanksComponent is not part of any NgModule or the module". This seems to be a roadblock for the "convention-over-configuration" idea.It would be great to be able to add component-specific routes inside a component code file and somehow make Angular Router automatically collect those routes from all components that have routes defined (similarly to how ASP.NET MVC Route attribute on controllers works). Is there any solution for this?
Should I ditch the idea entirely and accept the fact that Angular just can't work that way?
You can put your Angular components in different modules. This has the benefit that you can better manage your dependencies and developers won't have to touch the same files.
A folder structure that I use in all of my projects:
This structure separates the logic for authentication, pages and shared functionality. It also bundles a component/small module so that it can be developed independently and can be replaced easily.
Example
You can find an example on how this fits in an actual application in this stackblitz.
To answer your questions
Since Angular 6 you can register your services with the
@Injectable({providedIn: root})syntax. What this means is that your service will be globally available (you won't have to add it to theprovidersarray before you can use it) and will be automatically removed from the prod bundle (via tree shaking) if it is not injected in any place.Components should always be registered in the
declarationsarray. But you can make small modules where you declare the components.Via the
RouterModule.forChild()you can create component specific routes. Combine this with lazy loading and you have a better overview over your features and better overall performance.Lazy loading
You can improve the speed and decoupling of your application with lazy loaded routes. This is because the lazy routes (
loadChildrenin theroutesarray) only point to a path. This way you can replace the module with an other module (that has the same name), without changing the reference (Even less files we need to change! :D).Example import:
To further improve the performance of the application you can use a PreloadingStrategy. I would advice to use the PreloadAllModules strategy so your modules are loaded when it doesn't bother the user and it speeds up the the further loading and navigation of the application (more here).
Usage of constants over strings
In order to avoid a lot of debugging and/or runtime issues when you remove a route, I advise to use constants. This way you have 1 place where you define the page routes and can avoid string comparisons. Do note that you need a separate file for this. You cannot add the routes in the routing file, since that would create a circular dependency.