Organising your stuff feels good! Cover photo by Bynder on Unsplash.
Original publication date: 2019-06-21.
SCAMs (single component Angular modul...
For further actions, you may consider blocking this person and/or reporting abuse
What bout bundle sizes? Same/smaller/bigger? For small apps I belive that there will be no changes, have you any real-app example of comparing before-after state?
Individual Angular modules pretty much don't exist at runtime so no difference at all. They are compiled into static properties such as module injectors and transitive module scopes. If anything, big Angular modules declaring many declarables would result in larger bundles if it wasn't for the Angular Build Optimizer.
SCAMs can help guide the Angular compilers to split bundles more effectively.
If you're interested in before and after, try SAM4SC.
This doesn't seem to scale very well with larger applications. I started down this road, but there was just too much repetition to stomach. But maybe I'm missing something?
I would say it scales very well. We are able to refactor our application more easily because declarables are not tied to an Angular module that sets up declarations and compilation scope for multiple declarables.
What's the repetition you noticed?
On a side note, this was the first step towards components with local compilation scope. There are two more techniques, albeit experimental, that we cam use today. I didn't cover them in article yet because I thought we would get a stable API for this with Angular Ivy. However, that is still in the far end of the roadmap, so feel free to revisit these old techniques youtu.be/DA3efofhpq4
A large application has a lot of components. For each of those components, I now have to also create an NgModule for it and import any modules that export
declarations
that I depend on. So most likely, I'm at least importing CommonModule (for ngIf, async, etc) and probably some other ThirdPartyModule if I use third party components. So that's the first line of repetition.As I move further up the component tree from UI-interaction related components to business related components, I'm importing more ngModules for all the lower level components I need, and likely still CommonModule and ThirdPartyModule. So the result is a lot of
import { SomeComponentModule } from './some.component.ts'
and a long list NgModuleimports
.To quote the article "SCAMs mean more Angular modules since we will have one for every component, directive, and pipe in our application." This creates a lot of extra boiler code.
I can understand the value of refactoring: I can move the component anywhere and it already has all of the dependencies it needs, but I would also question how often that is a need.
Clarification question: Suppose I have some kind of compound component where I always use a combination of components in concert. Like, maybe I have something like:
If I wanted to follow the SCAM approach, there would be one module for each of these four components. So then anyone who wanted to use an accordion would have to import all 4 modules. Or would it be acceptable to create some parent AccordionModule that has no declarations and simply export all 4 component modules so that anyone who needs an accordion simply imports this single parent module?
The way I understand the SCAM approach and have been using it is not that you should literally have a module for every single component in your app. You should have one module for every single component that is reusable in isolation.
So, for instance, if I have a lazy-loaded OrderListModule that has a parent OrderListComponent and that parent has a child OrderDetailsComponent that is not reused anywhere in the app, I would just declare OrderDetailsComponent in the OrderListModule.
If I have a set of reusable components that are only meant to be used together, like in your example, I would also declare all of those in one module. If you look at the Angular Material project, that is how they do it.
That would be a feature module.
Heads up! There's an Angular issue open that builds on the idea of optional NgModules and suggests to make the declarable's selectors overridable and configurable, so that people can use them just the way we are currently using providers.
If you'd like to be able to use optional NgModules and the extended capabilities, please feel free to vote for the issue: github.com/angular/angular/issues/...
If the issue gets 20+ thumbups until June 23, 2021, it will be considered by the Angular team for implementation. 20 days left from now!
How do you share services?
Usually using tree-shakable providers. Or just importing them and providing them at the component level depending on the use case.
Thanks!