The ideal project structure is something that keeps moving.
So, a good project structure is something easy to refactor.
Few hours ago, I published this article about SCAM modules:
And this Angular schematic called @wishtack/schematics:scam
:
… then the annoying side of my brain was like:
OK! … and now, how do you regroup related components? And how do you handle routing?
Proxy Modules
In order to regroup related components & modules, I use what I call “proxy” modules.
A proxy module is a module that doesn’t declare anything, it just exports other modules in order to regroup & expose them.
Here’s an example of a proxy module.
@NgModule({
exports: [
MatButtonModule,
ReactiveFormsModule,
MyFunkyInputModule
]
})
export class SharedFormsModule {
}
DRY
A proxy module exports all the modules it imports, so let’s not repeat ourselves.
It’s still better to avoid them though.
Rule of Thumb
- Let your team vote and choose a number (named X) between 3 and 7.
- Now, you can’t have more than X components or X imports per module.
- You can vote again…
View Modules
One of the most confusing things I noticed when meeting new Angular apps is that it’s hard to tell which modules are Routed Modules and which are not.
To avoid this issue, I recommend dedicating a directory called views
to Routed Modules which we will call View Modules and view components following the rules below:
- Outside from View Modules (modules inside the
views
directory), no other module is defining any routes. - View components (components inside the
views
directory) are the only components allowed to read params & query params from the activated route. - View Modules shouldn’t export anything.
Example
views/app-routing.module.ts
:
views/sandwich/sandwich-views.module.ts
:
You should end up with a project structure that should look something like this.
app/
sandwich/
sandwich-catalog/
sandwich-catalog.component.ts|html
sandwich-form/
sandwich-form.component.ts|html
sandwich-picture/
sandwich-picture.component.ts|html
sandwich-preview/
sandwich-preview.component.ts|html
user/
...
views/
landing-view/
landing-view.component.ts
sandwich-views/
sandwich-views.module.ts
sandwich-catalog-view/
sandwich-catalog-view.component.ts
sandwich-detail-view/
sandwich-detail-view.component.ts
sandwich-editor-view/
sandwich-editor-view.component.ts
Note that
app/sandwich
is not an Angular module but just a directory that regroups SCAM modules.You can also note that
LandingViewComponent
which is inapp/views/landing-view/landing-view.component.ts
is free to use a component from a SCAM module inapp/sandwich
without having to refactor or load aSandwichModule
that would contain all these components (and which doesn’t exist with this kind of project structure).
Key Takeaways
This project structure has three kinds of modules:
- SCAM modules with one component per module.
- Proxy Modules to regroup stuff. These modules don’t declare anything.
- View Modules that handle the routing.
… and should following the rules below:
- Avoid having more than 7 imports per module.
- Separate view modules from the rest.
- Outside from View Modules (modules inside the
views
directory), no other module is defining any routes. - View components (components inside the
views
directory) are the only components allowed to read params & query params from the activated route. - View Modules shouldn’t export anything.
If you want to learn more about Angular and if you can read French (or if you don’t mind using google translate meanwhile I translate the content), you can have a look at our FREE Angular Guide https://guide-angular.wishtack.io/.