Disclaimer: sono uno sviluppatore, non un avvocato; queste informazioni sono ritenute corrette, ma non sono consigli legali; se pensi che qualcosa non sia corretto, per favore, scrivi un commento e lo sistemeremo insieme🔧

Prima non ero preoccupato della licenza del pacchetto npm. Potevo controllare la licenza della dipendenza immediata ma mai controllare le dipendenze di terze parti (transitorie).

🚓 E poi ho incontrato i ragazzi del dipartimento legale 🚓

Ora credo che gli sviluppatori dovrebbero avere una comprensione di base delle licenze software per avere un dialogo costruttivo con i team legali delle loro aziende. Questo post raccoglie una conoscenza generale sulle licenze Open-Source e come si applica alle dipendenze di npm e allo sviluppo Full-Stack JavaScript in generale.

Capiamo quando si dovrebbe iniziare a preoccuparsi delle licenze.

Quando scattano i requisiti di licenza?

Se eseguite il collegamento con librerie open source e poi distribuite il software risultante, allora il vostro software deve essere conforme ai requisiti delle librerie collegate.

Guardiamo più da vicino il collegamento e la distribuzione applicati alle applicazioni JavaScript.

Collegamento

Utilizzare librerie di terze parti normalmente significa collegarle:

  • Se fai il bundle (cioè con webpack) del tuo codice con pacchetti open source conta come collegamento statico
  • Se usi pacchetti open source nella tua app Node.JS (cioè tramite require) o lo colleghi a una pagina web tramite tag script, è un collegamento dinamico

Nota: quando costruisci un bundle o esegui un’applicazione Node.JS esegui lo stesso tipo di collegamento sia con dipendenze immediate (elencate nel tuo package.json) che transitive (elencate nel package.json di terze parti). Le licenze per le dipendenze immediate e transitive hanno lo stesso effetto sul tuo software.

Questo non era intuitivo per me prima 🤔

Distribuzione

Il solo utilizzo di librerie open source non fa necessariamente scattare i requisiti di licenza. Normalmente, i requisiti di licenza vengono attivati quando si distribuisce software:

  • Trasferire software tra dipendenti della stessa azienda non è una distribuzione
  • Quando gli utenti interagiscono con la tua app Node.JS in rete, non è una distribuzione per la maggior parte delle licenze open source; ma è una distribuzione per le licenze Network Protective come AGPL
  • Mettere file JavaScript su un server web pubblico è una distribuzione

Quale licenza va bene

La maggior parte delle licenze open source generalmente rientrano in uno di questi tipi:

  • Licenze di pubblico dominio e licenze permissive come il MIT che ti permettono di fare qualsiasi cosa tranne fare causa all’autore
  • Licenze copyleft o protettive come la GPL impediscono il collegamento (vedi sopra) con il software proprietario; il caso limite sono le licenze protettive di rete come Affero GPLv3 che si attivano per interazione in rete;
  • Tra le due precedenti ci sono le licenze debolmente protettive come la MPL che ha meno restrizioni per il collegamento dinamico (finché la libreria non è nel proprio file)

Controlliamo gli scenari comuni per uno sviluppatore JavaScript:

Stai facendo una web app

Molto probabilmente metti in bundle tutti i tuoi file, incluse le librerie in un file JS e lo metti su un server web. Stai eseguendo il linking statico e la distribuzione. Va bene usare pacchetti con licenze permissive in un bundle.

Se hai bisogno di usare un pacchetto con licenza debolmente protettiva come MPL hai delle opzioni:

  1. Carica la libreria da un file separato (cioè tramite tag script)
  2. Applica una licenza open source compatibile al tuo bundle (ma controlla i commenti qui sotto e parla con il tuo team legale prima)

Se il tuo bundle non ha ✨una proprietà intellettuale di valore✨ allora la seconda dovrebbe andare bene. Non credo che i concorrenti beneficeranno del tuo codice offuscato. Ma se il bundle contiene una preziosa proprietà intellettuale, allora applicare la licenza open source ne garantisce il libero utilizzo.

Stai facendo un’appNode.JS

In questo caso, normalmente colleghi le librerie tramite una chiamata require(). È un collegamento dinamico. Va bene usare licenze Permissive e anche Weakly Protective. Assicurati solo che i pacchetti stiano nei loro file con le rispettive licenze.

Se stai fornendo solo SaaS e non stai distribuendo in nessun altro modo, puoi usare anche pacchetti con una licenza Protective. Per molte licenze Protective, l’interazione di rete non è una distribuzione. L’eccezione è rappresentata dalle licenze di Network Protective come Affero GPLv3

