Tanques el Mòdul 4 amb una plataforma web completa —servidor, enrutador, estàtics, comandes, client HTTP— i sense ni una sola dependència externa. Va ser una decisió deliberada i ha tingut un valor pedagògic enorme: ara saps què hi ha a sota. Però també ha tingut un preu que has pagat a mà, línia a línia: compilar patrons de ruta, interpretar cossos, mantenir una taula de tipus MIME, calcular ETags.

Aquest preu no sempre val la pena pagar-lo. En un projecte real hi ha centenars de problemes ja resolts per altres persones, millor del que els resoldries tu en una tarda, i provats per milions d'instal·lacions. L'ofici consisteix a saber quan recolzar-se en aquesta feina i quan no, i per a això cal entendre la maquinària: npm.

Fins ara Escena Viva ha viscut sense package.json. S'executa amb node src/... i funciona. En aquesta lliçó això canvia: donem al projecte una identitat formal, un manifest que declara què és, amb quina versió de Node s'executa i —a partir de la lliçó següent— de què depèn.

Contingut

  1. Què és npm: dues coses amb el mateix nom
  2. L'ecosistema i les seves alternatives: yarn, pnpm, bun
  3. npm init: el manifest d'Escena Viva
  4. Els camps de package.json, un a un
  5. El package.json complet d'Escena Viva
  6. node_modules: què és i per què no es puja mai
  7. npm install sense arguments
  8. npx: executar sense instal·lar
  9. On viu la configuració: npm config i .npmrc

  1. Què és npm: dues coses amb el mateix nom

Quan algú diu "npm" pot estar parlant de dues coses diferents, i confondre-les genera malentesos constants.

El registre L'eina
Què és Un servidor públic de paquets a https://registry.npmjs.org El programa de línia d'ordres npm
Què fa Emmagatzema i serveix paquets publicats per qualsevol Descarrega, instal·la, versiona, publica i executa scripts
Se substitueix per Registres privats (Verdaccio, Artifactory, GitHub Packages) yarn, pnpm, bun
S'instal·la No, és un servei Ve inclòs amb Node.js

La segona fila és la important: el registre i l'eina són intercanviables per separat. Pots fer servir pnpm contra el registre públic, o npm contra un registre intern de la teva empresa. No estan casats.

Comprova que ja tens l'eina, perquè l'instal·lador de Node la va portar amb ell:

node -v     # v24.5.0
npm -v      # 11.x.y

Si fas servir nvm o fnm, cada versió de Node porta el seu propi npm. En canviar de versió de Node amb nvm use, canvies també de npm sense adonar-te'n. És normal i és el correcte.

Per què és l'ecosistema més gran del món

El registre públic supera els tres milions de paquets, més que qualsevol altre ecosistema de llenguatge. Les raons són estructurals:

  • JavaScript s'executa a tot arreu: navegador, servidor, mòbil, escriptori, funcions sense servidor. Un mateix registre serveix tots aquests mons.
  • Publicar és trivial: un package.json amb tres camps i npm publish. No hi ha cap comitè de revisió.
  • La biblioteca estàndard de JavaScript va ser històricament petita. On altres llenguatges porten de fàbrica gestió de dates o utilitats de col·leccions, JavaScript no ho feia, i el buit el va omplir el registre. D'aquí ve la seva fama de fragmentat i els paquets d'una sola funció. Avui el nucli de Node ha crescut molt —ho has comprovat en quatre mòduls— i moltes dependències clàssiques ja no calen.

El revers de "publicar és trivial" és que qualsevol pot publicar qualsevol cosa. Això converteix l'elecció de dependències en una decisió d'enginyeria, no en un tràmit: ho veurem a 05-02 amb una llista de comprovació i a 05-06 des de la seguretat.

  1. L'ecosistema i les seves alternatives: yarn, pnpm, bun

L'eina npm no és l'única que sap llegir un package.json i instal·lar dependències.

Eina Fitxer de bloqueig Estructura al disc Punt fort Punt feble
npm package-lock.json Arbre aplanat a node_modules Ve amb Node; zero instal·lació; universal Ni el més ràpid ni el més compacte
yarn (modern) yarn.lock Aplanat o Plug'n'Play sense node_modules Espais de treball madurs, PnP PnP trenca eines que assumeixen node_modules
pnpm pnpm-lock.yaml Magatzem global + enllaços durs Estalvi de disc brutal; estricte amb dependències no declarades Els enllaços confonen alguna eina antiga
bun bun.lock Aplanat, instal·lador propi Velocitat extrema; és també un runtime Ecosistema jove; compatibilitat no total

