CreditCardModuleit's pretty similar to the root
AppModulewith a few important differences:
CommonModule. If we see the documentation of the
BrowserModulehere, we can see that it's re-exporting the
CommonModulewith a lot of other services that helps with rendering an Angular application in the browser. These services are coupling our root module with a particular platform (the browser), but we want our feature modules to be platform independent. That's why we only import the
CommonModulethere, which only exports common directives and pipes.
When it comes to components, pipes and directives, every module should import its own dependencies disregarding if the same dependencies were imported in the root module or in any other feature module. In short, even when having multiple feature modules, each one of them needs to import the
exports. Every element defined in the
declarationsarray is private by default. We should only export whatever the other modules in our application need to perform its job. In our case, we only need to make the
CreditCardComponentvisible because it's being used in the template of the
We are keeping the
CreditCardMaskPipeprivate because it's only being used inside the
CreditCardModuleand no other module should use it directly.
CreditCardServicein our example. Notice first that the service is not in the
exportsarray but in the
providersarray. With this configuration, our service is going to be available everywhere, even in the
AppComponentwhich lives in another module. So, even when using modules, there's no way to have a "private" service unless... the module is being lazy loaded.
CreditCardModuleis configured to be lazy loaded. With our current configuration, when the application is bootstrapped and our root module is loaded in memory, an instance of the
CreditCardService(a singleton) is going to be added to the root injector. But, when the
CreditCardModuleis lazy loaded sometime in the future, a child injector will be created for that module with a new instance of the
CreditCardService. At this point we have a hierarchical injector with two instances of the same service, which is not usually what we want.
NgModuledecorator. This time we are defining a static method called
forRootwhere we define the module and the service we want to export.
CreditCardModuledirectly, instead what we are importing is the object returned from the
forRootmethod, which includes the
CreditCardService. Although this syntax is a little more convoluted than the original, it will guarantee us that only one instance of the
CreditCardServiceis added to the root module. When the
CreditCardModuleis loaded (even lazy loaded), no new instance of that service is going to be added to the child injector.
forRootsyntax when exporting services from feature modules, unless you have a very special need that requires multiple instances at different levels of the dependency injection tree.