Disclaimer: Jeg er udvikler, ikke advokat; disse oplysninger menes at være korrekte, men er ikke juridisk rådgivning; hvis du mener, at noget er forkert, så skriv en kommentar, så retter vi det sammen🔧

Forinden var jeg ligeglad med licensen for npm-pakker. Jeg kunne tjekke licensen for umiddelbar afhængighed, men aldrig tjekke 3. parts (overgangs)afhængigheder.

🚓 Og så mødte jeg fyre fra juridisk afdeling 🚓

Jeg mener nu, at udviklere bør have en grundlæggende forståelse for softwarelicensering for at kunne have en konstruktiv dialog med juridiske teams i deres virksomheder. Dette indlæg samler en generel viden om Open-Source-licenser, og hvordan det gælder for npm-afhængigheder og Full-Stack JavaScript-udvikling generelt.

Lad os finde ud af, hvornår du bør begynde at bekymre dig om licenser.

Hvornår udløses licenskrav?

Hvis du udfører linking med open source-biblioteker og derefter distribuerer den resulterende software, skal din software være i overensstemmelse med kravene til de linkede biblioteker.

Lad os se nærmere på linking og distribution anvendt på JavaScript-apps.

Linking

Anvendelse af biblioteker fra tredjepart betyder normalt linking af dem:

  • Hvis du bundler (dvs. med webpack) din kode med open source-pakker, tæller det som statisk linking
  • Hvis du bruger open source-pakker i din Node.JS-app (dvs. via require) eller forbinder den til en webside via scripttag, er det dynamisk linking

Bemærk: Når du opbygger en bundle eller kører en Node.JS-app, udfører du den samme type linking med både umiddelbare (anført i din package.json) og transitive (anført i tredjepartspakke.json) afhængigheder. Umiddelbare og transitive afhængigheder licenser har den samme effekt på din software.

Dette var ikke intuitivt for mig før 🤔

Distribution

Det er ikke nødvendigt at bruge open source-biblioteker for at udløse licenskrav. Normalt udløses licenskrav, når du distribuerer software:

  • Overførsel af software mellem medarbejdere i samme virksomhed er ikke en distribution
  • Når brugere interagerer med din Node.JS-app via netværk, er det ikke en distribution for de fleste open source-licenser; men det er en distribution for Network Protective-licenser som AGPL
  • At lægge JavaScript-filer på en offentlig webserver er en distribution

Hvilken licens er ok

De fleste open source-licenser falder generelt ind under en af disse typer:

  • Public Domain- og Permissive-licenser som MIT, der tillader dig at gøre hvad som helst, undtagen at sagsøge forfatteren
  • Copyleft- eller beskyttelseslicenser som GPL forhindrer sammenkædning (se ovenfor) med proprietær software; et særtilfælde er Network Protective-licenser som Affero GPLv3, der udløses ved interaktion over netværk;
  • Mellem de to ovennævnte er svagt beskyttende licenser som MPL, der har færre begrænsninger for dynamisk sammenkobling (indtil biblioteket er i sin egen fil)

Lad os undersøge almindelige scenarier for en JavaScript-udvikler:

Du laver en webapp

Sandsynligvis samler du alle dine filer, herunder biblioteker, i én JS-fil og lægger den på en webserver. Du udfører statisk linking og distribution. Det er fint at bruge pakker med Permissive licenser i et bundle.

Hvis du skal bruge en pakke med svagt beskyttende licens som MPL, har du muligheder:

  1. Lad bibliotek fra separat fil (dvs. via script tag)
  2. Anvend kompatibel open source-licens på din bundle (men tjek kommentaren nedenfor og tal med dit juridiske team før)

Hvis din bundle ikke har ✨vurderlig intellektuel ejendom✨ så burde det andet være fint. Jeg tror ikke, at konkurrenterne vil drage fordel af din obfuscated kode. Men hvis bundlen indeholder værdifuld intellektuel ejendom, så giver anvendelsen af open source-licensen fri brug af den.

Du laver enNode.JS-app

I dette tilfælde tilslutter du normalt biblioteker via et require()-kald. Det er en dynamisk sammenkobling. Det er fint at bruge Permissive- og endda Weakly Protective-licenser. Bare sørg for, at pakker forbliver i deres egne filer med respektive licenser.

Hvis du kun leverer SaaS og ikke distribuerer på anden vis, kan du endda bruge pakker med en Protective-licens. For mange Protective-licenser er netværksinteraktion ikke en distribution. Undtagelsen er Network Protective-licenser som Affero GPLv3

