Forsidebillede af John Moeses Bauan på Unsplash.
Original udgivelsesdato:2020-03-23.
I Nx-arbejdsområder kan vi følge en strategi om at holde vores Angular-applikationsprojekter så små som muligt for at have færre grunde til at ændre applikationsprojektet og muliggøre genbrug af almindelig kode. Det gør vi ved at indkapsle forretningslogik og konfiguration i arbejdsrumsbiblioteker.
En taktik ved denne strategi er at bruge et af shell-biblioteksmønstrene til orkestrering af initialisering, konfiguration og routing. For arbejdsområder med en enkelt applikation som denne er et feature shell-bibliotek et godt valg.
Denne shell-biblioteksvariant er også den, der bevarer den mindste mængde logik i applikationsprojektet, hvilket er meget velegnet til vores formål. Vi vil dog ikke gennemgå oprettelsen af denne type bibliotek i denne artikel.
Lad os i stedet sætte skub i dette ved at udtrække arbejdsområdebiblioteker til statiske aktiver, stilarter og miljøer.
Vi gennemgår kommandoerne og trinene for at konfigurere et komplet Nx Angular-arbejdsområde og anvender en lille applikationsprojektstrategi. Bagefter vil vi diskutere fordelene ved de forskellige taktikker og teknikker, vi bruger til at anvende den lille applikationsprojektstrategi.
Opret et Nx-arbejdsområde med en Angular-applikation
For at demonstrere dette opretter vi et Nx-arbejdsområde med en enkelt Angular-applikation. Udfør kommandoerne i liste 1.
npx create-nx-workspace workspace --cli=angular --preset=angular --appName=tiny-app --style=scss
nx update @angular/cli @angular/core
Vi opretter arbejdsområdebiblioteker, som applikationen kan importere gennem @workspace
omfang.
Udpak et aktivarbejdsområdebibliotek
Når vi genererer en Angular-applikation, kommer den med en tom assets
mappe til statiske filaktiver såsom ikoner, billeder og webskrifttyper. Vi kan referere til disse aktiver fra DOM-elementattributter og typografiark ved at bruge absolutte stier, for eksempel <img src="/assets/images/logo.png" />
og .twitter { background-image: url('/assets/icons/twitter.png'); }
.
Genererede Angular-applikationer kommer også med den statiske fil favicon.ico
som der henvises til i index.html
. Vi genererer et aktivarbejdsområdebibliotek, udtrækker vores statiske aktiver til det, konfigurerer arbejdsområdet og opdaterer referencer for at bruge aktivbiblioteket.
Generer et rent arbejdsområdebibliotek
Det første trin er at generere et arbejdsområdebibliotek og rydde op i det, da det ikke vil indeholde TypeScript-filer, kun statiske filer.
nx generate library assets --directory=shared --tags="scope:shared,type:assets" --style=scss
npx rimraf ./apps/tiny-app/src/assets ./libs/shared/assets/*.js ./libs/shared/assets/*.json ./libs/shared/assets/src/*.* ./libs/shared/assets/src/lib
"# shared-assets" > ./libs/shared/assets/README.md
Udfør kommandoerne i liste 2, og rediger derefter angular.json
for at fjerne alle arkitektmål fra shared-assets
projekt for at matche konfigurationsstrukturen i liste 3.
{
"//": "angular.json",
"projects": {
"shared-assets": {
"architect": {}
}
}
}
Opsæt mapper med almindelige aktiver, og flyt faviconet
Nu hvor vi har en ren arbejdsområdebiblioteksmappestruktur, lad os oprette fælles aktiver-mapper og flytte favicon-filen til vores aktiverbibliotek ved at udføre kommandoerne i Listing 4.
npx mkdirp ./libs/shared/assets/src/assets/fonts ./libs/shared/assets/src/assets/icons ./libs/shared/assets/src/assets/images
"" > ./libs/shared/assets/src/assets/fonts/.gitkeep
"" > ./libs/shared/assets/src/assets/icons/.gitkeep
"" > ./libs/shared/assets/src/assets/images/.gitkeep
mv ./apps/tiny-app/src/favicon.ico ./libs/shared/assets/src
For at konfigurere Angular-applikationsprojektet til at bruge aktiverne i arbejdsområdebiblioteket, navigerer vi til tiny-app:build
arkitektmål i angular.json
og erstat assets
muligheder med posterne i liste 5.
{
"//": "angular.json",
"projects": {
"tiny-app": {
"architect": {
"build": {
"options": {
"assets": [
{
"glob": "favicon.ico",
"input": "libs/shared/assets/src",
"output": "./"
},
{
"glob": "**/*",
"input": "libs/shared/assets/src/assets",
"output": "assets"
}
]
}
}
}
}
}
}
Vi instruerer Angular CLI om at kopiere favicon-filen til dist/apps/tiny-app
mappe, når du bygger applikationen. Derudover alle filer og mapper i libs/shared/assets/src/assets
mappen kopieres til dist/apps/tiny-app/assets
ved byggeprocessen. Dette vil holde vores applikations aktiver-links i drift i vores ikke-lokale miljøer, såsom vores iscenesættelse og produktionswebservere.
Prøv det lokalt
Gå videre, prøv det lokalt med nx serve --open
på Webpack-udviklingsserveren. Udfør kommandoerne i liste 6 for at bygge et produktionsprogrampakke og betjene det ved hjælp af en lokal statisk webserver. Sørg for, at favicon vises begge steder.
nx build --prod
npx http-server dist/apps/tiny-app -o
Samle et aktiv
Nx-genererede Angular-applikationer viser et Nx-logo i deres app-komponent, som det ses øverst i figur 1.
Hvis vi åbner app.component.html
, ser vi, at logoet er linket fra https://nx.dev/assets/images/nx-logo-white.svg
.
Lad os gøre logoet til en del af vores applikationspakke ved at inkludere det i vores aktivbibliotek og opdatere billedattributten i app-komponentens skabelon.
Udfør kommandoen i liste 7 for at downloade Nx-logoet og gemme det i aktivbiblioteket.
npx -p wget-improved nwget https://nx.dev/assets/images/nx-logo-white.svg -O ./libs/shared/assets/src/assets/images/nx-logo-white.svg
Lad os nu opdatere billedelementet for at referere til logoet fra vores aktivbibliotek. Rediger app.component.html
som vist i liste 8.
<!-- app.component.html -->
<img
alt="Nx logo"
width="75"
src="/assets/images/nx-logo-white.svg"
/>
Det er det. Vi udpakkede et aktivarbejdsområdebibliotek og bundtede statiske filer. Prøv det en gang til for at sikre dig, at alt er konfigureret korrekt.
Udpak et stilarbejdsområdebibliotek
Vinkelapplikationer genereres med et globalt typografiark kaldet styles.css
eller i vores tilfælde styles.scss
da vi bruger Sass. Det globale typografiark kan indeholde generiske typografier, elementtypetypografier, CSS-objekter og hjælpetypografier.
Et globalt stylesheet bliver større og mere komplekst, efterhånden som en applikation udvikler sig. Når vi bruger Sass, kan vi opdele et typografiark i Sass-partialer, som sædvanligvis har navne foran med en understregning (_
), for eksempel _global.scss
.
Sass-partialer er bundtet ved hjælp af import-sætninger, for eksempel @import './lib/global';
. Bemærk, at Sass bruger konvention til at finde filen, uanset om dens navn har et understregningspræfiks eller ej.
I modsætning til vanilla CSS, indlæses Sass' importerklæringer ikke en ad gangen, asynkront. I hvert fald ikke når vi refererer til vores applikations statiske aktiver. I stedet er de samlet i et enkelt stylesheet. Dette svarer til, hvordan vi er vant til værktøjer som Webpack og Browserify, der samler JavaScript- og TypeScript-filer.
Vi vil gøre vores Angular-applikationsprojekt mindre ved at udtrække et bibliotek med stilarter, konvertere styles.scss
til en Sass-del, bundter den som en del af et arbejdsområdebiblioteksstilark og konfigurer vores applikationsprojekt til at linke til dette typografiark.
Generer et rent arbejdsområdebibliotek
Som vi gjorde i et tidligere kapitel, starter vi med at generere et arbejdsområdebibliotek og rydde op i det, da det kun vil indeholde typografiark, ikke TypeScript-filer.
nx generate library styles --directory=shared --tags="scope:shared,type:styles" --style=scss
npx rimraf ./libs/shared/styles/*.js ./libs/shared/styles/*.json ./libs/shared/styles/src/*.* ./libs/shared/styles/src/lib/*.*
"# shared-styles" > ./libs/shared/styles/README.md
Udfør kommandoerne i liste 9, og rediger derefter angular.json
for at fjerne alle arkitektmål fra shared-styles
projekt for at matche konfigurationsstrukturen i liste 10.
{
"//": "angular.json",
"projects": {
"shared-styles": {
"architect": {}
}
}
}
Opsæt et indgangsstilark
Med en ren mappestruktur på arbejdsområdet er vi klar til at oprette en index.scss
stylesheet, der vil tjene som indgang til vores bibliotek med stilarter.
Samtidig konverterer vi applikationstypografiarket (styles.scss
) til en Sass-partial ved at omdøbe den og flytte den ind i stilbiblioteket. Dette gøres ved at udføre kommandoerne i liste 11.
mv ./apps/tiny-app/src/styles.scss ./libs/shared/styles/src/lib/_global.scss
"@import './lib/global';" > ./libs/shared/styles/src/index.scss
Kun én ting tilbage at gøre. Rediger angular.json
for at erstatte styles
mulighed for tiny-app:build
arkitektmål med posten, der ses i strukturen af Listing 12A.
{
"//": "angular.json",
"projects": {
"tiny-app": {
"architect": {
"build": {
"options": {
"styles": [
"libs/shared/styles/src/index.scss"
]
}
}
}
}
}
}
Bemærk, at hvis vi bruger Karma og skriver komponenttest, der er afhængige af globale stilarter, bliver vi nødt til at tilføje en lignende mulighed til test
arkitektmål for vores UI-arbejdsområdebiblioteker som vist i eksemplet i Listing 12B.
{
"//": "angular.json",
"projects": {
"ui-buttons": {
"architect": {
"test": {
"builder": "@angular-devkit/build-angular:karma",
"options": {
"styles": [
"libs/shared/styles/src/index.scss"
]
}
}
}
}
}
}
Hvis et brugergrænsefladebibliotek deles mellem flere apps og har tests, der er afhængige af deres individuelle globale stilarter, er vi nødt til at oprette flere test
konfigurationer for det pågældende projekt som vist i liste 12C.
{
"//": "angular.json",
"projects": {
"ui-buttons": {
"architect": {
"test": {
"builder": "@angular-devkit/build-angular:karma",
"configuration": {
"booking": {
"styles": [
"libs/booking/shared/styles/src/index.scss"
]
},
"check-in": {
"styles": [
"libs/check-in/shared/styles/src/index.scss"
]
}
}
}
}
}
}
}
Prøv det lokalt
Angular CLI linker nu index.scss
i index.html
, både lokalt på udviklingsserveren og i vores implementerede miljøer, hvor typografiarket er en del af applikationspakken.
Sørg for at prøve det. Tilføj globale typografier, og bekræft, at de er anvendt.
nx build --prod
npx http-server dist/apps/tiny-app -o
Kør nx serve --open
at teste globale stilarter lokalt eller køre kommandoerne i Listing 6 for at betjene en produktionspakke på en lokal statisk webserver.
Udpak et miljøarbejdsområdebibliotek
Før vi bootstrapper vores Angular-applikation i main.ts
, kalder vi betinget enableProdMode
baseret på om den boolske production
egenskaben for environment
objekt er indstillet eller ryddet.
Kører enableProdMode
deaktiveret yderligere registreringscyklusser for ændring af driftstid i produktionstilstand. I udviklingstilstand er denne ekstra cyklus det, der udløser ExpressionChangedAfterItHasBeenCheckedError
advarsel.
Yderligere runtime-påstande fremsættes i hele kernedelene af selve Angular i udviklingstilstand.
Generer et arbejdsområdebibliotek
Selvom det arbejdsområdebibliotek, vi vil udpakke, bliver lille og meget specialiseret, indeholder det TypeScript, så lint
og test
arkitektmål er stadig nyttige.
nx generate library environments --directory=shared --tags="scope:shared,type:environments" --style=scss
npx rimraf ./libs/shared/environments/src/lib/*.*
Liste 13 viser, at vi først genererer miljøbiblioteket. Derefter fjerner vi filerne genereret i src/lib
undermappe til biblioteket.
Flyt miljøfilerne og konfigurer applikationsafhængigheder
Med en tom lib
mappe i vores miljøbibliotek, lad os flytte miljøfilerne fra applikationsprojektet, eksponere dem gennem bibliotekets indgangspunkt og til sidst slette environments
mappe for ansøgningsprojektet. Det hele gøres ved at udføre kommandoerne i liste 14.
mv ./apps/tiny-app/src/environments/*.* ./libs/shared/environments/src/lib
"export * from './lib/environment';" > ./libs/shared/environments/src/index.ts
npx rimraf ./apps/tiny-app/src/environments
For at konfigurere Angular-applikationsprojektet til at bruge en miljøfil i arbejdsområdebiblioteket baseret på build-konfigurationen, navigerer vi til tiny-app:build
arkitektmål i angular.json
og erstat fileReplacements
mulighed for production
konfiguration med posten i liste 15.
{
"//": "angular.json",
"projects": {
"tiny-app": {
"architect": {
"build": {
"configurations": {
"production": {
"fileReplacements": [
{
"replace": "libs/shared/environments/src/lib/environment.ts",
"with": "libs/shared/environments/src/lib/environment.prod.ts"
}
]
}
}
}
}
}
}
}
Kun én ting tilbage at gøre. Vi skal opdatere importerklæringen i main.ts
at bruge miljøets arbejdsområdebibliotek som vist i oversigt 16.
// main.ts
import { enableProdMode } from '@angular/core';
import { environment } from '@workspace/shared/environments';
if (environment.production) {
enableProdMode();
}
Prøv det lokalt
Angular CLI erstatter nu environment.ts
med environment.prod.ts
i produktionspakken, selvom vores applikationsprojekt kun har en transitiv afhængighed af environment.ts
.
Sørg for at prøve det. Tjek din browserkonsol, når du kører nx serve --open
. Meddelelsen Angular is running in the development mode. Call enableProdMode() to enable the production mode.
skal udskrives.
nx build --prod
npx http-server dist/apps/tiny-app -o
Når du kører en produktionspakke lokalt med kommandoerne i liste 6, bør der ikke udlæses nogen meddelelse i din browsers konsol.
Tilføj kompileringstidskonfiguration til et bibliotek
Vi kan bruge miljøbiblioteket til at konfigurere vores applikations afhængigheder, da det tillader vores miljøkonfiguration at blive brugt i kompileringstidskonfigurationsmetoder.
Normalt vil vi tilføje en miljøudbyder, som tjenester, deklarables og Angular-moduler kan injicere, men det er ikke muligt i metoder, der returnerer ModuleWithProviders<T>
, for eksempel statisk forRoot
metoder på vinkelmoduler.
Det samme gælder for import af Angular-moduler. Hvis vi ønsker at indlæse visse Angular-moduler i udviklingstilstand, men ikke i produktionstilstand, kunne vi ikke afhænge af en givet miljøværdi. Vi har brug for statisk adgang til en værdi, da den evalueres på kompileringstidspunktet.
Det ville være en frygtelig idé at have et arbejdsområdebibliotek med afhængighed af et applikationsprojekt. Dette ville gå imod retningen af afhængigheder i en velstruktureret arkitektur og kunne føre til cykliske afhængigheder.
Tilføj og konfigurer NgRx Store
Som et use case tilføjer vi NgRx Store og dets udviklingsværktøjer ved at bruge deres ng add
skemaer som set i liste 17.
nx add @ngrx/store --minimal false
nx add @ngrx/store-devtools
Vi flytter NgRx Store-konfigurationerne fra AppModule
til CoreModule
da dette er den foretrukne måde at konfigurere rodinjektoren på i traditionelle Angular-applikationsprojekter. CoreModule
er importeret af AppModule
og kan ses på liste 18.
// core.module.ts
import { NgModule } from '@angular/core';
import { StoreModule } from '@ngrx/store';
import { StoreDevtoolsModule } from '@ngrx/store-devtools';
import { environment } from '@workspace/shared/environments';
import { metaReducers, reducers } from './reducers';
@NgModule({
imports: [
StoreModule.forRoot(reducers, {
metaReducers,
}),
StoreDevtoolsModule.instrument({
logOnly: environment.production,
maxAge: 25,
}),
],
})
export class CoreModule {}
I traditionelle Angular-arbejdsområder ville dette være fint, men vi ønsker at opretholde et lille applikationsprojekt ved at minimere mængden af logik, det indeholder.
Udpak et delt dataadgangsbibliotek
Vi ønsker at beholde NgRx-specifik konfiguration af rodinjektoren i et arbejdsområdebibliotek. Nx foreskriver en dataadgangsarbejdsområdebibliotekstype, så lad os generere en og udtrække konfigurationslogikken til den.
nx generate library data-access --directory=shared --tags="scope:shared,type:data-access" --style=scss
mv ./apps/tiny-app/src/app/reducers ./libs/shared/data-access/src/lib
Udfør kommandoerne i liste 19 for at generere et delt dataadgangsbibliotek og flyt undermappen src/app/reducers
genereret ved tilføjelse af NgRx Store.
Naviger til libs/shared/data-access/src/lib/shared-data-access.module.ts
og rediger den, så den indeholder filindholdet i liste 20.
// shared-data-access.module.ts
import { ModuleWithProviders, NgModule } from '@angular/core';
import { StoreModule } from '@ngrx/store';
import { StoreDevtoolsModule } from '@ngrx/store-devtools';
import { environment } from '@workspace/shared/environments';
import { metaReducers, reducers } from './reducers';
@NgModule({
imports: [
StoreModule.forRoot(reducers, {
metaReducers,
}),
StoreDevtoolsModule.instrument({
logOnly: environment.production,
maxAge: 25,
}),
],
})
export class SharedDataAccessRootModule {}
@NgModule({})
export class SharedDataAccessModule {
static forRoot(): ModuleWithProviders<SharedDataAccessRootModule> {
return {
ngModule: SharedDataAccessRootModule,
};
}
}
Vi følger forRoot
mønster for at angive, at de afhængigheder, der er angivet ved import af dette Angular-modul, er til rodinjektoren. Dette gøres ved at oprette en statisk metode, der returnerer en ModuleWithProviders<T>
objekt.
SharedDataAccessRootModule
som modulet med udbyderobjektet henviser til indeholder den konfiguration, som var i CoreModule
før vi oprettede dette bibliotek.
Til sidst skal du navigere til apps/tiny-app/src/app/core.module.ts
og rediger dens filindhold til det i liste 21.
// core.module.ts
import { NgModule } from '@angular/core';
import { SharedDataAccessModule } from '@workspace/shared/data-access';
@NgModule({
imports: [
SharedDataAccessModule.forRoot(),
],
})
export class CoreModule {}
Efter omstrukturering ender vi med grafen for arbejdsområdeafhængighed illustreret i figur 2.
Uden at udpakke et delt miljøbibliotek ville vi ikke have været i stand til at importere en miljøfil i vores delte dataadgangsbibliotek. Først og fremmest tiny-app
har ikke en scoped stimapping. For det andet må et biblioteksprojekt aldrig afhænge af et ansøgningsprojekt.
Tilføj en meta-reducer kun i udviklingstilstand
Nu kan vi bruge miljøobjektet til at konfigurere injektorer. Den genererede NgRx Store-konfigurationskode gør dette et andet sted, nemlig i reduceringsfilen som vist i oversigt 22, hvor meta-reducere er defineret.
// reducers/index.ts
import { ActionReducerMap, MetaReducer } from '@ngrx/store';
import { environment } from '@workspace/shared/environments';
export interface State {}
export const reducers: ActionReducerMap<State> = {};
export const metaReducers: MetaReducer<State>[] =
!environment.production ? [] : [];
Lad os bruge en opskrift fra NgRx-dokumentationen til at tilføje en meta-reducer til kun udviklingsfejl.
// reducers/debug.ts
import { ActionReducer } from '@ngrx/store';
export function debug(reducer: ActionReducer<any>): ActionReducer<any> {
return (state, action) => {
console.log('state', state);
console.log('action', action);
return reducer(state, action);
};
}
Fejlfindingsmeta-reduceren i liste 23 logger NgRx Store-tilstanden og den afsendte handling, hver gang handlinger er ved at blive reduceret.
// reducers/index.ts
import { ActionReducerMap, MetaReducer } from '@ngrx/store';
import { environment } from '@workspace/shared/environments';
import { debug } from './debug';
export interface State {}
export const reducers: ActionReducerMap<State> = {};
export const metaReducers: MetaReducer<State>[] =
!environment.production ? [debug] : [];
Liste 24 viser, hvordan man tilføjer debug-meta-reduceren kun i udviklingstilstand. Bemærk, at vi importerer miljøobjektet fra miljøbiblioteket.
// shared-data-access.module.ts
import { NgModule } from '@angular/core';
import { StoreModule } from '@ngrx/store';
import { metaReducers, reducers } from './reducers';
@NgModule({
imports: [
StoreModule.forRoot(reducers, {
metaReducers,
}),
],
})
export class SharedDataAccessRootModule {}
Den eksporterede metaReducers
array bruges til at konfigurere rodlageret som vist i oversigt 25.
Figur 3 viser fil- og mappestrukturen for vores delte dataadgangsbibliotek, som indeholder rodlagerkonfigurationen og meta-reducere.
Konfigurer Nx-arbejdsområdeafhængigheder
Nx-arbejdsområder har en arbejdsområdekonfiguration, som kan bruges til at opsætte begrænsninger for interne afhængigheder og instruere Nx om afhængigheder, der ikke er synlige i applikations- og biblioteks TypeScript-filer.
{
"//": "nx.json",
"projects": {
"tiny-app": {
"implicitDependencies": [
"shared-assets",
"shared-styles"
]
}
}
}
Liste 25 viser, hvordan vi konfigurerer vores applikationsprojekt til at have implicitte afhængigheder af aktiver og stilbiblioteker. Dette er nødvendigt, da der ikke er nogen TypeScript-importsætninger, der refererer til nogen af disse arbejdsrumsbiblioteker.
Miljøbiblioteket importeres i main.ts
, så det har en eksplicit afhængighed, som Nx er i stand til at opfange på egen hånd.
Konfiguration af disse afhængigheder sørg for, at Nx's affected:*
kommandoer opfanger ændringer foretaget i aktiv- og stilbibliotekerne.
Dette vil udløse behovet for at genopbygge applikationsprojektet, når du kører nx affected:build
. Det vil også udløse applikationsenhedstests og ende-til-ende-tests til at køre med nx affected:test
eller nx affected:e2e
. Endelig vil den vise ændrede og berørte arbejdsområdeprojekter, når du kører nx affected:dep-graph
.
Når vi foretager en ændring til _global.scss
og kør nx affected:dep-graph
, får vi afhængighedsgrafen vist i figur 4. Fremhævede noder (projekter) påvirkes af ændringen.
Et lillebitte Angular-applikationsprojekt
Efter omstrukturering af vores applikationsarbejdsområde er vores afhængighedsgraf en rettet acyklisk graf (almindeligvis forkortet som DAG) med afhængigheder, der peger i den rigtige retning som vist i figur 5.
End-to-end testprojektet tiny-app-e2e
afhænger af applikationsprojektet, hvilket betyder, at det er påvirket af ændringer i applikationsprojektet, og dets tests skal derfor køres igen.
Ansøgningsprojektet tiny-app
afhænger af og påvirkes af ændringer i de delte workpace-biblioteker shared-environments
, shared-assets
og shared-styles
. Når et af disse biblioteker ændres, skal applikationen genopbygges, og dens testpakker skal køres igen. Et eksempel på dette blev illustreret i figur 2, hvor shared-styles
blev ændret.
Intet arbejdsområdebibliotek afhænger af applikationsprojektet. Dette skal altid være tilfældet, ellers gør vi noget forkert.
Vores applikationsprojekt har meget få grunde til at ændre, da det indeholder minimal logik. Der er meget få grunde til nogensinde at røre ved ansøgningsprojektet igen.
I pull-anmodninger er det nemt at se, hvad der bliver ændret eller udvidet ved at se på mappenavnet på arbejdsområdets bibliotek, hvor filerne blev ændret, eller ved at køre nx affected:dep-graph
som vi så i et tidligere kapitel.
Figur 6 viser standardfil- og mappestrukturen for en Nx-genereret Angular-applikation. Konfigurationsfiler som tsconfig.json
og tslint.json
er udeladt af illustrationen, da de forbliver uændrede af de teknikker, der er demonstreret i denne artikel.
I det lille app-projekt, filer i src/app
undermappe er uberørt sammenlignet med standardapplikationsprojektet, bortset fra at vi tilføjede en CoreModule
i core.module.ts
når du opretter det delte dataadgangsbibliotek.
Som illustreret i figur 7 er alle undermapper af src
er blevet flyttet undtagen src/app
.
Det delte aktivers arbejdsområdebibliotek
assets
mappen er blevet flyttet ud af applikationsprojektet og ind i shared-assets
arbejdsområdebibliotek som vist i figur 8.
Vi oprettede de fælles aktiver mapper fonts
, icons
og images
og vi samlede Nx-logoet som vist i src/assets/images
undermappe af aktivbiblioteket.
.gitkeep
filer er tomme pladsholderfiler, der placeres for at beholde mappestrukturen i Git-lageret, selv uden rigtige filer indeni. De kan slettes, når filer placeres i mapperne og sættes under versionskontrol. For eksempel ville det være fint at slette src/assets/images/.gitkeep
, nu hvor vi har tilføjet nx-logo-white.svg
til den samme overordnede mappe.
Faviconet er i src
undermappe til et standardapplikationsprojekt. Vi flyttede også den fil til aktivbiblioteket til dens src
undermappe.
Glob-mønstre i tiny-app:build
arkitektmål for angular.json
sikrer, at filer i aktivarbejdsområdets bibliotek er bundter under vores applikations byggeproces.
Biblioteket har ingen TypeScript-konfigurationsfiler, da det kun indeholder statiske filer.
Det delte stilarbejdsområdebibliotek
Det globale typografiark styles.scss
er blevet flyttet fra applikationsprojektets src
undermappe og ind i shared-styles
arbejdsområdebibliotek som vist i figur 9.
styles.scss
blev omdøbt til _global.scss
for at konvertere den til en Sass-del. Sass-delen er placeret i src/lib
undermappe til vores bibliotek med stilarter. Det importeres af indgangsstilarket index.scss
i src
undermappe.
Biblioteket indeholder ingen TypeScript-konfigurationsfiler, fordi det kun indeholder stylesheets og Sass-partialer.
Det delte miljøs arbejdsområdebibliotek
Miljøfilerne er blevet flyttet fra applikationsprojektets src/environments
undermappe til src/lib
undermappe til vores miljøarbejdsområdebibliotek som vist i figur 10.
Miljøobjektet gen-eksporteres af miljøbibliotekets indgangspunkt, også kendt som dets offentlige API, som er defineret i index.ts
.
Konfigurationsfiler til TypeScript, TSLint og Jest samt arkitektmålene lint
og test
bevares, da arbejdsområdebiblioteket indeholder TypeScript.
Konklusion
Vi har genereret et Nx-arbejdsområde med en enkelt Angular-applikation. Selv før vi tilføjer nogen funktioner, kan vi udtrække arbejdsområdebiblioteker for at overholde Single Responsibility Princippet.
Aktivbiblioteket
Biblioteket med delte aktivers arbejdsområde indeholder statiske filer såsom webskrifttyper, ikoner og billeder. Den indeholder også favicon. Webapp-manifestet vil også blive tilføjet her.
Vi så et eksempel på at tilføje en billedfil til dette bibliotek og henvise til den fra vores applikationsprojekt. Dette fungerer selvfølgelig også fra UI-arbejdsområdebiblioteker og funktionsbiblioteker.
Med statiske filer placeret i et separat arbejdsområdebibliotek mindsker vi risikoen for at ødelægge hele applikationen, når du tilføjer, sletter eller ændrer statiske filer.
Stilbiblioteket
Med et arbejdsområdebibliotek udelukkende til globale stilarter, behøver vi ikke have det dårligt med at forurene applikationsprojektet med snesevis af Sass-partialer eller risikere at bryde applikationsopsætningen ved et uheld.
Biblioteket med delte stilarter kan også afsløre Sass-mixins, funktioner og partialer, der deles mellem komponenttypografier eller UI-arbejdsområdebiblioteker.
Miljøbiblioteket
Udpakning af miljøfilerne til et delt arbejdsområdebibliotek giver os mulighed for betinget at konfigurere injektorer fra arbejdsområdebiblioteker, såsom det delte dataadgangsbibliotek, vi oprettede for at konfigurere NgRx Store i rodinjektoren.
I en rigtig applikation kunne vi tilføje et feature shell-bibliotek, så det ville blive orkestreringsvinkelmodulet importeret af AppModule
eller CoreModule
.
Uden et feature shell-bibliotek er vi nødt til at foretage ændringer i applikationsprojektet for at tilføje yderligere konfiguration af rodinjektoren eller tilføje applikationstilfælde. Dette er risikabelt. Vi er bedre stillet ved at lade ansøgningsprojektet stå uberørt under de fleste omstændigheder for at få ro i sindet.
Delte arbejdsområdebiblioteker
I eksemplerne vist i denne artikel har vi lagt de udpakkede arbejdsrumsbiblioteker i shared
biblioteksgrupperingsmappe og tilføjede scope:shared
tag. For arbejdsområder med kun et enkelt program er dette muligvis ikke nødvendigt.
Men efterhånden som applikationen vokser, vil vi være glade for, at vi brugte grupperingsmapper fra starten af projektet. Applikationsdækkende arbejdsområdebiblioteker er i shared
grupperingsmappe, mens vi f.eks. bruger underdomænegrupperingsmapper til at gruppere vores funktionsbiblioteker og deres relaterede dataadgangs-, domæne- og UI-arbejdsområdebiblioteker.
Alternativt ville vi ende med dusinvis, hvis ikke hundredvis af biblioteksmapper inden for libs
mappe, hver med stadig længere mappenavne.
Hvis det viste sig, at vi ønskede at tilføje yderligere applikationer til arbejdsområdet, ville vi beholde de arbejdsområdebiblioteker, som vi ønskede at dele mellem applikationerne i shared
biblioteksgrupperingsmappe. Dem, som vi kunne eller ikke ønsker at dele mellem applikationerne, kan placeres i en biblioteksgrupperingsmappe opkaldt efter applikationen, for eksempel libs/tiny-app/shared
for applikationsdækkende biblioteker, der er unikke for tiny-app
ansøgningsprojekt.
Ressourcer
Du er velkommen til at klone LayZeeDK/nx-tiny-app-project
på GitHub for at eksperimentere med den fulde løsning.
Se en videogennemgang af denne artikel af Oscar Lagatta.
Lær, hvordan du implementerer et feature shell-bibliotek i "Shell Library patterns with Nx and Monorepo Architectures" af Nacho Vázquez.
Peer reviewers
Tak Nacho Vazquez for at give mig værdifuld feedback på denne artikel og for vores mange interessante diskussioner, der fører os til fælles arkitektonisk indsigt 🙇♂️