A la lliçó anterior vam publicar @escena-viva/format i vam veure que, en fer-ho, adquiríem un compromís: altres persones executarien el nostre codi a les seves màquines. Aquesta lliçó dona la volta a l'argument. Cada vegada que escrius npm install, estàs descarregant codi de desconeguts i executant-lo amb els teus permisos: els mateixos que té el teu usuari per llegir el teu ~/.ssh, el teu .env o el token de desplegament de la teva integració contínua.

No és una advertència teòrica. La cadena de subministrament de programari és avui un dels vectors d'atac més rendibles, precisament perquè un sol paquet compromès arriba a milers d'organitzacions sense que cap hagi comès cap error. Escena Viva té, a dia d'avui, dues dependències directes i un grapat de transitives: és el moment ideal per aprendre a auditar-les, perquè l'arbre encara cap al cap. Al mòdul 6 instal·larem Express i el número es multiplicarà.

Contingut

  1. La cadena de subministrament com a superfície d'atac
  2. npm audit: llegir la sortida de debò
  3. npm audit fix i el perill de --force
  4. Localitzar el culpable: npm ls i overrides
  5. Atacs que cal saber reconèixer
  6. Mesures pràctiques de defensa
  7. Manteniment continu: npm outdated i automatització
  8. Llicències: el risc que no és tècnic
  9. Auditar Escena Viva i escriure la rutina
  10. Errors Comuns i Consells
  11. Exercicis
  12. Conclusió (tancament del Mòdul 5)

  1. La cadena de subministrament com a superfície d'atac

L'aritmètica de l'ecosistema npm és l'arrel del problema. Un projecte amb 20 dependències directes sol acabar amb entre 300 i 800 paquets a node_modules, mantinguts per centenars de persones diferents que ningú no ha verificat. npm ls --all --parseable | wc -l et diu quants n'hi ha realment al teu projecte, i la xifra sol sorprendre.

Cadascun d'aquests paquets pot, durant la instal·lació o durant l'execució:

  • Llegir qualsevol fitxer al qual tingui accés el teu usuari, incloses claus privades i fitxers .env.
  • Obrir connexions de xarxa i enviar el que hagi llegit a un servidor qualsevol.
  • Executar ordres arbitràries mitjançant els ganxos preinstall, install i postinstall que vam veure a 05-04.

Aquest últim punt és el més greu i el menys conegut: no cal que arribis a importar el paquet. Un postinstall maliciós s'executa durant el mateix npm install.

Hi ha dues idees que convé tenir clares des del principi:

Creença habitual Realitat
"Només instal·lo paquets populars" La popularitat protegeix de la mala qualitat, no del segrest d'un compte
"És una dependència de desenvolupament, no arriba a producció" S'executa al teu portàtil i a la teva CI, on hi ha els tokens
"Reviso les dependències directes" El 95 % del codi instal·lat és transitiu
"El lock em protegeix" Et protegeix de canvis inesperats, no que la versió fixada sigui vulnerable

  1. npm audit: llegir la sortida de debò

npm audit compara l'arbre de dependències resolt (el del package-lock.json) amb una base de dades pública de vulnerabilitats conegudes.

npm audit

Una sortida típica té aquesta forma:

# npm audit report

tar-fs  2.0.0 - 2.1.2
Severity: high
tar-fs can extract outside the specified directory - GHSA-pq67-2wwv-3xjx
fix available via `npm audit fix`
node_modules/tar-fs
  bundled-dependency  *
  Depends on vulnerable versions of tar-fs
  node_modules/bundled-dependency

2 vulnerabilities (1 moderate, 1 high)

Cal llegir-la per parts: tar-fs 2.0.0 - 2.1.2 és el paquet afectat i el rang vulnerable; Severity la gravetat assignada; la descripció amb l'identificador GHSA-... diu què es pot fer amb la fallada (aquesta dada importa més que la gravetat); i el bloc sagnat mostra la cadena de dependències, on bundled-dependency és qui arrossega el paquet vulnerable i, per tant, on cal actuar.

Les gravetats no són una escala d'urgència automàtica:

