Disclaimer: Eu sou um desenvolvedor, não um advogado; acredita-se que esta informação esteja correta, mas não é um conselho legal; se você acha que algo está incorreto, por favor, escreva um comentário e nós iremos corrigi-lo together🔧

Antes de eu não estar preocupado com a licença do pacote npm. Eu poderia verificar a licença de dependência imediata mas nunca verificando dependências de terceiros (transitórias).

🚓 E então conheci caras do departamento jurídico 🚓

Eu agora acredito que os desenvolvedores devem ter um entendimento básico de licenciamento de software para ter um diálogo construtivo com as equipes jurídicas em suas empresas. Este post reúne um conhecimento geral sobre licenças Open-Source e como ele se aplica às dependências npm e ao desenvolvimento Full-Stack JavaScript em geral.

>

Vamos descobrir quando você deve começar a se preocupar com licenças.

>

Quando os requisitos da licença são acionados?

Se você fizer links com bibliotecas de código aberto e depois distribuir o software resultante, então seu software precisa estar de acordo com os requisitos das bibliotecas vinculadas.

Vejamos mais de perto os links e a distribuição aplicada aos aplicativos JavaScript.

Link

Usar bibliotecas de terceiros normalmente significa ligá-las:

  • Se você empacotar (ou seja, com webpack) o seu código com pacotes de código aberto, ele conta como ligação estática
  • Se você usar pacote de código aberto no seu aplicativo Node.JS (ou seja via require) ou conectá-lo a uma página web via tag de script, é um link dinâmico

Note: ao construir um pacote ou executar a aplicação Node.JS você executa o mesmo tipo de link tanto com dependências imediatas (listadas em seu package.json) quanto transitivas (listadas em 3rd party package.json). As licenças de dependências imediatas e transitivas têm o mesmo efeito no seu software.

Isto não era intuitivo para mim antes de 🤔

Distribuição

Apenas usando bibliotecas de código aberto não é necessário acionar os requisitos da licença. Normalmente, os requisitos da licença são acionados quando você distribui software:

  • Transferir software entre funcionários da mesma empresa não é uma distribuição
  • Quando os usuários interagem com o seu Nó.O aplicativo JS sobre rede, não é uma distribuição para a maioria das licenças de código aberto; mas é uma distribuição para licenças Network Protective como AGPL
  • Pôr ficheiros JavaScript num servidor web público é uma distribuição

Que licença é ok

A maior parte das licenças de código aberto geralmente se enquadram num destes tipos:

  • Licenças de domínio público e licenças permissivas como MIT que lhe permitem fazer qualquer coisa excepto processar o autor
  • Licenças Copyleft ou Protective como GPL impedem a ligação (ver acima) com software proprietário; o caso limite são as licenças Network Protective como Affero GPLv3 que dispara por interacção através da rede;
  • No meio de dois acima estão licenças Weakly Protective como MPL que tem menos restrição para links dinâmicos (até que a biblioteca esteja em seu próprio arquivo)

Vejamos os cenários comuns para um desenvolvedor JavaScript:

Você está fazendo uma aplicação web

Mais provavelmente você empacote todos os seus arquivos, incluindo bibliotecas em um arquivo JS e coloque-o em um servidor web. Você está realizando links estáticos e distribuição. É bom usar pacotes com licenças Permissive em um pacote.

Se você precisar usar um pacote com licença Weakly Protective como MPL você tem opções:

  1. Load library from separate file (i.e. via script tag)
  2. Aplique uma licença de código aberto compatível ao seu pacote (mas verifique o comentário abaixo e fale com a sua equipa jurídica antes)

Se o seu pacote não tem ✨valuable intelectual property✨ então o segundo deve estar bem. Eu não acredito que os concorrentes irão se beneficiar do seu código ofuscado. Mas se o pacote contém propriedade intelectual valiosa, então a aplicação da licença de código aberto está concedendo o uso gratuito do mesmo.

Você está fazendo um app.JS daNode

Neste caso, você normalmente conecta bibliotecas através de uma chamada require(). É uma ligação dinâmica. É bom usar licenças Permissive e até Weakly Protective. Apenas certifique-se que os pacotes ficam em seus próprios arquivos com as respectivas licenças.

Se você está fornecendo apenas SaaS e não está distribuindo de qualquer outra forma, você pode usar até mesmo pacotes com uma licença Protetora. Para muitas licenças Protective, a interacção em rede não é uma distribuição. A exceção são as licenças Network Protective como Affero GPLv3