Du laver en Open Source NPM-pakke

Normalt forbinder du afhængigheder fra tredjepart via en package.json. Så vidt jeg ved, kan det ikke betragtes som linking at opføre afhængighed i package.json. Linking vil blive udført af en app-udvikler, som vil bruge din pakke på et build- eller kørselsstadie.

Hvis du ikke ønsker at forvirre pakkebrugere, skal du sikre dig, at alle afhængigheder (både umiddelbare og transitive) har kompatible licenser med din pakkelicens.

Typisk bør afhængighedslicenser være mere tilladende eller have samme tilladelsesniveau som din pakkelicens.

For eksempel, hvis din pakke har licens Apache 2.0, kan du bruge afhængigheder med MIT- og BSD-licens. Men du bør ikke bruge afhængighed med MPL1.1 eller LGPLv3-licens, fordi de har en stærkere copyleft-licens.

En pil fra boks A til boks B betyder, at du kan kombinere software med disse licenser; det kombinerede resultat har i praksis licens B, muligvis med tilføjelser fra A; billedet stammer fra David A’s arbejde. Wheeler

Når du skal lægge bundles eller kildekode fra tredjepart ind i en NPM-pakke, må du ikke glemme at angive tredjepartslicenser og ophavsrettigheder. De fleste open source-licenser kræver anerkendelse af forfatteren.

Det er også en god praksis at angive et gyldigt SPDX-udtryk i din package.json-licens. Jeg mener, at dette felt skal være obligatorisk for udgivelse på npm.org.

Hvordan du finder ud af det

Mange hold begynder at tænke på licenser, når softwaren er klar til at blive sendt. Jeg har brugt ScanCode-værktøjet til dette. Det går virkelig til hver mappe i dit projekt og forsøger at opdage hver eneste licens eller copyright.

Screenshot fra https://github.com/nexB/scancode-toolkit

Du skal sandsynligvis bruge dette eller et lignende værktøj, før du distribuerer din app. Sørg for, at du kontrollerer nok og ikke for meget:

  • installer alle dine produktionsafhængigheder, før du kører værktøjet
  • sørg for, at devDependencies ikke kontrolleres af værktøjet; normalt distribuerer du ikke med dine udviklingsafhængigheder;
  • Bemærk: Hvis du, ligesom jeg, kigger på pakkelicenser, efter du har integreret pakken i din app, kan du måske komme i en vanskelig situation.

    Kørsel af ScanCode lige før deadline; billede fra https://giphy.com

    Hvordan du finder ud af det, før det er for sent

    Jeg tænkte på, hvornår er det bedste tidspunkt at lære om licenser for pakkeafhængighed. For mig er det normale flow for at opdage pakker:

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

    Det er desværre sådan, at npm.org ikke rigtig tager sig af transitive afhængigheder. Der findes webværktøjer som http://npm.anvaka.com/; men det passer ikke til mit pakkeopdagelsesflow, og jeg glemmer hele tiden at bruge det. Jeg tænkte, at det bedste tidspunkt at lære om pakkeafhængigheder er, når du skriver $ npm install <pkg>

    Det var min tankegang, da jeg byggede et CLI-værktøj kaldet npm-consider, som analyserer pakken med alle transitive afhængigheder, før den installeres eller endog downloades.

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

    For at spare en kommando for dig, ombryder den $ npm install og har de samme argumenter. Hvis du har det fint med afhængigheder, skal du bare vælge Install, og det vil køre npm install som normalt. Hvis du er bekymret vælger Detaljer og ser hele afhængighedstræet:

    Viser detaljer ved installation af komponent i det populære geospatiale bibliotek Turf.js; bemærk, at selve pakken har en Permissive-licens, men en af de transitive afhængigheder har AGPL-licens; du kan ikke rigtig bruge den til proprietær software;

    Jeg mener, at en sådan funktionalitet skal være en del af npm CLI. Hvis du er enig, så ⭐️ projektet på GitHub, og jeg vil skubbe ideen fremad.

    Kilder

    Jeg oplister mine kilder, hvis du vil dobbelttjekke mine konklusioner:

    • Forståelse af npm’s afhængighedsmodel
    • Open source-licensering: Hvad enhver tekniker bør vide | Opensource.com
    • Various Licenses and Comments about Them
    • The Free-Libre / Open Source Software (FLOSS) License Slide
    • License Center | ifrOSS
    • Comparison of free and open-source software licenses – Wikipedia
    • Library (computing) – Wikipedia

    Hvis artiklen var nyttig, så vær venlig 👏 og måske vil jeg skrive en mere 😀