Gravetat Significat aproximat Reacció raonable
Critical Execució remota de codi, robatori de credencials Immediata, encara que sigui divendres
High Escalada, escriptura fora de ruta, evasió d'autenticació En dies
Moderate Denegació de servei, filtració limitada A la iteració següent
Low Impacte marginal o molt condicionat Quan toqui manteniment

L'important és que la gravetat es calcula en abstracte, sense saber com fas servir tu el paquet. Una vulnerabilitat "high" d'expressió regular amb denegació de servei en una biblioteca que només processa cadenes escrites per tu, en temps de compilació, no és una emergència. I a la inversa: una "moderate" al camí d'una petició HTTP pública pot ser urgent. Abans de reaccionar, pregunta't sempre: la dada que arriba a aquesta funció ve d'un usuari?

Sobre els falsos positius en dependències de desenvolupament: és habitual que npm audit assenyali dotzenes de problemes a la cadena d'eines de construcció o proves. Mereixen atenció, però d'una altra mena: una fallada de denegació de servei en un formatador que només s'executa al teu portàtil no és un risc per als teus usuaris. Per separar el soroll del senyal, npm audit --omit=dev mostra només el que arriba a producció i npm audit --audit-level=high només el que passa de certa gravetat. Aquesta última és la que convé posar a la integració contínua: fer fallar la construcció per qualsevol "low" en una eina de desenvolupament genera fatiga d'alertes, i la fatiga d'alertes és com s'acaben ignorant les crítiques. Per processar la sortida amb eines, npm audit --json la retorna estructurada.

  1. npm audit fix i el perill de --force

npm audit fix intenta resoldre les vulnerabilitats respectant els rangs declarats al teu package.json. Si dotenv hi és com a ^17.2.1 i l'arranjament és a 17.2.4, l'aplica sense preguntar: és un canvi compatible segons SemVer. És una operació segura i convé executar-la amb regularitat.

El problema és l'indicador que la sortida et suggereix quan no pot arreglar alguna cosa. npm audit fix --force abandona els rangs declarats i instal·la la versió que resol el problema, encara que sigui un salt major: pot canviar express@4 per express@5 o pujar dues versions majors una eina de construcció, amb tots els canvis trencadors que això impliqui. La sortida ho avisa entre línies:

npm WARN audit Updating express to 5.1.0, which is a SemVer major change.

La regla és senzilla: npm audit fix sí, en qualsevol moment; npm audit fix --force mai a cegues, i tampoc mai a la branca principal sense revisar el git diff del package.json i del lock, i sense passar les proves. Si l'executes per error:

git checkout package.json package-lock.json
npm ci

I hi ha un tercer cas, el més frustrant: npm audit informa d'una vulnerabilitat sense arranjament disponible, perquè el paquet intermedi no ha publicat cap versió que faci servir la dependència apedaçada. Aquí és on entren les dues eines de la secció següent.

  1. Localitzar el culpable: npm ls i overrides

Abans d'arreglar res cal saber qui porta el paquet vulnerable. npm ls ho respon:

npm ls tar-fs
[email protected] /home/usuari/escena-viva
└─┬ [email protected]
  └─┬ [email protected]
    └── [email protected]

La lectura és directa: no depenem de tar-fs, sinó d'eina-construccio, que fa servir empaquetador, que fa servir tar-fs. Les opcions, per ordre de preferència: actualitzar la dependència directa si ja existeix una versió que arrossegui l'apedaçada (el que és net); forçar la versió de la transitiva amb overrides si l'anterior no està disponible; o substituir la dependència directa si el mantenidor no respon.

El camp overrides del package.json permet a npm reescriure l'arbre resolt:

{
  "overrides": {
    "tar-fs": "2.1.3"
  }
}

Això obliga que qualsevol aparició de tar-fs a l'arbre, vingui d'on vingui, es resolgui a 2.1.3. Si vols ser més quirúrgic i afectar només una branca concreta:

{
  "overrides": {
    "eina-construccio": {
      "empaquetador": {
        "tar-fs": "2.1.3"
      }
    }
  }
}

Després d'editar el manifest cal regenerar l'arbre i comprovar el resultat:

npm install
npm ls tar-fs
npm audit

