Modulariserad projektstruktur med AngularJS

Modulariserad projektstruktur med AngularJS

Modulariserad projektstruktur med AngularJS

En modul är logiskt grupperad funktionalitet. Bygger vi stora projekt i AngularJs finns det mycket att vinna på att ha en modulbaserad arkitektur. Delar vi upp applikationen i olika moduler får vi bättre ordning och reda genom att vi exempelvis kan kapsla in potentiella problem. Moduler ska ha få beroenden mellan varandra och kommunikation mellan moduler ska ske med hjälp av services eller events.

En moduluppdelad applikation blir enklare att testa eftersom vi kan mocka bort många beroenden. Dessutom blir det enklare att skala upp utvecklingsteamet eftersom utvecklare kan jobba ostört i olika moduler parallellt. Modulbaserad arkitektur kopplad med lite disciplin gör att vi kan säga hejdå till merge-konflikter. Jobbar man dessutom med git flow eller feature branches i sin källkodshantering kan man få en enkel och robust utvecklingsprocess.

Exempel på uppdelning

Säg att vi ska bygga ett administrationsverktyg för en e-handel. I detta exempel skulle vi kunna ha nedan funktioner eller moduler. 

  • Administrera utseende och form på siten
  • Varulager och prissättning
  • Kunddatabas
  • Manuell köpregistrering och fakturering
  • Orderdatabas

Flera moduler i ett projekt

För att uppnå störst inkapsling och separering är det bra att utveckla varje modul i ett separat projekt. Detta för med sig extra arbete så en pragmatisk mellanväg är att ha alla moduler i samma projekt, åtminstone tills projektet når en viss storlek. Om projektet blir stort kan man bryta ut modulerna till egna projekt och publicera som egna paket, exempelvis hos npm.

Projektstruktur

Sortera inte ditt projekt efter filtyp utan efter funktion eller modul. I andra fall är det vanligt att sortera efter typ, ex C# MVC, men i AngularJS ska en modul vara grupperad tillsammans i projektet. Du bryter mot inkapslingen om du sorterar projektet efter filtyp samt att det blir svårare att hitta.

Projektstruktur - exempel

Varje modul definierar sin egen navigering

Helst ska en modul inte ha några kunskaper om andra moduler, t.ex. vilka controllers eller vyer den innehåller. Av denna anledning faller det naturligt att varje modul ska definiera sin egen navigering. Med fördel kan varje modul ha en definitionsfil och en konfigurationsfil, lägg navigeringen i konfigurationsfilen.

För att undvika konflikter mellan moduler kan varje modul ha ett eget prefix i URL-adressen.

Varje modul ska ha sin egen routing

Kommunikation mellan moduler

Ofta behöver modulerna i stora projekt dela data. Kommunikation mellan modulerna sköts genom antingen events eller gemensamma services. Alla moduler kommer att dela $rootScope varför det är enkelt att använda events. Gemensamma services kan brytas ut och läggas i en egen modul, typ admin.common.

Gör aldrig data eller funktioner globala för att kommunicera med en annan modul.

Bryt inte inkapslingen med globala referenser

Navigering mellan moduler

Att gå från en vy i en modul till en vy i en annan modul kräver i regel att man vet vilka vyer eller states den andra modulen har. Länken måste vara explicit. Detta bryter mot inkapslingen.

<a ui-sref="inventory.list">List Inventory</a>

Här kan man tänka sig olika lösningar med t.ex. "service locator pattern" för att generera länken när applikationen kör. Länken kan exempelvis genereras olika beroende på vilka moduler som är laddade osv. Detta medför dock komplexitet och har i min erfarenhet inte tillfört värde i något projekt. Mitt råd: Var pragmatisk och börja med explicita länkar som i exemplet ovan.

Exempelkod

I bilagan till denna artikel går det att ladda ned ett projekt med exempelkod.

- Alexander Toresson

Läs nästa artikel i serien

Modulariserad projektstruktur med AngularJS

LADDA HEM BILAGA

Exempel - Modularisering.zip