Planera byggberoenden för din pipeline
- 10 minuter
I den här lektionen lär du dig mer om paketeringskod för att göra det enklare att dela. Du upptäcker varför du bör skapa paket, vilka typer av paket du kan skapa, var du kan vara värd för paketen och hur du kan komma åt dem när de finns. Du lär dig också om paketversionshantering.
Kodbaser blir alltid större och mer komplexa. Det är ovanligt att ett team skriver all kod som appen använder. I stället innehåller teamet befintlig kod som skrivits av andra utvecklare. Det kan finnas många av dessa paket, eller beroenden, i en app. Det är viktigt att aktivt hantera beroenden för att kunna underhålla dem korrekt och se till att de uppfyller säkerhetskraven.
Checka in och se hur det går för teamet. Andy ringde teamet tillsammans för att prata om en potentiell ändring av deras kod som skulle hjälpa ett annat team.
Teammöte
Andy: Hej alla. Jag chattade med teamet som arbetar med backend-systemet för Space Game. De kan använda de modeller som vi använder för webbplatsen i en serverdelsapp som de planerar att skriva.
Amita: Vad menar du med modeller?
Andy: Som ni vet är Space Game-webbplatsen ett ASP.NET Core-program. Den använder mönstret Model-View-Controller – eller MVC – för att separera data från hur dessa data visas i användargränssnittet. Jag tänkte att vi kunde skapa ett paket som innehåller våra modellklasser så att alla appar kan använda dem.
Amita: Vad exakt är målet?
Andy: Båda våra team delar samma databas. Spelet skickar de högsta poängen till databasen och vi läser dessa poäng så att vi kan visa dem på resultattavlan.
Amita: Det är vettigt. Hur ska vi skapa det här paketet?
Det var därför jag ville prata med dig. Vi har några alternativ och jag behöver fler idéer.
Tim: Jag skulle gärna hjälpa till, men först har jag några frågor. Det här är nytt för mig och jag vill förstå hur allt fungerar.
Vad är ett paket?
Ett paket innehåller återanvändbar kod som andra utvecklare kan använda i sina egna projekt, även om de inte skrev det.
För kompilerade språk innehåller ett paket vanligtvis den kompilerade binära koden, till exempel .dll filer i .NET- eller .class-filer i Java. För språk som tolkas i stället för att kompileras, till exempel JavaScript eller Python kan ett paket innehålla källkod.
I båda fallen komprimeras paketen normalt till ZIP eller liknande format. Paketsystem definierar ofta ett unikt filnamnstillägg, till exempel .nupkg eller .jar, för att göra paketets användning tydlig. Komprimering kan minska nedladdningstiden och även skapa en enda fil för att förenkla hanteringen.
Paket innehåller också ofta en eller flera filer som tillhandahåller metadata eller information om paketet. Dessa metadata kan beskriva vad paketet gör, ange dess licensvillkor, författarens kontaktuppgifter och paketversionen.
Varför ska jag skapa ett paket?
Det finns fördelar med att skapa ett paket i stället för att duplicera koden.
En anledning till att skapa ett paket i stället för att duplicera kod är för att förhindra drift. När koden dupliceras kan varje kopia snabbt avvika för att uppfylla kraven för en viss app. Det blir svårt att flytta ändringar från en kopia till andra. Med andra ord förlorar du möjligheten att förbättra koden på ett sätt som alla kan dra nytta av.
Paket innebär också att relaterade funktioner samlas i en återanvändbar komponent. Beroende på programmeringsspråket kan ett paket ge appar åtkomst till vissa typer och funktioner, samtidigt som åtkomsten till deras implementeringsinformation begränsas.
En annan anledning till att skapa ett paket är att tillhandahålla ett konsekvent sätt att skapa och testa funktionerna i paketet. När koden dupliceras kan varje app skapa och testa koden på olika sätt. En uppsättning tester kan innehålla kontroller som en annan uppsättning kan ha nytta av.
En kompromiss är att du har en annan kodbas att testa och underhålla med ett paket. Du måste också vara försiktig när du lägger till funktioner. Generellt sett bör ett paket innehålla funktioner som gynnar många typer av appar. Till exempel är Json.NET ett populärt NuGet-paket för .NET som gör att du kan arbeta med JSON-filer. Json.NET är öppen källkod, vilket innebär att communityn kan föreslå förbättringar och rapportera problem.
När flera appar kan dra nytta av samma kod uppväger fördelarna vida nackdelarna. Du har bara en kodbas, bara en uppsättning med tester och bara en byggprocess att hantera.
Hur kan jag identifiera beroenden?
Om målet är att omorganisera koden till separata komponenter måste du identifiera de delar av appen som kan tas bort, paketeras för att kunna återanvändas, lagras på en central plats och versionshanteras. Du kanske till och med vill ersätta din egen kod med partnerkomponenter som antingen är öppen källkod eller som du licensierar.
Det finns många sätt att identifiera potentiella beroenden i din kodbas. Dessa metoder omfattar genomsökning av koden efter återanvändningsmönster och analys av lösningens arkitektur. Här följer några sätt att identifiera beroenden:
Duplicerad kod.
Om vissa delar av koden visas på flera platser är det en bra indikation på att du kan återanvända koden. Centralisera dessa dubbletter av kod och packa om dem på rätt sätt.
Hög sammanhållning och låg koppling.
En annan metod är att leta efter kodelement som har hög sammanhållning till varandra och låg koppling till andra delar av koden. I grund och botten innebär hög sammanhållning att delar av en kodbas som är relaterade till varandra hålls kvar på en enda plats. Låg koppling handlar samtidigt om att separera orelaterade delar av kodbasen så mycket som möjligt.
Individuell livscykel.
Leta efter delar av koden som har en liknande livscykel som du kan distribuera och släppa individuellt. Om ett separat team kan underhålla den här koden är det en bra indikation på att du kan paketera den som en komponent utanför lösningen.
Stabila delar.
Vissa delar av din kodbas kan vara stabila och ändras sällan. Kontrollera kodlagringsplatsen för att hitta kod med låg ändringsfrekvens.
Oberoende kod och komponenter.
När kod och komponenter är oberoende och inte är relaterade till andra delar av systemet kan du eventuellt isolera dem i separata beroenden.
Du kan använda olika verktyg för att genomsöka och undersöka din kodbas. Exempel är allt från verktyg som söker efter duplicerad kod och ritar lösningsberoende grafer till verktyg som kan beräkna mått för koppling och sammanhållning.
Vilka typer av paket finns det?
Varje programmeringsspråk eller ramverk har egna sätt att skapa paket. Populära paketsystem innehåller dokumentation om hur processen fungerar.
Du kanske redan är bekant med dessa populära paketsystem:
- NuGet: paket-bibliotek för .NET
- NPM: paket JavaScript-bibliotek
- Maven: paketerar Java-bibliotek
- Docker: paketprogramvara i isolerade enheter som kallas containrar
Var finns paketen?
Du kan vara värd för paket i ditt eget nätverk eller använda en värdtjänst. En värdtjänst kallas ofta för en paketlagringsplats eller ett paketregister. Många av dessa tjänster tillhandahåller gratis värdtjänster för projekt med öppen källkod.
Här är några populära värdtjänster för pakettyperna som vi precis beskrev:
-
NuGet-paket används för .NET-kodartefakter. Dessa artefakter omfattar .NET-sammansättningar och relaterade filer, verktyg och ibland metadata. NuGet definierar hur paket skapas, lagras och används. Ett NuGet-paket är i huvudsak en komprimerad mappstruktur med filer i ZIP-format och har .nupkg-tillägget .
-
Ett NPM-paket används för JavaScript. Ett NPM-paket är en fil eller mapp som innehåller JavaScript-filer och en package.json fil som beskriver paketets metadata. För node.js innehåller paketet vanligtvis en eller flera moduler som kan läsas in när paketet har förbrukats.
-
Maven används för Java-baserade projekt. Varje paket har en Project Object Model-fil som beskriver projektets metadata och är den grundläggande enheten för att definiera ett paket och arbeta med det.
-
Docker-paket kallas avbildningar och innehåller fullständiga, fristående distributioner. Oftast representerar en Docker-avbildning en programvarukomponent som kan hanteras och köras av sig själv, utan några beroenden på andra avbildningar. Docker-avbildningar är skiktade och kan vara beroende av andra avbildningar.
Ett paketflöde refererar till din paketlagringsplatsserver. Den här servern kan finnas på Internet eller bakom brandväggen i nätverket. Du kan till exempel vara värd för dina egna NuGet-feeds med hjälp av värdprodukter som Azure Artifacts och MyGet. Du kan också ha paketen på en filresurs.
När du är värd för paket bakom en brandvägg kan du ta med feeds till dina egna paket. Du kan också cachelagrat paket som du litar på i nätverket när systemen inte kan ansluta till Internet.
Vilka element utgör en bra strategi för beroendehantering?
En bra strategi för beroendehantering är beroende av följande tre element:
Standardisering.
Standardisera hur du deklarerar och löser beroenden hjälper din automatiserade lanseringsprocess att förbli repeterbar och förutsägbar.
Paketeringsformat och källor.
Varje beroende ska paketeras med lämpligt format och lagras på en central plats.
Versionshantering.
Du måste hålla reda på de ändringar som sker över tid i beroenden precis som med din egen kod. Det innebär att beroenden ska vara versionshanterade.
Vem kan komma åt paketen?
Många paketfeeds erbjuder obegränsad åtkomst till paketen. Du kan till exempel ladda ned Json.NET från nuget.org, utan att behöva logga in eller autentisera.
För andra paketfeeds krävs autentisering. Du kan autentisera åtkomst till feeds på flera sätt. Vissa feeds kräver till exempel användarnamn och lösenord. Andra feeds kräver en åtkomsttoken, som vanligtvis är en lång serie tecken som identifierar vem du är och vilka resurser du har åtkomst till. Du kan ange att åtkomsttoken ska upphöra att gälla efter en viss period.
Hur hanteras paketversioner?
Versionsschemat beror på vilket paketsystem du använder.
NuGet-paket använder till exempel semantisk versionshantering.
Semantisk versionshantering är ett populärt versionsschema. Så här ser formatet ut:
Major.Minor.Patch[-Suffix]
Här är vad var och en av dessa parametrar innebär:
- En ny huvudversion introducerar större ändringar. Appar behöver vanligtvis uppdatera hur de använder paketet för att fungera med en ny huvudversion.
- En ny delversion introducerar nya funktioner, men är bakåtkompatibel med tidigare versioner.
- En ny patch introducerar bakåtkompatibla felkorrigeringar, men inte nya funktioner.
- -Suffix-delen är valfri och identifierar paketet som en förhandsversion. Till exempel kan 1.0.0-beta1 identifiera paketet som den första förhandsversionen av betaversionen för 1.0.0-versionen.
Du refererar till ett paket via versionsnumret.
Här är ett exempel på hur du installerar ett paket med hjälp av PowerShell och ett specifikt versionsnummer:
Install-Package Newtonsoft.Json -Version 13.0.1
Vad händer när paketet ändras?
När du refererar till ett paket från din app, låser eller anger du vanligtvis den version av paketet som du vill använda.
Med många ramverk kan du ange tillåtna intervall med paketversioner som ska installeras. Vissa låter dig också ange jokertecken, som vi kallar en flytande version.
I NuGet är till exempel version ”1.0” den första versionen som är lika med eller större än 1.0. ”[1.0]” anges för endast installation av version 1.0, och inte en nyare version.
Här följer några andra exempel:
| Den här notationen: | Väljer: |
|---|---|
| (1.0,) | Den första versionen som är större än 1. |
| [1.0,2.0] | Den första versionen som är större än eller lika med 1.0 och mindre än eller lika med 2.0 |
| (1.0,2.0) | Den första versionen som är större än 1.0 och mindre än 2.0 |
| [1.0,2.0) | Den första versionen som är större än eller lika med 1.0 och mindre än 2.0 |
När varje underhållare släpper en ny paketversion kan du utvärdera vad som har ändrats och testa din app mot den. När du är redo kan du uppdatera paketets versionsnummer i din konfiguration och skicka ändringen i din bygg-pipeline.
Här är ett exempel på hur du kan inkludera Newtonsoft.Json-paketet i C#-programmets projektfil (.csproj). Det här exemplet anger version 13.0.1 av paketet:
<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
</ItemGroup>