Dues advertències sobre overrides. La primera: estàs instal·lant una combinació de versions que el mantenidor d'empaquetador no ha provat mai, així que necessites proves pròpies que avalin el canvi (mòdul 9). La segona: un overrides és deute tècnic amb data. Posa-li un comentari al CHANGELOG o al README explicant per què hi és i quan es podrà treure, o d'aquí a un any ningú no s'atrevirà a tocar-lo.

  1. Atacs que cal saber reconèixer

Typosquatting. Es registra un paquet amb un nom gairebé idèntic a un de popular —expres en comptes d'express, lodahs en comptes de lodash, crossenv en comptes de cross-env— i s'espera que algú s'equivoqui en teclejar o en copiar d'un tutorial mal escrit. El paquet fals sol reexportar l'autèntic —perquè tot "funcioni"— i afegir un postinstall que envia les teves variables d'entorn a un servidor extern. Defensa: copia els noms des de la documentació oficial, no des d'un blog, i desconfia d'un paquet amb 200 descàrregues quan el que busques en té milions.

Segrest del compte d'un mantenidor. El paquet és legítim i fa anys que és de fiar; el que canvia és qui controla el compte que publica. Ha passat per contrasenyes reutilitzades, per pesca dirigida a mantenidors i per transferències de propietat a desconeguts que s'oferien amablement a "ajudar amb el manteniment". La versió maliciosa es publica i es propaga en hores a través dels rangs ^. Defensa: npm ci amb lock fixat, no actualitzar a cegues el dia de publicació, i revisar el diff quan un paquet petit i estable treu de sobte una versió.

Paquets abandonats. No hi ha atac, hi ha absència: ningú no apedaça, ningú no respon les incidències, i les vulnerabilitats s'acumulen. Senyals d'alarma: últim publish fa tres anys, incidències obertes sense resposta, un únic mantenidor. És també el terreny fèrtil del segrest per transferència. Defensa: la llista de comprovació de 05-02, aplicada també a les revisions periòdiques.

Confusió de dependències. Una empresa fa servir un paquet intern anomenat, per exemple, escena-viva-pagaments, allotjat al seu registre privat. Un atacant publica un paquet amb aquest mateix nom al registre públic i amb una versió més alta. Segons com estigui configurada la resolució, el client pot preferir la versió pública. Defensa: publicar sempre sota un àmbit propi (@escena-viva/pagaments) i ancorar aquest àmbit al registre privat:

# .npmrc del projecte
@escena-viva:registry=https://registre.intern.escena-viva.test/

Així, qualsevol cosa sota @escena-viva/ es busca només al registre intern, i un homònim públic és irrellevant.

Protestware. El mantenidor introdueix deliberadament un comportament no funcional —missatges polítics per consola, retards, en casos extrems esborrat de fitxers segons la geolocalització— com a forma de protesta. No és un atac extern, però trenca la confiança igualment i ha passat en paquets amb milions de descàrregues setmanals. Defensa: la mateixa que per a la resta —lock fixat, actualitzacions revisades— més una reflexió honesta sobre quantes dependències trivials té el teu projecte.

  1. Mesures pràctiques de defensa

npm ci en producció i a la CI. Ja ho vam veure a 05-03: instal·la exactament el que diu el package-lock.json, sense resoldre rangs. És el que impedeix que una versió publicada fa deu minuts entri al teu desplegament.

npm ci --omit=dev

--ignore-scripts. npm ci --ignore-scripts impedeix que s'executin els ganxos d'instal·lació de les dependències, que és per on entra bona part del codi maliciós. Què trenca: els paquets que compilen binaris natius o descarreguen artefactes al seu postinstall queden inservibles —biblioteques amb extensions natives, eines que baixen un navegador—. Escena Viva, amb dotenv i prettier, no en té cap, així que ho pot activar sense problema i deixar-ho fixat al .npmrc del projecte:

engine-strict=true
ignore-scripts=true

Si un paquet concret ho necessita, s'executa el seu script de forma explícita i conscient en comptes d'obrir la porta als centenars restants.

Fixar versions crítiques. Per al que toca autenticació, criptografia o pagaments, la comoditat de ^ no compensa. Fixa la versió exacta i actualitza a mà llegint el changelog:

"dependencies": {
  "@escena-viva/format": "0.2.1"
}

