Kodberoenden är djävulen.

Dina beroenden bränner dig varje gång.
"Förändring är den enda konstanten ..." - Heraclitus (filosof)

De verktyg, bibliotek och ramverk som vi använder för att bygga våra webbapplikationer idag skiljer sig drastiskt från de som vi använde för några korta år sedan.

På några korta år kommer nu de flesta av dessa tekniker att förändras dramatiskt igen. Ändå gör många av oss dessa till en central, ofördelbar del av våra appar.

Vi importerar, använder och ärver från ramarna för månadens smak som om de alla kommer att vara runt och oförändrade för alltid. Det är de inte. Och det är ett problem.

Efter 20 år med att utveckla, designa och arkivera webbapplikationer har jag uppskattat två viktiga sanningar:

  1. Yttre beroenden utgör ett stort hot mot långsiktig stabilitet och livskraft för alla tillämpningar.
  2. Det blir allt svårare - om inte omöjligt - att bygga någon form av icke-trivial app utan att utnyttja externa beroenden.

Den här artikeln handlar om att förena dessa två sanningar så att våra appar har den största chansen att överleva på lång sikt.

Kaninhålet är verkligen mycket djupt.

Om vi ​​börjar tänka på alla saker som våra webbappar är beroende av är det lätt att tänka på ett dussin eller mer innan vi ens kommer till koden:

  • Kraft
  • Anslutningar
  • brandvägg
  • DNS
  • Serverhårdvara (CPU, Disk, Ram, ...)
  • Kyl
  • Virtualiseringsplattform
  • Behållarplattform
  • Operativ system
  • Webbserverplattform
  • App-serverplattform
  • Webbläsare

Som utvecklare är det bra att vara medveten om dessa saker, men det finns ofta inte mycket vi kan göra åt dem. Så låt oss ignorera dem för nu och prata bara om koden.

I kod finns det tre typer av beroenden:

1. Beroende som vi kontrollerar

Detta är kod skriven och ägs av oss eller vår organisation.

2. Beroende som vi inte kontrollerar

Detta är kod skriven av en tredjepartsleverantör eller programvara med öppen källkod.

3. Beroende när de har tagits bort

Det här är kodberoenden som våra tredjeparts kodberoende är beroende av. (Säg det tre gånger snabbt!)

Vi kommer främst att prata om beroenden vi inte kontrollerar.

Beroende som vi kontrollerar och beroende när de har tagits bort kan fortfarande orsaka huvudvärk, men när det gäller beroende som vi kontrollerar, bör vi kunna direkt ingripa och mildra eventuella problem.

När det gäller beroende när de en gång har tagits bort kan vi vanligtvis lita på att en tredje part tar hand om det för oss, eftersom de också är beroende av dessa.

Varför tredjeparts kodberoende är bra

En stor del av din webbapplikation existerar för att lösa vanliga problem: autentisering, auktorisation, datatillgång, felhantering, navigering, loggning, kryptering, visa en lista med objekt, validera formulärinsputs och så vidare ...

Oavsett vilken teknikstapel du använder, finns det en god chans att vanliga lösningar på dessa problem finns och finns som bibliotek som du enkelt kan skaffa och plug-in till din kodbas. Att skriva något av det här helt från början är i allmänhet slöseri med tid.

Du vill koncentrera dig på kod som antingen löser ett ovanligt problem eller löser ett vanligt problem på ett ovanligt sätt. Det är vad som gör din applikation värdefull: koden som implementerar affärsreglerna som är unika för din app enbart - den "hemliga såsen."

Googles sök- och sidrankingsalgoritm, Facebooks tidslinjefiltrering, Netflix's avsnitt "rekommenderas för dig" och datakomprimeringsalgoritmer - koden bakom alla dessa funktioner är "hemlig sås."

Tredje parts kod - i form av bibliotek - låter dig snabbt implementera de kommoditerade funktionerna i din app, så att du kan hålla fokus på din "hemliga sås."

Varför tredje parts kodberoende är dåliga

Ta en titt på alla icke-triviala webbappar som har byggts under de senaste åren och du blir helt förvånad över mängden kod som faktiskt kommer från ett tredjepartsbibliotek. Vad händer om ett eller flera av dessa tredjepartsbibliotek förändras drastiskt, försvinner eller går sönder?

Om det är open source, kanske du kan fixa det själv. Men hur väl förstår du all koden i det biblioteket du inte äger? En stor anledning till att du använder ett bibliotek i första hand är att få fördelarna med koden utan att behöva oroa dig för alla detaljer. Men nu är du fast. Du har helt bundit din förmögenhet till dessa beroenden som du inte äger och inte kontrollerar.

Oroa dig inte, i slutet av denna artikel hittar du ett nytt hopp.