Stai facendo un pacchetto Open Source NPM

Normalmente, colleghi le dipendenze di terze parti tramite un package.json. Per quanto ne so, elencare le dipendenze in package.json non può essere considerato un collegamento. Il collegamento verrà eseguito da uno sviluppatore di app che utilizzerà il tuo pacchetto in una fase di compilazione o esecuzione.

Se non vuoi confondere gli utenti del pacchetto assicurati che tutte le dipendenze (sia immediate che transitive) abbiano licenze compatibili con la licenza del tuo pacchetto.

In genere le licenze delle dipendenze dovrebbero essere più permissive o con lo stesso livello di permissività della licenza del tuo pacchetto.

Per esempio, se il tuo pacchetto ha licenza Apache 2.0 puoi usare dipendenze con licenza MIT e BSD. Ma non dovreste usare dipendenze con licenza MPL1.1 o LGPLv3, perché hanno un copyleft più forte.

Una freccia dalla casella A alla casella B significa che è possibile combinare software con queste licenze; il risultato combinato ha effettivamente la licenza di B, eventualmente con aggiunte da A; immagine dal lavoro di David A. Wheeler

Quando avete bisogno di mettere bundle o sorgenti di terze parti nel pacchetto NPM, non dimenticate di elencare le licenze e i copyright delle terze parti. La maggior parte delle licenze open source richiedono il riconoscimento dell’autore.

Inoltre, è una buona pratica specificare un’espressione SPDX valida nella licenza package.json. Credo che questo campo debba essere obbligatorio per la pubblicazione su npm.org.

Come si capisce

Molti team iniziano a pensare alle licenze quando il software è pronto per la spedizione. Ho usato l’utilità ScanCode per questo. Va davvero in ogni cartella del tuo progetto e cerca di rilevare ogni licenza o copyright.

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

Probabilmente devi usare questo o uno strumento simile prima di distribuire la tua app. Assicurati di controllare abbastanza e non troppo:

  • installa tutte le tue dipendenze di produzione prima di eseguire lo strumento
  • assicurati che le devDependencies non siano controllate dallo strumento; normalmente non distribuisci con le tue dipendenze di sviluppo;

Nota: se stai, come me, guardando le licenze dei pacchetti dopo aver integrato il pacchetto nella tua app, potresti trovarti in una situazione difficile.

Eseguire ScanCode poco prima della scadenza; immagine da https://giphy.com

Come capirlo prima che sia troppo tardi

Mi stavo chiedendo, quando è il momento migliore per conoscere le licenze dei pacchetti. Per me, il normale flusso di scoperta dei pacchetti è:

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

Purtroppo npm.org non si occupa realmente delle dipendenze transitive. Ci sono strumenti web come http://npm.anvaka.com/; ma non si adatta al mio flusso di scoperta dei pacchetti e continuo a dimenticare di usarlo. Ho pensato che il momento migliore per conoscere le dipendenze dei pacchetti è quando si digita $ npm install <pkg>

Questo era il mio pensiero quando ho costruito uno strumento CLI chiamato npm-consider che analizza i pacchetti con tutte le dipendenze transitive prima di installarli o addirittura scaricarli.

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

Per risparmiarti un comando, avvolge $ npm install e ha gli stessi argomenti. Se siete a posto con le dipendenze basta scegliere Install e verrà eseguito npm install come al solito. Se siete preoccupati scegliete Dettagli e vedrete l’intero albero delle dipendenze:

Mostra i dettagli dell’installazione del componente della popolare libreria geospaziale Turf.js; si noti che il pacchetto stesso ha una licenza Permissive, ma una delle dipendenze transitive ha la licenza AGPL; non si può davvero usare per il software proprietario;

Credo che tale funzionalità debba essere parte di npm CLI. Se sei d’accordo, per favore ⭐️ progetto su GitHub e spingerò l’idea in avanti.

Fonti

Elenco le mie fonti nel caso tu voglia ricontrollare le mie conclusioni:

  • Capire il modello di dipendenza di npm
  • Licenze open source: Quello che ogni tecnologo dovrebbe sapere | Opensource.com
  • Varie licenze e commenti su di esse
  • La slide della licenza Free-Libre / Open Source Software (FLOSS)
  • License Center | ifrOSS
  • Confronto tra licenze di software libero e open-source – Wikipedia
  • Biblioteca (informatica) – Wikipedia

Se l’articolo è stato utile, per favore 👏 e forse ne scriverò un altro 😀