Revisar el package-lock.json a les revisions de codi. No cal llegir les 4.000 línies; cal mirar tres coses: paquets nous que ningú no ha esmentat a la descripció del canvi, canvis al camp resolved que apuntin a un domini que no sigui el registre esperat, i salts de versió major. Un lock que canvia en un pull request que "només toca CSS" és un senyal.

Tokens de només lectura. Si la teva CI únicament instal·la, el seu token no necessita permís de publicació. El token amb permís d'escriptura viu només al flux que publica, i amb abast limitat als paquets concrets (ho vam veure a 05-05, i ho configurarem al mòdul 11).

npm audit signatures. Verifica que els paquets instal·lats estan signats pel registre i que les signatures coincideixen amb el que s'ha descarregat; detecta manipulacions en trànsit o en un mirall compromès. Respon amb un 214 packages have verified registry signatures en pocs segons, i és un bon candidat per al flux de CI al costat de npm audit --audit-level=high.

  1. Manteniment continu: npm outdated i automatització

La seguretat de dependències no és una tasca, és una rutina. L'eina base:

npm outdated
Package    Current  Wanted  Latest  Location              Depended by
dotenv      17.2.1  17.2.4  17.4.0  node_modules/dotenv   escena-viva
prettier     3.6.2   3.6.4   4.0.1  node_modules/prettier escena-viva

Current és el que hi ha instal·lat ara mateix, Wanted el màxim que permet el teu rang al package.json i Latest l'última publicada amb l'etiqueta latest. La diferència entre Current i Wanted es resol amb npm update i és de risc baix; la diferència entre Wanted i Latest és un salt major i requereix feina: llegir el changelog, migrar, provar.

Una política d'actualització raonable, i sostenible:

Tipus de canvi Termini Procediment
Pedaç de seguretat (alta o crítica) El mateix dia npm audit fix, proves, desplegament
Pedaç normal Setmanal npm update, proves automàtiques, fusionar
Menor Quinzenal o mensual Revisar changelog, proves, fusionar
Major Planificat Branca pròpia, lectura de la guia de migració, proves manuals

Tot això descansa sobre una condició que avui no complim: proves automàtiques fiables. Sense elles, actualitzar és una aposta i l'equip acaba congelant versions per por, que és la pitjor situació possible. Per això el test d'Escena Viva continua a exit 1 amb el missatge "Sense proves encara — Modul 9": és un deute declarat, no oblidat, i és el que farà que aquest calendari sigui aplicable.

Per no fer-ho a mà existeixen els bots d'actualització, Dependabot (integrat a GitHub) i Renovate. Obren pull requests automàtics quan hi ha versions noves, amb el changelog a la descripció, i deixen que la teva CI decideixi si passen. Una configuració sensata:

# .github/dependabot.yml
version: 2
updates:
  - package-ecosystem: npm
    directory: /
    schedule:
      interval: weekly
    open-pull-requests-limit: 5
    groups:
      pedacos:
        update-types: [patch]

Agrupar els pedaços en un sol pull request setmanal i deixar els majors individuals evita l'efecte contrari al desitjat: vint pull requests oberts que ningú no revisa són pitjor que cap.

  1. Llicències: el risc que no és tècnic

Cada dependència porta una llicència, i aquesta llicència imposa condicions al teu producte. En un projecte personal s'ignora; en un projecte d'empresa és un assumpte legal amb conseqüències reals.

Llicència Tipus Implicació pràctica
MIT, ISC, BSD, Apache-2.0 Permissiva Ús lliure, fins i tot comercial i tancat, conservant l'avís de copyright
LGPL Copyleft feble Ús possible enllaçant, amb condicions si modifiques la biblioteca
GPL, AGPL Copyleft fort Pot obligar a publicar el codi del teu producte; l'AGPL abasta també el programari servit per xarxa
Sense llicència Tots els drets reservats Legalment no tens permís d'ús, encara que sigui a npm
Comercial / dual Variable Pot requerir compra a partir de certa mida d'empresa

El cas que més problemes causa en aplicacions web és l'AGPL: com que Escena Viva serveix la seva funcionalitat per xarxa, una dependència AGPL podria obligar a publicar el codi complet del projecte. I "sense llicència" és pitjor que una llicència restrictiva, perquè no hi ha res per negociar.