Du kanske tror att jag överdriver eller talar från en rent akademisk synvinkel. Låt mig försäkra er - jag har dussintals exempel på klienter som helt snookerade sig själva genom att bädda in tredjepartskod för hårt i sin app. Här är bara ett senaste exempel ...

En tidigare kund av mig byggde sin app med en Backend-as-a-Service-leverantör som ägs av Facebook, kallad Parse. De använde ett JavaScript-klientbibliotek som tillhandahålls av Parse för att konsumera Parse-tjänsten. Under processen kopplade de tätt all sin kod - inklusive "hemlig sås" -kod - till detta bibliotek.

Tre månader efter min klients första produktlansering - precis som de började få bra dragkraft med riktiga, betalande kunder - meddelade Parse att den stängde av.

Istället för att fokusera på att iterera på sin produkt och växa sin kundbas, var min klient tvungen att ta reda på hur man antingen migrerar till en självhostad, öppen källkodsversion av Parse, eller ersätter Parse helt.

Störningen som detta orsakade för en ung, ny applikation var så enorm att min klient så småningom skrotade appen helt.

Att balansera det goda och det dåliga

För flera år sedan var min go-to-lösning för att övervinna riskerna och samtidigt behålla fördelarna med tredjepartsbibliotek att packa in dem med Adapter-mönstret.

I grund och botten packar du in tredjepartskoden i en adapterklass eller modul som du har skrivit. Detta fungerar sedan för att exponera funktionerna i tredjepartsbibliotek på ett sätt som du kontrollerar.

Om du använder detta mönster, om ett tredjepartsbibliotek eller ramverk ändras eller försvinner, måste du bara fixa lite adapterkod. Resten av din app förblir intakt.

Adaptermönsterdiagram från Dofactory.com

Detta låter bra på papper. När du har fristående beroende som bara ger några få funktioner kommer detta att göra susen. Men saker och ting kan bli ful snabbt.

Kan du tänka dig att du måste packa in hela React-biblioteket (inklusive JSX) innan du använder något av det? Vad sägs om att lägga in jQuery eller Angular eller vårramen i Java? Detta blir snabbt en mardröm.

Idag rekommenderar jag en mer nyanserad strategi ...

För varje beroende du vill lägga till i din kodbas, utvärdera risknivån som den kommer att införa genom att multiplicera två faktorer:

  1. Sannolikheten för att beroendet kommer att förändras på ett materiellt sätt.
  2. Mängden skada som en väsentlig förändring av beroendet skulle göra för din ansökan.

Ett tredje parts bibliotek eller ramverk är mindre benägna att förändras när några eller alla följande saker är sanna:

  • Det har funnits i flera år och har haft flera stora utgåvor.
  • Det används ofta av många kommersiella applikationer.
  • Den har aktivt stöd från en stor organisation - helst ett hushållsnamnföretag eller institution.

Ett bibliotek eller ramverk från tredje part kommer att göra mindre skada på din ansökan när några eller alla följande saker är sanna:

  • Det används bara av en liten del av din applikation, snarare än att användas i hela.
  • Koden som beror på den är inte en del av den "hemliga sås" som jag talade om tidigare.
  • Att ta bort det kräver minimala ändringar av din kodbas.
  • Hela applikationen är mycket liten och kan skrivas om snabbt. (Var försiktig med den här - det är sällan sant mycket länge.)

Ju mer riskfyllda saker är, desto mer troligt bör du vara att packa in det eller undvika det helt.

När det gäller koden som verkligen är central för värdepropositionen för din ansökan - din "hemliga sås" - måste du vara extremt skyddande för den. Gör den koden så oberoende som möjligt. Om du absolut behöver använda ett beroende kan du överväga att injicera det snarare än att direkt hänvisa till det. Även då, var försiktig.

Ibland betyder det att man säger ”nej” till ett tredjepartsbibliotek som du tycker är riktigt coolt, eller som du verkligen vill använda av en eller annan anledning. Var stark. Lita på mig, det kommer att betala sig. Fråga bara alla de människor som investerade mycket i den allra första utgåvan av Angular, eller min tidigare klient som använde Parse överallt. Det är inte kul. Tro mig.

På tal om kul, ta en titt på det här ...

Beroendegraf för TinyTag explorer

Bilden ovan är beroendegraf för ett program som heter TinyTag Explorer.

Att skapa ett beroende-diagram för dina befintliga appar är ett bra sätt att förstå risknivån som dina beroenden introducerar. Jag har satt upp en lista med gratisverktyg för att generera diagram som liknar ovan på olika språk inklusive JavaScript, C #, Java, PHP och Python. Du kan få det här.

Hjälp mig att hjälpa andra

Jag vill hjälpa så många utvecklare som möjligt genom att dela min kunskap och erfarenhet med dem. Snälla hjälp mig genom att klicka på knappen ❤ rekommendera (grönt hjärta) nedan.

Slutligen, glöm inte att ta din lista över generatörer för gratis beroende graf här.