Disclaimer: Jag är en utvecklare, inte en jurist; denna information tros vara korrekt, men är inte juridisk rådgivning; om du tror att något är felaktigt, skriv en kommentar så fixar vi det tillsammans🔧

Förut brydde jag mig inte om licensen för npm-paket. Jag kunde kontrollera licensen för det omedelbara beroendet men aldrig kontrollera beroenden från tredje part (övergångsberoende).

🚓 Och sedan träffade jag killar från juridiska avdelningen 🚓

Jag tror nu att utvecklare bör ha en grundläggande förståelse för programvarulicenser för att kunna ha en konstruktiv dialog med juridiska team i sina företag. Det här inlägget samlar en allmän kunskap om licenser för öppen källkod och hur det gäller för npm-beroenden och Full-Stack JavaScript-utveckling i allmänhet.

Låt oss ta reda på när du bör börja oroa dig för licenser.

När utlöses licenskrav?

Om du gör länkningar med bibliotek med öppen källkod och sedan distribuerar den resulterande programvaran måste din programvara uppfylla kraven för länkade bibliotek.

Låt oss titta närmare på länkningar och distribution som tillämpas på JavaScript-appar.

Länkning

Användning av bibliotek från tredje part innebär normalt att de länkas:

  • Om du buntar (t.ex. med webpack) din kod med paket med öppen källkod räknas det som statisk länkning
  • Om du använder paket med öppen källkod i din Node.JS-app (t.ex. via require) eller ansluter det till en webbsida via en skripttagg är det dynamisk länkning

Notera: När du bygger ett paket eller kör en Node.JS-app utför du samma typ av länkning med både omedelbara (som listas i din package.json) och transitiva (som listas i tredje partens package.json) beroenden. Licenser för omedelbara och transitiva beroenden har samma effekt på din programvara.

Detta var inte intuitivt för mig tidigare 🤔

Distribution

Att bara använda bibliotek med öppen källkod utlöser inte nödvändigtvis licenskrav. Normalt utlöses licenskrav när du distribuerar programvara:

  • Överföring av programvara mellan anställda på samma företag är inte en distribution
  • När användare interagerar med din Node.JS-appen över ett nätverk är det inte en distribution för de flesta licenser för öppen källkod, men det är en distribution för nätverksskyddande licenser som AGPL
  • Att lägga JavaScript-filer på en offentlig webbserver är en distribution

Vilken licens är okej

De flesta licenser för öppen källkod faller generellt sett in i en av dessa typer:

  • Public Domain och tillåtande licenser som MIT som tillåter dig att göra vad som helst utom att stämma författaren
  • Copyleft- eller skyddslicenser som GPL förhindrar länkning (se ovan) med proprietär mjukvara; ett specialfall är nätverksskyddande licenser som Affero GPLv3 som utlöses av interaktion över nätverk;
  • Mellan dessa två finns svagt skyddande licenser som MPL som har mindre begränsningar för dynamisk länkning (tills biblioteket finns i en egen fil)

Låt oss kolla vanliga scenarier för en JavaScript-utvecklare:

Du gör en webbapplikation

Det är troligt att du samlar alla dina filer, inklusive bibliotek, i en JS-fil och lägger den på en webbserver. Du utför statisk länkning och distribution. Det går bra att använda paket med tillåtande licenser i ett paket.

Om du behöver använda ett paket med svagt skyddande licens som MPL har du följande alternativ:

  1. Lad biblioteket från en separat fil (t.ex. via script tag)
  2. Använd kompatibel öppen källkodslicens på ditt paket (men kontrollera kommentaren nedan och prata med ditt juridiska team innan)

Om ditt paket inte har ✨värderlig immateriell egendom✨ bör det andra alternativet vara bra. Jag tror inte att konkurrenterna kommer att dra nytta av din fördunklade kod. Men om paketet innehåller värdefull immateriell egendom, så ger tillämpningen av öppen källkodslicens fri användning av den.

Du gör enNode.JS-app

I det här fallet ansluter du normalt bibliotek via ett require()-anrop. Det är en dynamisk länkning. Det går bra att använda Permissive och till och med Weakly Protective licenser. Se bara till att paketen stannar i sina egna filer med respektive licenser.

Om du endast tillhandahåller SaaS och inte distribuerar på något annat sätt kan du använda även paket med en Protective-licens. För många Protective-licenser är nätverksinteraktion inte en distribution. Undantaget är Network Protective licenser som Affero GPLv3