Revisar les llicències de l'arbre és senzill: npm view dotenv license mostra la declarada per un paquet, i npx license-checker --summary recorre l'arbre complet. En un entorn d'empresa l'habitual és tenir una llista de llicències aprovades i comprovar-la a la CI. La conversa amb el departament legal és infinitament més fàcil abans de construir el producte que després.

  1. Auditar Escena Viva i escriure la rutina

Aplicarem tot l'anterior al nostre projecte. Les dependències reals són @escena-viva/format i dotenv en producció, prettier i eslint en desenvolupament.

npm ls --all            # 1. Estat de l-arbre complet
npm audit               # 2. Auditoria general...
npm audit --omit=dev    #    ...i nomes el que arriba a produccio
npm audit signatures    # 3. Verificacio de signatures del registre
npm outdated            # 4. Que hi ha desactualitzat
npm view dotenv license # 5. Llicencies de les dependencies directes

El resultat esperat és tranquil·litzador precisament perquè durant els mòduls 1 a 4 vam construir el servidor sencer amb la biblioteca estàndard. Aquell va ser el millor control de seguretat de tot el curs: el codi que no instal·les no et pot comprometre.

Amb el diagnòstic fet, deixem la rutina escrita on es pugui trobar. Afegim aquesta secció al README.md del projecte:

## Manteniment de dependencies

**Setmanal** (responsable: qui faci la guardia)
- `npm outdated` i `npm audit`
- `npm audit fix` per al que es resolgui dins dels rangs
- Revisar i fusionar el PR agrupat de pedacos de Dependabot

**Mensual**
- Revisar versions menors pendents llegint el seu changelog
- Revisar que cap `overrides` continui sent necessari
- `npm ls --all` i comprovar si ha aparegut alguna dependencia sense justificar

**Davant d-un avis de gravetat alta o critica**
- `npm ls <paquet>` per identificar qui l-arrossega
- Actualitzar la dependencia directa; si no hi ha versio, fer servir `overrides`
- Mai `npm audit fix --force` sense revisar el diff i passar les proves

**Regles fixes**
- En produccio i a la CI: `npm ci --omit=dev`, mai `npm install`
- `ignore-scripts=true` al `.npmrc` del projecte
- El `package-lock.json` es revisa a cada pull request
- Abans d-acceptar una dependencia nova: llista de comprovacio (manteniment,
  descarregues, dependencies propies, llicencia, alternativa a la biblioteca estandard)

I afegim un script que agrupa la comprovació, seguint el criteri de 05-04 que tot s'executi per la mateixa interfície:

"scripts": {
  "auditoria": "npm audit --audit-level=high && npm audit signatures",
  "comprovar": "npm run lint && npm run format && npm run auditoria"
}

Ara npm run auditoria forma part del vocabulari del projecte, i npm run comprovar —l'ordre que ja feia servir l'equip— incorpora la seguretat sense que ningú hagi de recordar una ordre nova.

Errors Comuns i Consells

Executar npm audit fix --force perquè la mateixa sortida ho suggereix. Aquest text no avalua el teu projecte: canvia versions majors sense preguntar. Tracta'l com una migració, amb branca, revisió i proves.

Tractar totes les gravetats igual. Una de crítica al camí d'una petició pública i una de moderada en un formatador de desenvolupament no mereixen la mateixa reacció. Llegeix la descripció, no només l'etiqueta.

Ignorar npm audit perquè "sempre surt el mateix". La fatiga d'alertes és com s'escolen les importants. Filtra amb --audit-level=high i --omit=dev fins que la sortida torni a ser accionable.

Creure que el lock és una defensa de seguretat. Garanteix reproduïbilitat: instal·laràs sempre el mateix, vulnerable o no. La defensa és auditar, no fixar. I en desplegament sempre npm ci, mai npm install, que resol rangs i et pot portar una versió publicada fa minuts.

Copiar noms de paquets des de blogs o des d'una resposta generada. És la via natural del typosquatting. Verifica el nom a la documentació oficial i mira les descàrregues abans d'instal·lar.

Publicar paquets interns sense àmbit. És la porta oberta a la confusió de dependències. Fes servir @empresa/nom i ancora l'àmbit al teu registre al .npmrc.

