https://gist.github.com/trungk18/7ef8766cafc05bc8fd87be22de6c5b12
Below is the sample folder structure for Nx with NestJS and Angular. Our principles are:
RegisterComponent
will have a corresponding RegisterModule
, we wonβt declare RegisterComponent
as part of AuthModule
for example.libs
folder. New modules, new models, new configurations, new components etcβ¦ are in libs. libs should be separated into different directories based on existing apps. We wonβt put them inside the apps
folder. For example in an Angular, it contains the main.ts
, app.component.ts
and app.module.ts
.
βββ root
βββ apps
β βββ api (nestjs)
β βββ client (angular)
βββ libs (1)
βββ api (dir)
β βββ core (dir)
β β βββ feature (nest:lib) (2)
β βββ feature-1 (dir)
β β βββ data-access (nest:lib, service + entities)
β β βββ feature (nest:lib, module + controller)
β β βββ utils (nest:lib, things like interceptors, guards, pipes etc...)
β βββ feature-2 (dir)
β βββ data-access (nest:lib, service + entities)
β βββ feature (nest:lib, module + controller)
β βββ utils (nest:lib, things like interceptors, guards, pipes etc...)
βββ client (dir)
β βββ shell (dir)
β β βββ feature (angular:lib) (3)
β βββ feature-1 (dir)
β βββ data-access (angular:lib, service, API calls, state management)
β βββ feature (4)
β β βββ list (angular:lib e.g. ProductList)
β β βββ detail (angular:lib e.g. ProductDetail)
β βββ ui (dir)
β β βββ comp-1 (angular:lib, SCAM for Component)
β β βββ pipe-1 (angular:lib, SCAM for Pipe)
β βββ shared (dir)
β βββ data-access (angular:lib, any Service or State management to share across the Client app)
β βββ ui (dir, 5)
β βββ utils (angular:lib, usually shared Guards, Interceptors, Validators...)
βββ shared (dir, most libs in here are buildable @nrwl/angular:lib)
βββ data-access (my shared data-access is usually models, so it is a lib)
βββ ui (optional dir, if I have multiple client apps)
βββ utils (optional dir, usually validation logic or shared utilities)
βββ util1 (lib)
βββ util2 (lib)
(1) lib vs dir
(2) api-core-feature
: this is the CoreModule that will include all initial setups like Config and Database Connection etc⦠and importing other Modules. CoreModule will be imported by AppModule
(3) client-shell-feature
: Same idea as NestJSβs CoreModule. This Shell includes RouterModule.forRoot()
(4) client-feature-1-feature
: This can either a dir or a lib.
βββ feature
βββ list (angular:lib e.g ProductList)
βββ detail (angular:lib e.g. ProductDetail)
feature
usually contains the ContainerComponent and the RouterModule.forChild()
(5) client-shared-ui
is a little tricky. The general recommendation is to NOT grouped stuffs by type like components
, pipes
etc⦠into a single module but because these are shared, it is easy to get quite messy if not grouped by type. This is your call. We prefer to have a Single Component Per Module (SCAM) for each angular library.
This structure is proposed by my friend Chau Tran and I am applying it for my latest project!
Following the above structure will bring three advantages:
data-access
: data-access
can import other data-access
. But never import its feature
. For example: user/data-access
can import from product/data-access
but it will never import from user/feature
feature
: can only import its own data-access
or the global shared/data-access
. For example: user/feature
can import from user/data-access
but never from product/data-access
.util
: Utils can be shared across data-access
, util
.