La idea de pnpm mereix un paràgraf perquè és genuïnament diferent. En comptes de copiar cada paquet dins del node_modules de cada projecte, desa una sola còpia de cada versió en un magatzem global de la teva màquina (~/.local/share/pnpm/store) i al projecte hi crea enllaços. Si tens deu projectes que fan servir [email protected], al disc hi ha un express, no deu: en un portàtil amb vint repositoris l'estalvi es mesura en gigabytes. A més pnpm és estricte: si el teu codi fa require('qualsevol-cosa') sense haver-ho declarat, falla. Amb npm sol funcionar per accident, perquè l'aplanament deixa aquesta dependència transitiva visible a l'arrel (05-02).

Per què aquest curs fa servir npm, tot i saber que hi ha opcions més ràpides: ve amb Node (zero instal·lació, zero divergència entre màquines); és el denominador comú que entenen tota la documentació i tots els sistemes d'integració contínua; i els conceptes són els mateixos —package.json, semver, lock, scripts, registre—, així que passar a pnpm són cinc minuts de taula d'equivalències.

Regla pràctica de convivència: una sola eina per projecte. Barrejar npm install i yarn add al mateix repositori genera dos fitxers de bloqueig contradictoris i hores de depuració inútil.

  1. npm init: el manifest d'Escena Viva