Deixar overrides sense documentar. D'aquí a sis mesos ningú no sabrà si allò continua fent falta i ningú no s'atrevirà a treure-ho. Anota el motiu i la condició de sortida.

Descartar les llicències com a "cosa d'advocats". Una AGPL a l'arbre d'una aplicació web pot tenir conseqüències cares. Costa menys comprovar-ho avui.

Exercicis

Exercici 1: interpretar una auditoria

npm audit a Escena Viva informa d'això:

minimatch  <3.0.5
Severity: high
Regular Expression Denial of Service - GHSA-f8q6-p94x-37v3
No fix available
node_modules/minimatch
  eslint  8.0.0 - 8.57.0
  Depends on vulnerable versions of minimatch

Respon: és una urgència per als usuaris de la plataforma? Quina ordre fas servir per confirmar qui arrossega minimatch? Enumera les opcions de resolució, ordenades de millor a pitjor, sabent que la sortida diu "No fix available".

Exercici 2: forçar una transitiva apedaçada

Una dependència directa teva, [email protected], arrossega [email protected], que té una vulnerabilitat crítica ja corregida a [email protected]. El mantenidor de generador-informes no ha publicat res en sis mesos. Escriu l'overrides mínim que resol el cas afectant només aquesta branca, les ordres per aplicar-lo i verificar-lo, i què anotaries al README.

Exercici 3: un pull request sospitós

Arriba un pull request titulat "Millora del format de l'informe d'ocupació". El diff toca src/informes/ocupacio.js (12 línies), però també afegeix al package.json una dependència colors-consola i 340 línies al package-lock.json. Enumera les comprovacions concretes que faries abans d'aprovar-lo i quins senyals concrets et farien rebutjar-lo.

Solucions

Solució 1. No és una urgència per als usuaris. eslint és una dependència de desenvolupament: no s'instal·la en producció (npm ci --omit=dev) ni processa dades que enviï un comprador d'entrades. La denegació de servei per expressió regular requereix una cadena d'entrada maliciosa, i aquí les entrades són rutes de fitxers del mateix repositori. És una troballa real però de risc baix en aquest context; npm audit --omit=dev hauria de deixar de mostrar-la.

Per confirmar la cadena:

npm ls minimatch

Opcions, de millor a pitjor:

  1. Actualitzar eslint a una versió major que ja faci servir un minimatch apedaçat. És la solució neta i afecta només les eines.
  2. Si aquesta versió encara no existeix, afegir un overrides per a minimatch i documentar que és temporal.
  3. Acceptar el risc de forma explícita i documentada, amb revisió a la rutina mensual, atès que és una dependència de desenvolupament.
  4. Substituir eslint. Desproporcionat per al risc real.

El que no es fa és npm audit fix --force, que probablement pujaria ESLint de versió major i trencaria la configuració de 05-04 sense previ avís.

Solució 2. L'overrides acotat a aquesta branca:

{
  "overrides": {
    "generador-informes": {
      "analitzador-csv": "1.0.5"
    }
  }
}

Aplicació i verificació:

npm install
npm ls analitzador-csv   # ha de mostrar 1.0.5
npm audit                # la critica ha de desapareixer
npm run informe          # comprovacio funcional real

Al README, dins de la secció de manteniment:

### Overrides actius
- `[email protected]` sota `generador-informes`: pedac de GHSA-xxxx.
  Retirar quan `generador-informes` publiqui una versio que ja l-inclogui.
  Revisat: 2026-08-14.

L'anotació amb data és el que converteix una solució temporal en alguna cosa revisable, en comptes d'un misteri permanent.

Solució 3. Comprovacions abans d'aprovar:

  1. Està justificada la dependència? Dotze línies de format d'informe no solen necessitar un paquet extern; les seqüències ANSI de color caben en cinc línies pròpies, i Node ja ofereix utilitats d'estil en consola.
  2. Verificar el nom exacte contra la documentació oficial del paquet que es pretenia fer servir: és el patró exacte del typosquatting.
  3. npm view colors-consola: data de l'última publicació, nombre de descàrregues, mantenidors, llicència i —molt important— les seves pròpies dependències.
  4. Buscar postinstall al package.json del paquet i al lock.
  5. Revisar al package-lock.json els camps resolved: han d'apuntar al registre esperat i no a un domini o repositori arbitrari.
  6. Comprovar quants paquets nous apareixen: 340 línies de lock per a una utilitat de color suggereix un arbre transitiu desproporcionat.
  7. Passar npm audit i npm audit signatures sobre la branca.

