Enterprise Angular apps with Nx and monorepo approach
dtom@stibosystems.com
Problems we want to solve
- Code formatting
- Internal dependencies consistency
- Responsibilities leak
- External dependencies consistency
- Code sharing
- Sharing common practices in large teams
- Code ownership
- CI/CD scalability in large apps
- and more...
Monorepo
Based on experience of
Monorepo !== Monolith
Monorepo
Polyrepo
Monolith
Modular
Why not ?
Problem: External dependencies consistency
Nx
Nx ❤️ Monorepo
But is not a "full" monorepo
initial-workspace/
apps/ <-- All our apps (can be build and deployed separately)
libs/ <-- All our libs (encapsulated code with own APIs)
tools/ <-- All our tools (ex. local schematics)
.prettierrc <-- Prettier configuration file
angular.json <-- Angular configuration file
nx.json <-- Nx configuration file
package.json <-- Single package.json per repository
tsconfig.json <-- Main tsconfig.json applied to all apps/libs
tslint.json <-- Main tslint.json applied to all apps/libs
// equivalent commands
npx create-nx-workspace initial-workspace
npm init nx-workspace initial-workspace
yarn create nx-workspace initial-workspace
application
library
Problem: Code formatting
// package.json
"lint-staged": {
"*.{js,json,css,scss,md,ts,html,component.html}": [
"prettier --write",
"git add"
]
}
// package.json
// Check un-formatted files
"format:check": "./node_modules/.bin/nx format:check"
// Overwrite un-formatted files
"format:write": "./node_modules/.bin/nx format:write"
Problem: Code formatting
Problem: Internal dependencies consistency
npm run dep-graph
Trust but verify
Dependencies forbidden by default
// tslint.json
"nx-enforce-module-boundaries": [
true, // Enable functionality
{
"allow": [], // Exceptions
"depConstraints": [
{
// Explicit constraints
"sourceTag": "*",
"onlyDependOnLibsWithTags": ["*"]
}
]
}
]
// nx.json
"projects": {
...
"rent-data-access": {
"tags": ["scope:rent", "type:data-access"]
},
"shared-ui-buttons": {
"tags": ["scope:shared", "type:ui"]
}
...
}
// tslint.json
"nx-enforce-module-boundaries": [
true,
{
"allow": [],
"depConstraints": [
{
"sourceTag": "scope:payments",
"onlyDependOnLibsWithTags": ["scope:payments", "scope:shared"]
},
{
"sourceTag": "scope:rent",
"onlyDependOnLibsWithTags": ["scope:rent", "scope:shared"]
},
{
"sourceTag": "scope:shared",
"onlyDependOnLibsWithTags": ["scope:shared"]
},
{
"sourceTag": "type:ui",
"onlyDependOnLibsWithTags": ["type:ui"]
}
]
}
]
Problem: Internal dependencies consistency
Problem: Responsibilities leak
Relative path
Missing service in index.ts
index.js
Problem: Responsibilities leak
Problem: Code sharing
Monorepo
+
Nx build in limitations
+
Nx Tags
+
Nx libs index.js
Problem: Code sharing
Problem: Sharing common practices in large teams
Prettier
+
Nx Schematics
+
Custom Schematics
Problem: Sharing common practices in large teams
Problem: Code ownership
Nx Libs
+
Nx Libs index.ts
+
Nx Libs Readme files
Problem: Code ownership
Problem: CI/CD scalability in large apps
npm run affected:build -- --base=master
npm run affected:test -- --base=master
npm run affected:e2e -- --base=master
npm run affected:dep-graph -- --base=master
npm run affected:lint -- --base=master
npm run affected:apps -- --base=master
npm run affected:libs -- --base=master
// test / build / e2e / dep-graph / lint
npm run affected:test -- --base=master --parallel --maxParallel=4
npm run affected:test -- --base=SHA1 --head=SHA2
npm run affected:test -- --files=path/file1.ts,path/file2.ts
npm run affected:test -- --all
npm run affected:test -- --only-failed
Problem: CI/CD scalability in large apps
More...
Use new tools without configuration
// No Angular Only React workspace
npx create-nx-workspace happynrwl --preset=react
// React App in existing Empty/Angular/React workspace
ng g app frontend --framework=react
// Add node 'api' app for project 'my-project'
ng g node-app api --frontendProject=my-project
initial-workspace/
apps/
angular-app/
react-app/
node-app/
node-express-app/
node-nest-app/
typescript-app/
Add Nx to existing app
ng add @nrwl/schematics
Problems solved
- Code formatting (Prettier)
- Internal dependencies consistency (Nx tags)
- Responsibilities leak (Nx libs)
- External dependencies consistency (Monorepo)
- Code sharing (Nx libs, Monorepo)
- Sharing common practices in large teams (Schematics)
- Code ownership (Nx libs)
- CI/CD scalability in large apps (Nx affected)
- Use new tools without configuration hell (Nx)
- Add Nx to existing project
Thank You!
Nx
By Dariusz Tomaszewski
Nx
- 1,114