angular-architects / nx-ddd-plugin Goto Github PK
View Code? Open in Web Editor NEWNx plugin for structuring a monorepo with domains and layers
Nx plugin for structuring a monorepo with domains and layers
Help me decide please.
Notification should be domain or dumb shared or just a lib or a feature?
I need to load all notifications from the server and use setTimeout to trigger them.
I can add notification/delete and show all the notifications.
I have entities in the app such products
and they can be add notification with there extra metadata.
Email should be domain or dumb shared or just a lib or a feature?
most of my entities (such products, reports and so on) need sometimes to send a email. I can use within the products or other entity but if I use it more than once I think about to have it as a lib.
the question is it should be domain or shared or lib or a feature belong to domain?
Thanks
Which approach is better to create a ui-module (dumb components)?
Create ui-module-s per feature-
auth:
feature-login
ui-login-form
feature-register
ui-register-form
shared
social-links
OR
create one ui-module (ui-auth
) and inside all create all components for all features?
auth:
feature-login
feature-register
ui-auth:
lib/src/components/login-form
lib/src/components/register-form
lib/src/components/social-links
Hi,
the good news are: The library is already supporting eslint. If it detects an .eslintrc
file it assumes it should create its rules there.
Does this work for you?
Best wishes,
Manfred
Originally posted by @manfredsteyer in #39 (comment)
Trying to run on an Angular NX 10 project
ng g @angular-architects/ddd:feature search --domain explore
Getting the following error:
For publishable libs you have to provide a proper "--importPath" which needs to be a valid npm package name (e.g. my-awesome-lib or @myorg/my-lib)
If I go into the node_modules package and change:
schematics_1.externalSchematic('@nrwl/angular', 'lib', {
name: `feature-${options.name}`,
directory: options.domain,
tags: `domain:${options.domain},type:feature`,
style: 'scss',
prefix: options.domain,
publishable: true,
}),
i.e. if I change the line "publishable" to false - then it works 100% fine again...
Add an option to create components as Single Angular Module Schematics using the schematics.
Single Angular Module Schematics makes tree-shaking much better.
The file should have both decorators: @Component
and @NgModule
.
@Component(...)
export class Component...
@NgModule({
declarations: [Component...],
exports: [Component]
})
export class Module...
@manfredsteyer I can send PR quickly.
This error occurs when the plugin tries to create a library, e. g. a domain library.
This is related to the following issues in Nx 12.4:
nrwl/nx#6065
A temp. solution is downgrading to Nx 12.3.x
An error occurs during
Command:
ng add @angular-architects/ddd
Error:
Cannot read property 'toString' of null
I think it is because there is no tslint.json in the new generated workspace.
Got this error when trying to create a new library for the first time after migrating to Angular 12
Command:
npx nx g @angular-architects/ddd:ui qr-code --domain shared
Warning:
ui-options" schema is using the keyword "id" which its support is deprecated. Use "$id" for schema ID
npx create-nx-workspace@latest workspace-name --preset=empty --cli=angular --style=scss --nx-cloud=false
ng add @angular-architects/ddd
and nx add @angular-architects/ddd
Hi,
thank you for developing this great library and providing the related knowledge. While working with NX DDD, it turned out that I am struggling with the imports of a feature into another feature. There is a "shell" feature of a domain with all its routing. In the routing I want to specify a component from a feature within the same domain. This however is not allowed, because in the root .eslint.rc it says
{
"sourceTag": "type:feature",
"onlyDependOnLibsWithTags": [
"type:ui",
"type:domain-logic",
"type:util"
]
}
When I was reading through Nrwls "Enterprise Angular Monorepo Patterns" eBook, I found out that this type of restriction is not given here. Is this intended on your side or is the "type:feature" missing in the list of onlyDependOnLibsWithTags? If so, I would be happy to support and submit a PR.
Thank you in advance!
After I create a domain and feature using those commands:
nx generate @angular-architects/ddd:domain --name=report --directory=ui
nx generate @angular-architects/ddd:feature --name=search --domain=report --app=ng-app --domainDirectory=ui --lazy
The ddd
generate file search.component.ts
with wrong path:
import { SearchFacade } from '@org-ddd/report/domain';
should be with ui
like that:
import { SearchFacade } from '@org-ddd/report/ui/domain';
I'm using this plugin every day so this bug is really annoying.
@manfredsteyer I was send PR
I started to use nx-ddd-plugin
in my project and I created Auth
domain.
Inside auth
I have this structure:
auth
|-> domain
|-> feature-login
And I want to add a dumb component call login-form
. so I create login-form
under ui folder (this folder contains all dumb components that belong to auth
domain) . The schematics adds ui
prefix: ui-login-form
. inside I created a component: login-form
under components folder.
auth
|-> domain
|-> feature-login
|-> ui
|-> ui-login-form
|-> src/lib/components/login-form.component.ts
|-> auth-ui-ui-login-form.module.ts
I don't know something doesn't fit here..
The names are bad.
The problem is the selector created for me: login-form-login-form
. And also the module name is looking bad.
Any ideas how should I structure this domain with ui-module?
Sorry if this is a dumb question. I am just getting to learn about Angular libs.
I found that if I just use the nx cli command nx g @nrwl/angular:lib ui
the created library doesn't contain this tsconfig.lib.prod.json
file. So my questions are:
Thanks!
Can type:api
depend on another type:api
?
Consider the case when you have api-lib deepened on another api-lib
{
"sourceTag": "type:api",
"onlyDependOnLibsWithTags": [
"type:ui",
"type:domain-logic",
"type:util"
]
},
Currently a cannot extend the path to domain/feature like this: web/expert
.
Empty libs
folder. The workspace could contain multiple apps for different platforms (web, nativescript, ionic, electron etc.).
I could image two possible solutions:
directory
/
with -
to generate a nameIn the end we would have a more flexible way to organize the libs folder:
libs:
web:
admin:
domain
feature
mobile:
some-folder:
domain
feature
desktop:
I'm generating entities for an application we're building to integrate with Dynamics 365. Code is based on #35. I want to organize these into a directory
called cdm
My domains look like this:
# make the domains
nx generate @angular-architects/ddd:domain --directory=frontend --addApp --appDirectory=domain --ngrx --no-interactive --name=accounting
nx generate @angular-architects/ddd:domain --directory=frontend --addApp --appDirectory=domain --ngrx --no-interactive --name=admin
nx generate @angular-architects/ddd:domain --directory=frontend --addApp --appDirectory=domain --ngrx --no-interactive --name=core
nx generate @angular-architects/ddd:domain --directory=frontend --addApp --appDirectory=domain --ngrx --no-interactive --name=licensing
nx generate @angular-architects/ddd:domain --directory=frontend --addApp --appDirectory=domain --ngrx --no-interactive --name=marketing
nx generate @angular-architects/ddd:domain --directory=frontend --addApp --appDirectory=domain --ngrx --no-interactive --name=partner
nx generate @angular-architects/ddd:domain --directory=frontend --addApp --appDirectory=domain --ngrx --no-interactive --name=project
nx generate @angular-architects/ddd:domain --directory=frontend --addApp --appDirectory=domain --ngrx --no-interactive --name=referral
nx generate @angular-architects/ddd:domain --directory=frontend --addApp --appDirectory=domain --ngrx --no-interactive --name=sales
nx generate @angular-architects/ddd:domain --directory=frontend --addApp --appDirectory=domain --ngrx --no-interactive --name=service
nx generate @angular-architects/ddd:domain --directory=frontend --addApp --appDirectory=domain --ngrx --no-interactive --name=time
nx generate @angular-architects/ddd:domain --directory=frontend --addApp --appDirectory=domain --ngrx --no-interactive --name=user
nx generate @angular-architects/ddd:domain --directory=frontend --addApp --appDirectory=domain --ngrx --no-interactive --name=integrations
Goal: make core CDM entities: https://docs.microsoft.com/en-us/common-data-model/schema/core/applicationcommon/overview
nx generate @angular-architects/ddd:feature --domain=core --directory=cdm --app=core --appDirectory=domain --domainDirectory=frontend --lazy --ngrx --no-prefix --no-interactive --name='account' --entity='account'
nx generate @angular-architects/ddd:feature --domain=core --directory=cdm --app=core --appDirectory=domain --domainDirectory=frontend --lazy --ngrx --no-prefix --no-interactive --name='activity' --entity='activity'
nx generate @angular-architects/ddd:feature --domain=core --directory=cdm --app=core --appDirectory=domain --domainDirectory=frontend --lazy --ngrx --no-prefix --no-interactive --name='activity party' --entity='activity party'
nx generate @angular-architects/ddd:feature --domain=core --directory=cdm --app=core --appDirectory=domain --domainDirectory=frontend --lazy --ngrx --no-prefix --no-interactive --name='address' --entity='address'
nx generate @angular-architects/ddd:feature --domain=core --directory=cdm --app=core --appDirectory=domain --domainDirectory=frontend --lazy --ngrx --no-prefix --no-interactive --name='appointment' --entity='appointment'
nx generate @angular-architects/ddd:feature --domain=core --directory=cdm --app=core --appDirectory=domain --domainDirectory=frontend --lazy --ngrx --no-prefix --no-interactive --name='article' --entity='article'
nx generate @angular-architects/ddd:feature --domain=core --directory=cdm --app=core --appDirectory=domain --domainDirectory=frontend --lazy --ngrx --no-prefix --no-interactive --name='article comment' --entity='article comment'
nx generate @angular-architects/ddd:feature --domain=core --directory=cdm --app=core --appDirectory=domain --domainDirectory=frontend --lazy --ngrx --no-prefix --no-interactive --name='article template' --entity='article template'
I need to be able to enter the directory
parameter "N" levels deep like so:
--directory=cdm/application-common/foundation-common/crm-common/project-service-automation
We won't support need support for camelCase filenames ... only "hyphen-case" with all lowercase characters. Classes are generated LikeThis within typescript anyway
I want to add custom tags, like --tags=platform:desktop
or --tags=platform:web
or --tags=platform:mobile
when generating a Feature
When installing and using the ng generate @angular-architects/ddd:feature
in Angular 9 it is working as expected:
> Executing task: ng generate @angular-architects/ddd:feature --name=test --domain=mydomain --no-interactive --dry-run
CREATE libs/mydomain/feature-test/README.md (180 bytes)
CREATE libs/mydomain/feature-test/tsconfig.lib.json (411 bytes)
CREATE libs/mydomain/feature-test/tsconfig.lib.prod.json (97 bytes)
CREATE libs/mydomain/feature-test/tslint.json (265 bytes)
...
But after an update to Angular 10 following error occurs executing the same command again
$ ng generate @angular-architects/ddd:feature --name=test --domain=mydomain --no-interactive --dry-run
Specified app mydomain does not exist: apps/mydomain/src/app/app.module.ts expected!
In the package.json the @angular-architects/ddd got updated to
"@angular-architects/ddd": "^1.3.0",
Has anything else to be adapted for the update in order to get the generator back to work?
I haven't been successful in using Nx's native move command to, for example,
nx g @nrwl/angular:move --project property-ui-card inventory/inventory-ui-hotel-card
Getting error:
RangeError: path should be a `path.relative()`d string, but got "."
at throwError (/Users/crash/git/iko-travel-spa/node_modules/ignore/index.js:366:9)
at checkPath (/Users/crash/git/iko-travel-spa/node_modules/ignore/index.js:385:12)
at Ignore._test (/Users/crash/git/iko-travel-spa/node_modules/ignore/index.js:502:5)
at Ignore.ignores (/Users/crash/git/iko-travel-spa/node_modules/ignore/index.js:541:17)
at Object.visitNotIgnoredFiles (/Users/crash/git/iko-travel-spa/node_modules/@nrwl/devkit/src/generators/visit-not-ignored-files.js:15:71)
at Object.updateImports (/Users/crash/git/iko-travel-spa/node_modules/@nrwl/workspace/src/generators/move/lib/update-imports.js:41:22)
at /Users/crash/git/iko-travel-spa/node_modules/@nrwl/workspace/src/generators/move/move.js:23:26
at Generator.next (<anonymous>)
at /Users/crash/git/iko-travel-spa/node_modules/tslib/tslib.js:117:75
at new Promise (<anonymous>)
path should be a `path.relative()`d string, but got "."
Here I am trying to move a module under the 'property' domain to another domain called 'inventory' and rename the module to fit where it's located.
I'm not even sure if this is possible/feasible but I am looking for a way to add custom build options when creating a new domain, namely stylePreprocessorOptions and extractCss so that my shared styles are automatically included in the new domain. Based on my limited understanding and research it looks like extending the existing schematic is the best way to accomplish this but I am running into an issue tracking down exactly what needs to be extended.
Another nice to have would be being able to add code when generating a feature. In this case just adding '@use variables;' to the features scss file to pull in access to all the shared styles.
nx generate @angular-architects/ddd:domain --directory='' --addApp --appDirectory='domain' --ngrx --no-interactive --name='core'
nx generate @angular-architects/ddd:feature --domain=core --app='core' --appDirectory='domain' --domainDirectory='' --lazy --ngrx --no-prefix --no-interactive --directory='cdm' --name='account' --entity='account'
Change import { CdmAccountComponent } from './cdm-account.component';
to import { CdmAccountComponent } from './account.component';
The many packages generates too many slashes in the name. so they can't be publish to npm. (need to rename the names which can be confusing).
such:
@myorg/products/ui/domain
@myorg/products/ui/feature-xxx
As mentioned in your article series, shared libraries can and should be used to share logic, which does not belong to a specific domain, like technical stuff (authenticaton, ...).
Since the nx ddd plugin adds a lot of constraints to the tslint.json, generating a shared lib via the nrwl schematics would require the developer to add a tag for the type and to add a tag for the domain (--> shared). Otherwise, the shared lib can not be used within the generated libs by this plugin.
I think, it would make sense to add a schematic which creates a shared lib for you with
In the end, this would enforce a meaningful folder structure and it would free the dev from adding those tags manually. Especially DEVs not used to the nx linting rules might have problems solving the issue, when the tags are missing.
Please let me know, what you think. I'd be happy to support with a PR again.
nx
version: 10.4.4@angular-architects/ddd
version: ^1.1.0TL;DR;
In nx project configured with eslint, the generated eslint config should be put inside the top-level overrides
array instead of overwriting the whole .eslintrc.json
file
More details:
.eslintrc.json
after running nx add @angular-architects/ddd
and/or nx g @angular-architects/ddd:domain blog
:{
"files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
"rules": {
"@nrwl/nx/enforce-module-boundaries": [
"error",
{
"enforceBuildableLibDependency": true,
"allow": [],
"depConstraints": [
{
"sourceTag": "type:app",
"onlyDependOnLibsWithTags": [
"type:api",
"type:feature",
"type:ui",
"type:domain-logic",
"type:util"
]
},
{
"sourceTag": "type:api",
"onlyDependOnLibsWithTags": [
"type:ui",
"type:domain-logic",
"type:util"
]
},
{
"sourceTag": "type:feature",
"onlyDependOnLibsWithTags": [
"type:ui",
"type:domain-logic",
"type:util"
]
},
{
"sourceTag": "type:ui",
"onlyDependOnLibsWithTags": ["type:domain-logic", "type:util"]
},
{
"sourceTag": "type:domain-logic",
"onlyDependOnLibsWithTags": ["type:util"]
},
{
"sourceTag": "domain:shared",
"onlyDependOnLibsWithTags": ["domain:shared"]
},
{
"sourceTag": "domain:blog",
"onlyDependOnLibsWithTags": ["domain:blog", "domain:shared"]
}
]
}
]
}
}
.eslintrc.json
:{
"root": true,
"ignorePatterns": ["**/*"],
"plugins": ["@nrwl/nx"],
"overrides": [
{
"files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
"rules": {
"@nrwl/nx/enforce-module-boundaries": [
"error",
{
"enforceBuildableLibDependency": true,
"allow": [],
"depConstraints": [
{
"sourceTag": "type:app",
"onlyDependOnLibsWithTags": [
"type:api",
"type:feature",
"type:ui",
"type:domain-logic",
"type:util"
]
},
{
"sourceTag": "type:api",
"onlyDependOnLibsWithTags": [
"type:ui",
"type:domain-logic",
"type:util"
]
},
{
"sourceTag": "type:feature",
"onlyDependOnLibsWithTags": [
"type:ui",
"type:domain-logic",
"type:util"
]
},
{
"sourceTag": "type:ui",
"onlyDependOnLibsWithTags": ["type:domain-logic", "type:util"]
},
{
"sourceTag": "type:domain-logic",
"onlyDependOnLibsWithTags": ["type:util"]
},
{
"sourceTag": "domain:shared",
"onlyDependOnLibsWithTags": ["domain:shared"]
},
{
"sourceTag": "domain:blog",
"onlyDependOnLibsWithTags": ["domain:blog", "domain:shared"]
}
]
}
]
}
},
{
"files": ["*.ts", "*.tsx"],
"extends": ["plugin:@nrwl/nx/typescript"],
"parserOptions": { "project": "./tsconfig.*?.json" },
"rules": {}
},
{
"files": ["*.js", "*.jsx"],
"extends": ["plugin:@nrwl/nx/javascript"],
"rules": {}
}
]
}
Otherwise, nx lint
will fail with error:
An unhandled exception occurred: ESLint configuration in apps/desci/.eslintrc.json » ../../.eslintrc.json is invalid:
- Unexpected top-level property "files".
Referenced from: /home/xzhan/Development/Projects/desci_online/frontend/apps/desci/.eslintrc.json
See "/tmp/ng-taMiLt/angular-errors.log" for further details.
In the source code missing schematics for adding api library with type:api
tag.
Sometimes developers can forget to add this tag every time they create @nrwl/node:lib
so I think it should be option to create such a library.
When running schematics and when I have workspace.json
and not angular.json
, I have to temporarily rename mv workspace.json angular.json
Hi, I'm new to this plugin, so I was learning how do to things.
I've found in nx-ddd-plugin/libs/ddd/collection.json
, these types: domain
, feature
, ui
and util
.
And in this issue, #15 (comment), something like this:
ng g [...]:domain
ng g [...]:feature
ng g [...]:util
ng g [...]:ui
ng g [...]:api
But when I try this command: ng g @angular-architects/ddd:ui todo
It gives me this error:
$ nx g @angular-architects/ddd:ui todo
An unhandled exception occurred: Schematic "ui" not found in collection "@angular-architects/ddd".
See "/private/var/folders/5q/vp21tsm932z9chmrch5ch6tc0000gn/T/ng-91UPZX/angular-errors.log" for further details.
error Command failed with exit code 127.
Os: MacOs Catalina
Node: v14.14.0
Yarn: 1.22.10
Angular: v9
Nx: v9
I want to speed up my workspace development with this plugin, so, any help will be appreciated.
Thanks.
I don't understand why we are forced to generate an app when we just want to generate a domain using ngrx flag. Could the plugin not just skip adding the root store part in an app.
Also the current documentation is unclear because these commands:
ng g @angular-architects/ddd:domain booking --addApp --ngrx
ng g @angular-architects/ddd:feature search --domain booking --entity flight --ngrx
[...]
Do not result in the dependency graph as shown.
My current workaround is to generate a domain and clean up afterwards, could this be changed in the future?
Assuming I have two domains, a product and an order, the order requires data from the product and then has to access the corresponding domain via an API. What could an API look like here? Is the product data service for the other domain simply exported in a module?
For those interested I was attempting to have storyboard with DDD-plugin, but for some reason the tsconfig.json
thats is being passed is based on the project app name and not for the feature it self.
I encountered an error like this:
info => Using angular project 'admin' for configuring Storybook.
ERR! SyntaxError: Unexpected token } in JSON at position 223
ERR! at JSON.parse ()
ERR! at getTsConfigOptions (/node_modules/@storybook/angular/dist/server/angular-cli_config.js:41:25)
ERR! at Object.getAngularCliWebpackConfigOptions (/node_modules/@storybook/angular/dist/server/angular-cli_config.js:121:20)
ERR! at Object.webpackFinal (/node_modules/@storybook/angular/dist/server/framework-preset-angular-cli.js:8:56)
ERR! at /node_modules/@storybook/core/dist/server/presets.js:260:28
ERR! SyntaxError: Unexpected token } in JSON at position 223
ERR! at JSON.parse ()
ERR! at getTsConfigOptions (/node_modules/@storybook/angular/dist/server/angular-cli_config.js:41:25)
ERR! at Object.getAngularCliWebpackConfigOptions (/node_modules/@storybook/angular/dist/server/angular-cli_config.js:121:20)
ERR! at Object.webpackFinal (/node_modules/@storybook/angular/dist/server/framework-preset-angular-cli.js:8:56)
ERR! at /node_modules/@storybook/core/dist/server/presets.js:260:28
admin
being my project app name
so I went through the process of trying to understand the problem with my tsconfig
's, and found out that it was pushing in the admin
tsconfig.json
and not the lib feature one.
After searching a while I encountered this nrwl/nx#2560 (comment) and added a new project both to nx.json and angular.json and it worked.
angular.json
"projects": {
"storybook": {
"projectType": "application",
"root": "",
"architect": {
"build": {
"options": {
"tsConfig": "tsconfig.base.json"
}
}
}
},
"admin": {
"projectType": "application",
// ...
},
// ...
Hope this helps someone.
To the maintainer not sure if you think of this as a bug / feature. so you decide if it should be closed.
What am I missing?
ng g @angular-architects/ddd:domain admin --add-app
Path "/libs/admin/domain/src/lib/admin-domain.service.ts" does not exist.
The use case is very helpful for very large domains with many reactive entities. The module tends to become large when it could be separated into separate features.
Example:
apps:
- my-app
libs:
- my-app
- domain
- +state
- feature-1
- feature-2
- feature-100
- feature-1
- feature-2
- feature-100
Instead:
apps:
- my-app
libs:
- my-app
- domain -> +state
- feature-core-1
- feature-core-2
- my-app-feature-1
- domain -> +state
- feature-1-create
- feature-1-update
- my-app-feature-2
- domain -> +state
- feature-2-create
- feature-2-update
- my-app-feature-100
- domain -> +state
- feature-100-create
- feature-100-update
All feature libraries would depend on domain and parent domain modules:
MyAppFeature100CreateModule {
imports: [CommonModule, MyAppDomainModule, MyAppFeature100DomainModule]
}
Thoughts on this appreciated. I want to avoid creating ui modules and then rename them to feature because they contain reactive code.
Cheers on a great plugin!
Why is ${libName}/${options.directory}
Instead of ${options.directory}/${libName}
I think Domain is unique, which means that Domain/Directory can only have one directory.
We might need something like this:
libs/management/user/domain
libs/management/user/feature-**
libs/management/dept/domain
libs/management/dept/featue-**
Did I understand it wrong?
Happens when adding a domain. Might be resolved if #41 gets resolved
Hi,
we are currently struggling when we want to publish our libraries to make them accessible for other teams. On a look on the generated import paths we saw:
@scope/moduleName/feature
I guess for being publishable it should be:
@scope/moduleName-featureName
Or did we misunderstand the approach?
regards
sebastiano
ng g @angular-architects/ddd:domain IAM
Generates wrong naming:
export class IamDomainModule {}
This will generate the wrong naming within the feature:
@NgModule({
imports: [CommonModule, IAMDomainModule], // <-- should be IamDomainModule
declarations: [UserComponent],
exports: [UserComponent],
})
export class IamFeatureUserModule {}
I suppose this is working as intended. I would have assumed that the naming would be as is on the creation of the domain.
What type of service I write in application?
What type of service I write in infrastructure?
for example I have a button when clicking on the button I go to the api and get the data. how application
and infrastructure
fit in this example?
Thanks
Hi, I like what the plugin does. However, tslint IS deprecated, which prevents me from using the package. Angular 11 flags tslint as deprecated too. Is there a timeline to switch to eslint?
Thanks
By generating domains I get this folder structure:
libs:
company:
domain:
src:
lib:
domain.module.ts
index.ts
...
expert:
domain:
src:
lib:
domain.module.ts
index.ts
...
Then I wanna import company and expert "modules". There're at least two ways to import:
import()
There is no problem with the lazy approach but with non lazy:
import { DomainModule as ExpertModule } from '@workspace/expert/domain';
import { DomainModule as CompanyModule } from '@workspace/company/domain';
@NgModule({
imports: [
ExpertModule,
CompanyModule,
]
})
...
In the sample above I need to use aliases as ExpertModule
and as CompanyModule
to be able to import both modules with the identical class name. We, devs, are pretty lazy and that approach compels us to add an extra alias for every lib/module name.
What about class names that match the names passed in while generating a lib?
While many apps probably do work fine with simple BehaviorSubjects within the facades, it would be great to be able to scaffold ngrx code when generating a (domain?) library via a flag, so it's easier for developers to generate that code in a consistent manner across a monorepo.
While technically, this shouldn't be too hard by using the nx ngrx schematics, I'm wondering how to structure the code reasonably.
Nx recommends having feature level states, however, the domain-driven setup we have with this plugin requires the state of all feature libs for a domain to live inside the domain library. Would you have separate Feature-States within Domain-Feature-Modules and import them in the specific Feature-Modules or would you add all ngrx Stuff to the Domain-Module?
Do you have any examples following some best practices about structuring an ngrx managed state with the library structure of the nx-ddd-plugin? The demo apps all make use of BehaviorSubjects only to manage the state.
When working in monorepos one of the biggest benefits is sharing code between multiple applications. This is particularly useful when you have backend and front end that can share an interface as a sort of contract between the two.
NestJS by design is extremely similar to Angular in architecture and I believe Domain Driven Design would be very appropriate for it.
There are three challenges I would like to see a NestJS feature tackle.
Code Organization. In the current model we use the libs folder as a list of domains. This may become disorganized if libraries are created that are not domains like api-interfaces
. I would like to see some thought given to a pattern that would keep things organized and for the schematics to follow that pattern and for it to be documented in the README.md
.
NestJS Schematics. This one is pretty simple, I would like to see NestJS schematics added to generate domains and features specific for NestJS.
Universal Schematics. I would like to see schematics added that would allow a domain to be consumed either by Angular or by NestJS. Of course the features in that domain will need to be either Angular or NestJS specific but it would be nice to keep a universal domain with two entry points.
One more thing could be added to push this to the next level, automatically tagging generated libraries. This would be very useful for restricting imports from Angular to NestJS and vice versa.
Given the naming of this library @angular-architects
this feature request very well may be out of scope, however given the request for Universal Schematics, I don't believe a new library focused around NestJS domain driven design would be appropriate either. I would really like some feedback on this whole idea @manfredsteyer. I would be happy to contribute in anyway I can.
After upgrading this plugin to Nx 11, when running:
nx generate @angular-architects/ddd:domain --addApp --ngrx --no-interactive --name=accounting
you get the error: Cannot read property 'root' of undefined
I've traced it to root: true on line 62 of libs/ddd/src/schematics/domain/index.ts
options.addApp && options.ngrx
? chain([
externalSchematic('@ngrx/schematics', 'store', {
project: options.name,
root: true,
minimal: true,
module: 'app.module.ts',
name: 'state',
}),
addNgrxImportsToApp(appModulePath),
addNgRxToPackageJson(),
])
: noop(),
Using @ngrx/[email protected]
https://ngrx.io/guide/schematics/store
Manfres, This is a great plugin for nx tooling. Thank you for creating this.
Can you please generate the 'feature' with angular style guide convention. i,e please keep the type to the end. i.e name.type.exn
Example: instead of "feature-search" name it "search-feature" so it's consistent with other artifacts.
https://angular.io/guide/styleguide#general-naming-guidelines.
I create a shared ui library (libs/shared/ui/ui-common
) and I want to use it inside domain/ui-xxx but I got an error:
A project tagged with "type:ui" can only depend on libs tagged with "type:domain-logic", "type:util"
The UI inside domain-lib can't depend on shared?
When I use the nx-ddd-plugin to scaffold a domain library + a feature library, the libraries are always added as publishable libraries (with extra package.json
+ build target in angular.json
, etc.) without the option to make it non publishable (if I didn't miss something).
This has the following drawbacks:
angular.json
angular.json
to make nx affected:build
work. This ofc is an annoying workaround.--> Errors appear (like within the previously noted nx github issue)
The option to have a publishable lib should at least be avoidable by providing a flag.
By looking at the source code, I recognized, that you call the nrwl angular lib
schematic without any kind of publishable flag. Since publishable is defaulted to false within the nrwl angular lib
schematic, I'm quite confused about the nx-ddd-plugin creating publishable libs.
How to import ui component without breaking ddd rules?
I have libs/reports/ui-grid
and I want to import it in libs/dashboard/feature-shell
.
This library contains a list of cards display list of reports details (the data come from report service inside the domain).
--
How should I do it without breaking the ddd rules?
ui-grid
and import it in dashabord/feature-shell
?libs/shared
and import the shared in dashabord/feature-shell
and get the data from libs/report/api
?libs/report/api
and import it in dashabord/feature-shell
?I noticed Peter gave a demo using vscode and saw the generate @angular-architects/ddd:domain, etc when using the nx console.
In webstorm 2020.3.2 when using the nx console, I do not see the @angular-architects:ddd options..... in the list of schemaitics.
Also what is the proper way to add @angular-architects:ddd using nx?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.