Du gör ett NPM-paket med öppen källkod

Normalt sett ansluter du beroenden från tredje part via en package.json. Såvitt jag vet kan inte listning av beroenden i package.json betraktas som länkning. Länkning utförs av en apputvecklare som kommer att använda ditt paket i ett bygg- eller körskede.

Om du inte vill förvirra paketanvändare ska du se till att alla beroenden (både omedelbara och transitiva) har kompatibla licenser med din paketlicens.

Typiskt sett bör beroendelicenser vara mer tillåtande eller ha samma nivå av tillåtande som din paketlicens.

Till exempel, om ditt paket har licensen Apache 2.0 kan du använda beroenden med MIT- och BSD-licens. Men du bör inte använda beroenden med licenserna MPL1.1 eller LGPLv3, eftersom de har starkare copyleft.

En pil från ruta A till ruta B innebär att du kan kombinera programvara med dessa licenser; det kombinerade resultatet har i själva verket licensen för B, möjligen med tillägg från A; bilden är hämtad från David A. Wheeler

När du behöver lägga in paket eller källkod från tredje part i ett NPM-paket får du inte glömma att ange tredje parts licenser och upphovsrätt. De flesta licenser för öppen källkod kräver att författaren anges.

Det är också bra att ange ett giltigt SPDX-uttryck i din package.json-licens. Jag tror att det här fältet måste vara obligatoriskt för publicering på npm.org.

Hur du räknar ut det

Många team börjar tänka på licenser när programvaran är redo att levereras. Jag har använt verktyget ScanCode för detta. Det går verkligen till varje mapp i ditt projekt och försöker upptäcka varje licens eller upphovsrätt.

Screenshot från https://github.com/nexB/scancode-toolkit

Du måste antagligen använda det här eller liknande verktyg innan du distribuerar din app. Se till att du kontrollerar tillräckligt och inte för mycket:

  • installera alla dina produktionsberoenden innan du kör verktyget
  • säkerställ att devDependencies inte kontrolleras av verktyget; normalt sett distribuerar du inte med dina utvecklingsberoenden;
  • Anm.: Om du, som jag, kollar in paketlicenser efter att du integrerat paketet i din app, kan du hamna i en svår situation.

    Körning av ScanCode strax före deadline; bild från https://giphy.com

    Hur man listar ut det innan det är för sent

    Jag undrade när det är bäst att lära sig mer om licenser för paketberoende. För mig är det normala flödet för att upptäcka paket:

    🔍 Google 👉 npm.org 👉 GitHub 👉 $ npm install

    Tyvärr tar npm.org inte riktigt upp transitiva beroenden. Det finns webbverktyg som http://npm.anvaka.com/; men det passar inte in i mitt paketupptäcktsflöde och jag glömmer hela tiden att använda det. Jag tänkte att det bästa tillfället att lära sig om paketberoenden är när du skriver $ npm install <pkg>

    Det var min tanke när jag byggde ett CLI-verktyg som heter npm-consider som analyserar paketet med alla transitiva beroenden innan det installeras eller ens hämtas.

    https://github.com/delfrrr/npm-consider

    För att spara ett kommando åt dig, omsluter det $ npm install och har samma argument. Om du är nöjd med beroenden väljer du bara Install så körs npm install som vanligt. Om du är orolig väljer du Detaljer och ser hela beroendeträdet:

    Visar detaljer vid installation av komponent i det populära geospatiala biblioteket Turf.js; observera att paketet i sig har en tillåtande licens, men att ett av de transitiva beroendena har AGPL-licens; du kan egentligen inte använda det för proprietär programvara;

    Jag anser att en sådan funktionalitet måste vara en del av npm CLI. Om du håller med, vänligen ⭐️ projektet på GitHub så kommer jag att driva idén framåt.

    Källor

    Jag listar mina källor ifall du vill dubbelkolla mina slutsatser:

    • Förståelse för npm:s beroendemodell
    • Open source licensing: Vad varje tekniker bör veta | Opensource.com
    • Variösa licenser och kommentarer om dem
    • Den fria licenserna (Free-Libre / Open Source Software (FLOSS) License Slide
    • License Center | ifrOSS
    • Varierade licenser för fri och öppen källkod – Wikipedia
    • Bibliotek (databehandling) – Wikipedia

    Om artikeln var till hjälp, snälla 👏 så kanske jag skriver en till 😀