El package.json és un fitxer JSON a l'arrel del projecte que compleix quatre papers alhora: identitat (com es diu, quina versió té, qui el manté), contracte d'execució (quina versió de Node necessita, si és CommonJS o ESM, quin és el seu punt d'entrada), declaració de dependències (05-02 i 05-03) i interfície de tasques amb el camp scripts (05-04).

Crear-lo és una sola ordre. Des de l'arrel del projecte:

cd ~/escena-viva
npm init

npm init obre un qüestionari interactiu amb valors per defecte entre parèntesis; prémer Retorn accepta el proposat:

package name: (escena-viva)
version: (1.0.0) 0.1.0
description: Plataforma de venda d'entrades per a esdeveniments culturals
entry point: (index.js) src/servidor/servidor.js
test command:
git repository:
keywords: entrades,esdeveniments,teatre
author: Equip Escena Viva <[email protected]>
license: (ISC) MIT

Dos detalls: el nom per defecte és el de la carpeta —si la teva es diu Escena Viva, amb majúscules i espai, npm init protestarà per les regles de l'apartat següent—; i hi hem posat 0.1.0, no 1.0.0, perquè el valor per defecte de npm significa "API estable, prometo compatibilitat" i això és una mala promesa per a un projecte que comença. A 05-03 farem aquest salt conscientment.

Si vols saltar-te el qüestionari i acceptar tots els valors per defecte:

npm init -y      # equival a --yes

Genera un package.json mínim en un instant. És perfecte per a un laboratori d'usar i llençar, i sempre pots editar-lo després: package.json és un fitxer de text normal, no hi ha res màgic. De fet, editar-lo a mà és el més habitual un cop el projecte existeix.

  1. Els camps de package.json, un a un

name

L'identificador del paquet. Les seves regles són estrictes perquè acaba formant part d'una URL: màxim 214 caràcters, només minúscules (EscenaViva no val), sense espais —es fan servir guions: escena-viva—, no pot començar per . ni _, i ha de ser URL-safe: res d'accents, ñ ni ·.

Existeix una variant amb àmbit (scope), un prefix amb arrova: @escena-viva/format. L'àmbit és un espai de noms reservat per a una persona o organització, i té tres avantatges: evita col·lisions (@escena-viva/format és teu encara que format estigui agafat), agrupa paquets d'un mateix equip, i és privat per defecte en publicar, cosa que evita filtracions accidentals (05-05). Els veuràs constantment: @babel/core, @types/node, @eslint/js.

version

La versió actual del paquet en format semver: MAJOR.MENOR.PEDAÇ. És obligatòria per publicar i és l'eix de tota la lliçó 05-03. Per ara queda't amb la idea que 0.1.0 comunica "això encara es mou".

description i keywords

Text lliure i llista de paraules clau. Són metadades de cerca: alimenten el cercador de npmjs.com. En un paquet privat no serveixen per a res funcional, però description continua sent útil com a recordatori de què és aquest repositori.

main

El fitxer que es carrega quan algú fa require('escena-viva'). És el punt d'entrada de la biblioteca, no necessàriament l'executable. Si s'omet, Node busca index.js a l'arrel.

A Escena Viva apuntem a src/servidor/servidor.js, que exporta crearServidor sense arrencar res gràcies al require.main === module del Mòdul 4. És exactament el que es vol d'un punt d'entrada: importar no ha de tenir efectes secundaris.

El camp modern que substitueix main amb molt més control es diu exports, i el veurem a 05-05 en construir un paquet publicable.

type

Decideix com interpreta Node els fitxers .js d'aquest projecte:

Valor Els fitxers .js es llegeixen com require import
"commonjs" (per defecte) CommonJS Sí Només dinàmic, o en .mjs
"module" ES Modules No (fes servir .cjs) Sí

Al Mòdul 2 vam esmentar aquesta línia sense desenvolupar-la; ara ja té lloc on viure. Escena Viva declara "type": "commonjs" explícitament. És el valor per defecte, així que tècnicament sobra, però escriure'l elimina tota ambigüitat per a qui llegeixi el projecte i per a les eines.

engines

Declara quines versions de Node admet el projecte:

"engines": {
  "node": ">=24.5.0 <25"
}

Això ha de ser coherent amb el .nvmrc que vas crear al Mòdul 1, però són dos fitxers amb públics diferents: el .nvmrc el llegeixen nvm, fnm, Volta i la CI, i canvia la teva versió activa de Node; engines el llegeixen npm i les plataformes de desplegament, i avisa o falla si la versió no encaixa. Per defecte només avisa; perquè sigui un error real cal activar-ho al .npmrc de l'apartat 9.

private

"private": true

Un interruptor de seguretat: amb private: true, npm publish es nega a executar-se. Res més, i res menys.

Escena Viva és una aplicació, no una biblioteca: no ha d'acabar mai al registre públic. Posar private: true a tota aplicació és un costum barat que ha evitat moltes filtracions de codi propietari per un npm publish teclejat a la carpeta equivocada. Només es treu quan de debò vols publicar, que és el que farem a 05-05 amb el paquet @escena-viva/format.

license

Identificador SPDX de la llicència: MIT, Apache-2.0, GPL-3.0-only, ISC. Per a codi tancat, el valor convencional és:

"license": "UNLICENSED"

No és un camp decoratiu: a 05-06 veurem com s'auditen les llicències de tot l'arbre de dependències, i aquesta anàlisi es recolza justament en aquest camp.

author i repository

"author": "Equip Escena Viva <[email protected]>",
"repository": {
  "type": "git",
  "url": "git+https://github.com/escena-viva/escena-viva.git"
}

repository és més útil del que sembla: npm repo <paquet> obre aquesta URL, i les eines d'auditoria la fan servir per localitzar el codi font d'una dependència. Quan estiguis investigant si un paquet és de fiar, l'absència de repository ja és un senyal.

  1. El package.json complet d'Escena Viva

Aquest és el manifest amb què arrenquem el mòdul. Encara no té dependències —arriben a 05-02— ni scripts útils —arriben a 05-04—, i la seva versió és 0.1.0.

{
  "name": "escena-viva",
  "version": "0.1.0",
  "private": true,
  "description": "Plataforma de venda d'entrades per a esdeveniments culturals",
  "keywords": ["entrades", "esdeveniments", "teatre", "aforament"],
  "license": "MIT",
  "author": "Equip Escena Viva <[email protected]>",
  "type": "commonjs",
  "main": "src/servidor/servidor.js",
  "engines": {
    "node": ">=24.5.0 <25"
  },
  "repository": {
    "type": "git",
    "url": "git+https://github.com/escena-viva/escena-viva.git"
  },
  "scripts": {
    "start": "node src/servidor/servidor.js"
  }
}

Repassa el que diu aquest fitxer a qui el llegeixi per primera vegada, sense obrir res més: és una plataforma de venda d'entrades, versió primerenca, privada (no es publica), CommonJS, necessita Node 24, s'arrenca amb npm start i el seu codi viu en un repositori git conegut. Vuit línies de metadades que estalvien una conversa sencera.

Un avís: package.json és JSON estricte, sense comentaris, sense comes finals i amb cometes dobles. Si npm falla amb Unexpected token, gairebé sempre és una coma de més abans d'un }. Comprova que npm l'entén:

npm pkg get name version engines
{
  "name": "escena-viva",
  "version": "0.1.0",
  "engines": {
    "node": ">=24.5.0 <25"
  }
}

npm pkg get i npm pkg set llegeixen i escriuen camps sense obrir l'editor, respectant el format. Són la manera correcta de tocar el manifest des d'un script:

npm pkg set description="Venda d'entrades per a esdeveniments culturals"

  1. node_modules: què és i per què no es puja mai

node_modules és la carpeta on npm diposita el codi de les dependències descarregades. Encara no existeix a Escena Viva perquè no hi ha dependències, però convé entendre-la abans de crear-la.

Quan al Mòdul 2 vas estudiar la resolució de require, vas veure que Node, davant d'un require('alguna-cosa') sense ./, puja per l'arbre de directoris buscant node_modules/alguna-cosa a cada nivell. npm és simplement qui omple aquestes carpetes: escriu fitxers on Node ja sabia mirar, sense màgia addicional. I és una carpeta enorme: un projecte Express modest ronda els 40.000 fitxers.

No es puja mai al control de versions. Les raons, per ordre d'importància:

Raó Explicació
És reproduïble package.json + package-lock.json basten per reconstruir-la idèntica. Desar el resultat a més de l'origen és redundant.
Mida i soroll Desenes de milers de fitxers converteixen cada git status i cada revisió de codi en una cosa inabastable.
Contingut binari i per plataforma Alguns paquets compilen binaris natius per al teu sistema operatiu i arquitectura. El que funciona al teu macOS pot no arrencar al Linux del servidor.
Conflictes impossibles Un conflicte de fusió dins de node_modules no es resol; s'esborra i es reinstal·la.

Per això el .gitignore que vas crear al Mòdul 1 ja començava per aquesta línia:

node_modules/
.env
informes/*.csv
*.log

La primera línia és la crítica. La segona també ho serà a partir de la lliçó vinent, quan dotenv entri en joc. I compte amb l'asimetria, que és la font de confusió més comuna del mòdul:

  • node_modules/ → s'ignora (és el resultat).
  • package.json i package-lock.json → es pugen sempre (són la font).

  1. npm install sense arguments

Executat sense nom de paquet, npm install (o el seu àlies npm i) significa: "posa aquest projecte en condicions d'executar-se". És el primer que tecleja qualsevol després de clonar un repositori.

Els seus passos exactes, en ordre: llegeix package.json i reuneix dependencies i devDependencies; llegeix package-lock.json si existeix, per conèixer l'arbre ja resolt; compara amb el que hi ha instal·lat i calcula què falta o què sobra; descarrega del registre allò que falti, fent servir la memòria cau local si el té; verifica la integritat de cada paquet amb el seu hash (integrity); extreu a node_modules aplanant l'arbre; enllaça els executables a node_modules/.bin (clau per a 05-04); executa els scripts d'instal·lació dels paquets que en tinguin (postinstall — atenció, 05-06); i finalment actualitza package-lock.json si va caldre resoldre alguna cosa nova.

Aquest últim pas és la diferència essencial amb npm ci, i li dedicarem una taula sencera a 05-03: npm install pot modificar el lock; npm ci no el toca mai.

A Escena Viva, avui, el resultat és anticlimàtic i didàctic:

npm install
up to date, audited 1 package in 231ms

found 0 vulnerabilities

"1 package" és el projecte mateix. Zero dependències, zero vulnerabilitats: l'estat més segur possible, i el punt de partida contra el qual compararem tot el que hi afegim.

  1. npx: executar sense instal·lar

Hi ha dues maneres de fer servir una eina de línia d'ordres publicada a npm.

La forma antiga, instal·lació global:

npm install -g cowsay      # s'instal·la al teu sistema, fora del projecte
cowsay "Hola Escena Viva"

La forma recomanable, npx:

npx cowsay "Hola Escena Viva"

npx busca en aquest ordre: si l'executable existeix a node_modules/.bin del projecte, el fa servir; si és a la memòria cau de npx, el fa servir; i si no, el descarrega a una memòria cau temporal, l'executa i no l'instal·la al projecte.

Instal·lació global (-g) npx
On queda Al teu sistema, per sempre A la memòria cau; no embruta el projecte
Versió La que vas instal·lar fa mesos La declarada pel projecte, o l'última
Coherència en equip Cadascú té la seva Tothom fa servir la mateixa
Ús ideal Eines d'ús diari alienes als projectes Gairebé tota la resta

El problema real de -g no és l'espai al disc, és la deriva de versions: tu generes un projecte amb la versió global que vas instal·lar al març i el teu company amb la que va instal·lar ahir, i els resultats difereixen sense que ningú entengui per què.

Pots fixar la versió, que és el que s'aconsella a la documentació i a la CI:

npx create-express-app@latest la-meva-app
npx eslint@9 src

I el punt que tanca el cercle: si el projecte declara una eina a devDependencies, npx eslint fa servir aquesta còpia local, sense descarregar res. Aquesta és la raó per la qual a 05-04 podrem escriure "lint": "eslint src" als scripts sense instal·lar ESLint globalment.

  1. On viu la configuració: npm config i .npmrc

npm es configura per capes. Per veure el resultat efectiu:

npm config list
; "user" config from /home/usuari/.npmrc
init-author-name = "Equip Escena Viva"

; node bin location = /home/usuari/.nvm/versions/node/v24.5.0/bin/node
; cwd = /home/usuari/escena-viva
; npm version = 11.4.2

Amb npm config list -l veuràs a més tots els valors per defecte. Les capes s'apliquen en aquest ordre, de major a menor prioritat:

Capa Ubicació Ús típic
Línia d'ordres --registry=... Una execució concreta
Variables d'entorn NPM_CONFIG_REGISTRY CI i contenidors
.npmrc de projecte ./.npmrc Es puja al repo: política de l'equip
.npmrc d'usuari ~/.npmrc No es puja: els teus tokens
.npmrc global Al costat de la instal·lació de npm Poques vegades es toca
Valors per defecte Integrats —

El .npmrc de projecte d'Escena Viva, que sí que va al repositori:

# Falla la installacio si la versio de Node no compleix "engines"
engine-strict=true

# En usar "npm install <paquet>", desa un rang exacte en comptes de "^"
# (ho justificarem a 05-03; de moment queda anotat)
save-exact=false

# Registre per defecte, explicit perque ningu en dubti
registry=https://registry.npmjs.org/

engine-strict=true converteix l'avís d'engines en un error: si algú intenta instal·lar el projecte amb Node 22, npm es planta. Combinat amb .nvmrc, la versió de Node deixa de ser una convenció de passadís i passa a ser una regla verificada.

I l'advertència més important de l'apartat: el .npmrc d'usuari (~/.npmrc) conté els teus tokens d'autenticació, en línies de l'estil //registry.npmjs.org/:_authToken=npm_xxxxxxxx. Aquest fitxer no es puja mai enlloc: un token filtrat en un repositori públic permet a qualsevol publicar paquets en el teu nom (05-05 i 05-06).

Finalment, el registre per defecte és https://registry.npmjs.org/. Canviar-lo té dos casos d'ús legítims: un mirall intern d'empresa i un registre privat per a paquets propietaris, normalment combinat amb àmbits:

# Nomes els paquets @escena-viva/* van al registre intern
@escena-viva:registry=https://registre.intern.test/

Errors Comuns i Consells

  • Executar npm init a la carpeta equivocada. Comprova-ho amb pwd abans. Si t'equivoques, esborra el package.json creat: un manifest orfe a la teva carpeta personal fa que npm tracti tota aquella carpeta com un projecte.
  • Un package.json invàlid. Sense comentaris, sense comes finals, amb cometes dobles. Valida-ho ràpid amb node -e "require('./package.json')": si no imprimeix cap error, és JSON correcte.
  • Confondre main amb "el fitxer que arrenca l'aplicació". main és el que s'obté en importar el paquet; el que arrenca l'aplicació és scripts.start. Que aquí coincideixin és una comoditat, no una regla.
  • Pujar node_modules per oblidar el .gitignore. Si ja ho has pujat: git rm -r --cached node_modules, afegeix la línia i confirma. L'historial continuarà pesant, però el mal deixa de créixer.
  • Instal·lar eines amb -g per costum. Cada -g és una versió que només existeix a la teva màquina. Fes servir npx, o declara-la a devDependencies.
  • Consell: npm init -y seguit de npm pkg set. Més ràpid que el qüestionari i automatitzable en una plantilla de projecte. I fes servir npm pkg get en comptes de llegir el fitxer amb grep: retorna JSON vàlid i no es trenca amb canvis de format.

Exercicis

Exercici 1. Crear el manifest d'Escena Viva. Des de l'arrel del projecte, executa npm init i respon el qüestionari per produir exactament el package.json de l'apartat 5: nom escena-viva, versió 0.1.0, llicència MIT, punt d'entrada src/servidor/servidor.js. Després afegeix a mà private, type i engines. Verifica-ho amb npm pkg get i comprova que npm start arrenca el servidor del Mòdul 4.

Exercici 2. Comprovar que engine-strict funciona. Crea el .npmrc de projecte amb engine-strict=true. Canvia temporalment engines.node a ">=99.0.0" i executa npm install. Observa l'error exacte. Després treu engine-strict i repeteix: què canvia? Deixa el fitxer com estava.

Exercici 3. npx davant de -g. Sense instal·lar res globalment, executa npx [email protected] "Aforament 3000" i anota què imprimeix npx la primera vegada i què imprimeix la segona. Després busca on queda la memòria cau amb npm config get cache i explica en dues frases per què npx dona resultats més reproduïbles en un equip que una instal·lació global.

Solucions

Solució 1. Després del qüestionari, el fitxer generat no inclou private, type ni engines; s'afegeixen a mà o amb npm pkg:

npm pkg set private=true --json
npm pkg set type="commonjs"
npm pkg set engines.node=">=24.5.0 <25"
npm pkg set scripts.start="node src/servidor/servidor.js"

El --json de la primera línia és imprescindible: sense ell, private es desaria com la cadena "true" i no com el booleà true, i npm no ho interpretaria com un interruptor. És l'error més freqüent amb npm pkg set.

Després, npm start ha d'arrencar el servidor exactament igual que node src/servidor/servidor.js, perquè literalment és això el que executa.

Solució 2. Amb engine-strict=true i un engines.node impossible:

npm error code EBADENGINE
npm error engine Unsupported engine
npm error engine Not compatible with your version of node/npm: [email protected]
npm error notsup Required: {"node":">=99.0.0"}
npm error notsup Actual:   {"npm":"11.4.2","node":"v24.5.0"}

La instal·lació s'atura amb un codi de sortida diferent de zero. Sense engine-strict, el mateix cas produeix només un npm warn EBADENGINE i la instal·lació continua. La diferència importa sobretot a la CI del Mòdul 11: un avís passa desapercebut en un registre de milers de línies; una fallada atura el desplegament.

Solució 3. La primera execució descarrega el paquet i ho anuncia:

Need to install the following packages:
[email protected]
Ok to proceed? (y)

La segona el troba a la memòria cau i s'executa a l'instant, sense preguntar. La memòria cau viu on digui npm config get cache (~/.npm/_npx per als executables temporals).

La reproduïbilitat ve de dues coses: npx paquet@versio fixa la versió a la mateixa ordre, de manera que la mateixa ordre produeix el mateix resultat en qualsevol màquina; i quan el projecte declara l'eina a devDependencies, npx fa servir la còpia local del projecte, que està fixada al package-lock.json i és idèntica per a tot l'equip. Una instal·lació global no ofereix cap de les dues garanties: depèn de quan va instal·lar cada persona.

Conclusió

Escena Viva ja té manifest. Has vist que npm són dues coses: un registre públic amb més de tres milions de paquets i una eina de línia d'ordres que ve inclosa amb Node, i que totes dues es poden substituir per separat —el curs fa servir npm per ubiqüitat, sabent que pnpm estalvia disc amb el seu magatzem global i enllaços, i que yarn i bun juguen la mateixa partida amb altres regles.

El package.json que has creat compleix els quatre papers de l'apartat 3: identitat (name, version, description, author, repository), contracte d'execució (type: commonjs, main, engines coherent amb el .nvmrc del Mòdul 1), i els dos buits que omplirem de seguida: dependències i scripts. I porta private: true, l'interruptor barat que impedeix que una aplicació acabi publicada per accident.

Saps també que node_modules és només el lloc on npm diposita allò que Node ja sabia buscar des del Mòdul 2, que no es puja mai al repositori perquè és reproduïble a partir de package.json i del lock, i que npm install sense arguments executa nou passos molt concrets —dels quals l'últim, tocar el lock, és justament el que npm ci no fa—. Que npx executa eines sense instal·lar-les i evita la deriva de versions que provoca el -g. I que la configuració viu en capes, amb un .npmrc de projecte que es puja (engine-strict=true) i un d'usuari que conté els teus tokens i no es puja mai.

A la lliçó següent, Instal·lació i Ús de Paquets, trenquem per fi la ratxa de zero dependències: instal·larem les primeres, distingirem dependencies de devDependencies i per què aquesta distinció canvia la mida i la seguretat del que desplegues, i —més important que qualsevol ordre— construirem una llista de comprovació per decidir si una dependència mereix entrar al projecte. Perquè després d'escriure un mòdul sencer sense cap, ja saps que la resposta no sempre és que sí.

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