Você está fazendo um pacote Open Source NPM

Normalmente, você conecta dependências de terceiros através de um pacote.json. Para meu melhor conhecimento, listar dependências em package.json não pode ser considerado como um link. A ligação será feita por um desenvolvedor de aplicativos que usará seu pacote em um estágio de compilação ou execução.

Se você não quiser confundir usuários de pacotes, certifique-se de que todas as dependências (tanto imediatas quanto transitivas) tenham licenças compatíveis com a sua licença de pacote.

As licenças de dependência tipicamente devem ser mais permissivas ou do mesmo nível de permissividade que a sua licença de pacote.

Por exemplo, se o seu pacote tem licença Apache 2.0 você pode usar dependências com a licença MIT e BSD. Mas você não deve usar dependências com a licença MPL1.1 ou LGPLv3, pois elas têm copyleft mais forte.

Uma seta da caixa A para a caixa B significa que você pode combinar software com estas licenças; o resultado combinado efetivamente tem a licença de B, possivelmente com adições de A; imagem do trabalho de David A. Wheeler

Quando precisar de colocar pacotes ou fontes de terceiros no pacote NPM, não se esqueça de listar as licenças e direitos de autor de terceiros. A maioria das licenças de código aberto requer o reconhecimento do autor.

Também, é uma boa prática especificar uma expressão SPDX válida na sua licença package.json. Eu acredito que este campo deve ser obrigatório para publicação em npm.org.

Como você o descobre

Muitas equipes começam a pensar em licenças quando o software está pronto para ser enviado. Eu tenho usado o utilitário ScanCode para isto. Ele realmente vai para cada pasta do seu projeto e tenta detectar cada licença ou copyright.

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

Você provavelmente tem que usar esta ou outra ferramenta similar antes de distribuir o seu aplicativo. Certifique-se de que você está verificando o suficiente e não muito:

  • instale todas as suas dependências de produção antes de executar a ferramenta
  • confirme que as dependências não são verificadas pela ferramenta; normalmente você não distribui com suas dependências de desenvolvimento;

Nota: se você está, como eu, procurando por licenças de pacotes após ter integrado o pacote em sua aplicação, você pode se encontrar em uma situação difícil.

Executar ScanCode pouco antes do prazo; imagem de https://giphy.com

Como você descobre antes que seja tarde demais

Interrogava-me, quando é o melhor momento para aprender sobre licenças de dependência de pacotes. Para mim, o fluxo normal de descoberta de pacotes é:

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

Felizmente npm.org não está realmente abordando as dependências transitivas. Existem ferramentas web como http://npm.anvaka.com/; mas não se encaixa no meu fluxo de descoberta de pacotes e eu continuo me esquecendo de usá-lo. Eu pensei que o melhor momento para aprender sobre dependências de pacotes é quando você digita $ npm install <pkg>

Foi o que eu pensei quando construí uma ferramenta CLI chamada npm-consider que analisa pacotes com todas as dependências transitivas antes de instalá-los ou mesmo baixá-los.

>

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

Para salvar um comando para você, ele envolve $ npm install e tem os mesmos argumentos. Se você estiver bem com dependências basta escolher Install e ele executará npm install como de costume. Se você estiver preocupado escolha Detalhes e veja toda a árvore de dependências:

Mostrar detalhes ao instalar o componente da popular biblioteca geoespacial Turf.js; note que o pacote em si tem uma licença Permissiva, mas uma das dependências transitivas tem licença AGPL; você não pode realmente usá-la para software proprietário;

Eu acredito que tal funcionalidade deve ser parte da npm CLI. Se você concordar, por favor ⭐️ projeto no GitHub e eu empurrarei a idéia para frente.

Fontes

I’m listing my sources in case you want to double-check my conclusions:

  • Understanding the npm dependency model
  • Open source licensing: O que todos os tecnólogos devem saber |Abrir código fonte.com
  • >

  • Várias licenças e comentários sobre elas
  • A Licença de Software Livre / Software de Código Aberto (FLOSS) Slide
  • Centro de Licenças | ifrOSS
  • >

  • Comparação de licenças de software livre e de código aberto – Wikipedia
  • Biblioteca (computação) – Wikipedia
  • >

>

Se o artigo foi útil, por favor 👏 e talvez eu escreva mais um 😀