Senyals per rebutjar directament: el nom no coincideix amb cap paquet conegut i té poques descàrregues; hi ha un script d'instal·lació; el resolved apunta fora del registre; el paquet es va publicar fa dies; o simplement la funcionalitat es resol sense dependència. En aquest cas, el raonable és demanar que el color s'implementi al mateix projecte i que el pull request quedi en les 12 línies que anunciava el seu títol.

Conclusió

Instal·lar és executar codi aliè amb els teus permisos. Aquesta frase resumeix la lliçó i justifica tota la resta: npm audit per saber què hi ha, llegint la descripció de la fallada i no només l'etiqueta de gravetat; npm audit fix com a rutina i --force mai a cegues; npm ls <paquet> per localitzar qui arrossega el que és vulnerable i overrides —documentat i amb data— per forçar una transitiva apedaçada quan no hi ha sortida neta. Hem après a reconèixer typosquatting, comptes segrestats, paquets abandonats, confusió de dependències i protestware, i a defensar-nos amb mesures concretes: npm ci en producció, ignore-scripts al .npmrc, versions fixades en allò crític, revisió del lock a cada pull request, tokens de només lectura i npm audit signatures. I hem deixat escrita al README una rutina de manteniment —pedaços de pressa, majors amb calma— que només serà sostenible quan tinguem les proves del mòdul 9, a més d'una mirada a les llicències, que són un risc d'empresa encara que no siguin un risc tècnic.

Amb això es tanca el mòdul 5 complet. Vam començar amb el manifest: npm init, el package.json camp a camp, node_modules, npx i .npmrc. Vam continuar amb la instal·lació: dependencies davant de devDependencies, l'arbre aplanat i les seves dependències fantasma, i la llista de comprovació per acceptar una dependència abans d'instal·lar-la. Després va venir el versionat: SemVer, els rangs i la seva trampa a ^0.x.y, el package-lock.json amb el seu integrity i el seu resolved, i npm ci com a forma correcta d'instal·lar en màquines que no són la teva. Després els scripts, convertits en la interfície única del projecte, amb el PATH de node_modules/.bin, els ganxos i els seus riscos. A la cinquena lliçó vam canviar de banda del taulell i vam publicar @escena-viva/format, decidint amb exports què és API pública i amb files què viatja al registre. I aquí hem après a conviure amb tot aquest codi aliè sense ingenuïtat. Escena Viva ja no és només una aplicació que funciona: és un projecte amb manifest, versions reproduïbles, ordres estandarditzades, un paquet propi publicat i una política de seguretat escrita.

Al mòdul 6 arriba Express, i arriba en el millor moment possible. Substituirem l'enrutador artesanal que vam escriure al mòdul 4 per un framework, i l'experiència serà diferent de l'habitual: on altres veuen màgia, tu reconeixeràs peces. L'app.get('/api/esdeveniments/:id') d'Express és l'enrutador.js que vas construir comparant rutes i extraient paràmetres a mà. El seu middleware és la cadena de funcions que ja vas encadenar al voltant de cos.js. El seu res.json() és el teu respostes.js. El seu gestor d'errors és el teu errors-http.js. I cada dependència que Express porti amb ell la miraràs amb els ulls que acabes d'entrenar en aquesta lliçó. Començarem per la introducció a Express: quin problema resol exactament, què t'estalvia i què continua sent responsabilitat teva.

Curs de Node.js: De Principiant a Avançat

Mòdul 1: Introducció a Node.js

Mòdul 2: Conceptes Bàsics

Mòdul 3: Sistema de Fitxers i E/S

Mòdul 4: HTTP i Servidors Web

Mòdul 5: NPM i Gestió de Paquets

Mòdul 6: Framework Express.js

Mòdul 7: Bases de Dades i ORMs

Mòdul 8: Autenticació i Autorització

Mòdul 9: Proves i Depuració

Mòdul 10: Temes Avançats

Mòdul 11: Desplegament i DevOps

Mòdul 12: Projectes del Món Real

© Copyright 2026. Tots els drets reservats