A la lliçó anterior vas seguir un cicle que coneixes bé: escriure codi, desar, executar node src/cataleg.js, llegir la sortida, corregir, repetir. Aquest cicle és correcte per construir un programa, però és lentíssim quan el que vols és respondre una pregunta petita: com es comporta reduce amb aquest array?, què retorna exactament Object.entries sobre una sessió?, quant suma l'aforament total de l'Auditorio Ribera?
Per a això existeix el REPL: un intèrpret interactiu on escrius una expressió i en veus el resultat a l'instant. És una de les eines més infravalorades de l'ecosistema i, ben feta servir, estalvia hores. En aquesta lliçó aprendràs a manejar-lo amb solvència i a explorar en directe les dades d'Escena Viva abans d'escriure-les en un script.
Contingut
- Què és un REPL i per a què serveix
- Arrencar el REPL i avaluar expressions
- La variable
_i el resultat de les declaracions - Autocompletat, historial i navegació
- Les ordres de punt
- Carregar el catàleg d'Escena Viva al REPL
- Explorar i transformar les dades en directe
- El mode
.editorper a funcions de diverses línies - Executar codi solt sense REPL:
node -einode -p - Peculiaritats: promeses,
awaitde nivell superior i altres sorpreses - Quan fer servir el REPL i quan no
- Què és un REPL i per a què serveix
REPL són les sigles de Read-Eval-Print-Loop: llegir, avaluar, imprimir i repetir. És un bucle que:
- Llegeix (Read) el que escrius.
- Ho avalua (Eval) com a codi JavaScript.
- Imprimeix (Print) el resultat.
- Repeteix (Loop) esperant la línia següent.
flowchart LR
R["Read<br/>llegeix la teva línia"] --> E["Eval<br/>executa el codi"]
E --> P["Print<br/>mostra el resultat"]
P --> L["Loop<br/>espera la següent"]
L --> R
No és una peculiaritat de Node: la consola del navegador és un REPL, i també ho són python, irb o psql. El seu valor és el cost zero de l'experiment: provar una cosa no requereix crear fitxers ni recordar rutes.
Usos reals del dia a dia:
- Comprovar el comportament exacte d'un mètode d'array que no fas servir sovint.
- Verificar una expressió regular abans de ficar-la al codi.
- Explorar la forma d'unes dades que acabes de rebre.
- Convertir valors ràpidament (dates, cèntims a euros, bytes a megabytes).
- Comprovar què exporta un mòdul instal·lat, sense llegir-ne la documentació.
- Arrencar el REPL i avaluar expressions
Escriu node sense arguments:
El símbol > indica que el REPL espera una línia. Prova:
> 2 + 2 4 > 'Teatro' + ' ' + 'Almendra' 'Teatro Almendra' > [1, 2, 3].map((n) => n * 10) [ 10, 20, 30 ] > Math.round(2500 / 100) 25
El REPL manté l'estat entre línies: les variables que declares continuen existint.
> const sala = 'Auditorio Ribera' undefined > sala.toUpperCase() 'AUDITORIO RIBERA' > sala.length 16
També funciona amb codi de diverses línies: si una línia està incompleta, el símbol canvia a ... i el REPL espera que tanquis.
> const sessio = {
... id: 'ses-001-1',
... aforament: 420,
... venudes: 180
... }
undefined
> sessio.aforament - sessio.venudes
240Per sortir: .exit, o Ctrl+D, o Ctrl+C dues vegades.
- La variable
_ i el resultat de les declaracions
_ i el resultat de les declaracionsEl resultat undefined de les declaracions
Deus haver notat una cosa desconcertant: en escriure const sala = 'Auditorio Ribera' el REPL ha respost undefined. No és un error. El REPL imprimeix el valor de l'expressió avaluada, i en JavaScript una declaració de variable no produeix cap valor: produeix undefined.
> const preu = 2500 undefined > preu // Ara si, aixo es una expressio que val 2500 2500 > let x = 10; x // Truc: separar amb ";" per veure el valor 10
El mateix passa amb function, class, bucles i console.log (que retorna undefined després d'imprimir):
La primera línia és el que imprimeix console.log; la segona és el seu valor de retorn. Amb el temps deixes de veure-ho.
La variable _
_ guarda el resultat de l'última expressió avaluada. És comodíssim per encadenar exploracions sense declarar variables intermèdies.
Hi ha una variable germana, _error, que guarda l'últim error llançat:
> JSON.parse('{ aixo no es json }')
Uncaught SyntaxError: Expected property name or '}' in JSON at position 2
> _error.message
"Expected property name or '}' in JSON at position 2"Compte: si assignes manualment
_ = 5, perds aquesta funcionalitat en aquella sessió (el REPL t'avisa). Evita fer servir_com a nom de variable pròpia.
- Autocompletat, historial i navegació
Aquestes tecles converteixen el REPL en una cosa realment ràpida:
| Tecla | Efecte |
|---|---|
Tab |
Autocompleta. Si hi ha diverses opcions, prem-la dues vegades per llistar-les |
↑ / ↓ |
Recorre l'historial d'ordres |
Ctrl+R |
Cerca inversa a l'historial (escriu part de l'ordre) |
Ctrl+A / Ctrl+E |
Anar al principi / final de la línia |
Ctrl+U |
Esborrar la línia sencera |
Ctrl+L |
Netejar la pantalla |
Ctrl+C |
Cancel·lar la línia actual (dues vegades: sortir) |
Ctrl+D |
Sortir |
L'autocompletat és la joia. Escriu un objecte i un punt, i prem Tab:
> const sessio = { id: 'ses-001-1', aforament: 420, venudes: 180 }
undefined
> sessio.
sessio.__proto__ sessio.constructor sessio.hasOwnProperty
...
sessio.aforament sessio.id sessio.venudesTambé funciona amb mòduls interns, cosa que el converteix en una documentació instantània:
> const path = require('node:path')
undefined
> path.
path.basename path.dirname path.extname path.join
path.normalize path.parse path.relative path.resolveL'historial es conserva entre sessions al fitxer ~/.node_repl_history. Pots tancar el REPL, obrir-lo demà i recuperar amb ↑ el que has provat avui.
- Les ordres de punt
Tot el que comença per . al REPL és una ordre del mateix REPL, no JavaScript.
| Ordre | Què fa |
|---|---|
.help |
Llista totes les ordres disponibles |
.break |
Abandona una expressió multilínia a mitges (àlies: Ctrl+C) |
.clear |
Reinicia el context: esborra totes les teves variables |
.editor |
Entra en mode editor multilínia |
.exit |
Surt del REPL |
.load <fitxer> |
Carrega i avalua un fitxer a la sessió actual |
.save <fitxer> |
Desa en un fitxer tot el que has escrit a la sessió |
Exemple del cicle complet .load / .save:
.save escriu totes les línies que has teclejat (no els resultats). És una manera còmoda de rescatar una exploració que ha sortit bé i convertir-la en el punt de partida d'un script.
.break et salva de l'embús clàssic:
Sense .break (o Ctrl+C), el REPL es queda esperant eternament el tancament de la clau.
.clear mereix un avís: reinicia el context i perds totes les variables definides. Fes-lo servir quan vulguis començar de zero, no per error.
- Carregar el catàleg d'Escena Viva al REPL
Aquí hi ha l'aplicació pràctica de .load. Prepararem un fitxer que contingui només les dades, sense la part de presentació ni el filtratge per arguments, per poder carregar-lo netament al REPL.
Crea src/cataleg-dades.js:
// src/cataleg-dades.js
// Nomes les dades del cataleg, sense logica de presentacio.
// Al modul 2 hi afegirem module.exports per poder reutilitzar-lo
// des d'altres fitxers; de moment serveix per carregar-lo al REPL amb .load
const cataleg = [
{
id: 'evt-001',
titol: 'Concierto de Otono',
sala: 'Teatro Almendra',
categoria: 'concert',
duracioMinuts: 95,
sessions: [
{ id: 'ses-001-1', dataHora: '2026-10-03T20:00:00', aforament: 420, venudes: 180, preuCentims: 2500 },
{ id: 'ses-001-2', dataHora: '2026-10-04T19:00:00', aforament: 420, venudes: 96, preuCentims: 2200 }
]
},
{
id: 'evt-002',
titol: 'Noche de Monologos',
sala: 'Sala Boveda',
categoria: 'humor',
duracioMinuts: 80,
sessions: [
{ id: 'ses-002-1', dataHora: '2026-10-10T21:30:00', aforament: 120, venudes: 118, preuCentims: 1800 },
{ id: 'ses-002-2', dataHora: '2026-10-11T21:30:00', aforament: 120, venudes: 45, preuCentims: 1800 },
{ id: 'ses-002-3', dataHora: '2026-10-17T21:30:00', aforament: 120, venudes: 12, preuCentims: 1500 }
]
},
{
id: 'evt-003',
titol: 'Festival de Jazz de Primavera',
sala: 'Auditorio Ribera',
categoria: 'festival',
duracioMinuts: 240,
sessions: [
{ id: 'ses-003-1', dataHora: '2027-04-17T19:00:00', aforament: 900, venudes: 640, preuCentims: 3800 },
{ id: 'ses-003-2', dataHora: '2027-04-18T19:00:00', aforament: 900, venudes: 720, preuCentims: 4200 }
]
}
];Ara, des de l'arrel del projecte:
El REPL mostra el contingut del fitxer mentre l'avalua línia a línia. En acabar, la constant cataleg existeix a la teva sessió:
Punt important:
.loadno és el mateix querequire..loadcopia i avalua el text del fitxer dins del context del REPL, com si l'haguessis teclejat.requirecarrega un mòdul aïllat i només et dona el que aquell mòdul exporta. Per això.loadfunciona encara que el fitxer no exporti res, i per això és l'eina ideal per explorar. Els mòduls de debò arriben al Mòdul 2.
- Explorar i transformar les dades en directe
Amb el catàleg carregat, comença el que és divertit: provar transformacions abans d'escriure-les a l'script.
Veure la forma de les dades
> cataleg.map((e) => e.titol) [ 'Concierto de Otono', 'Noche de Monologos', 'Festival de Jazz de Primavera' ] > cataleg[1].sessions.length 3
Per inspeccionar un objecte imbricat sense que Node el retalli amb [Object]:
filter: quedar-se amb part del catàleg
> cataleg.filter((e) => e.sala === 'Sala Boveda').map((e) => e.titol) [ 'Noche de Monologos' ] > cataleg.filter((e) => e.duracioMinuts > 90).map((e) => e.titol) [ 'Concierto de Otono', 'Festival de Jazz de Primavera' ]
flatMap: aplanar totes les sessions
Les sessions estan imbricades dins de cada esdeveniment. Per treballar amb totes alhora:
I si necessitem saber a quin esdeveniment pertany cadascuna, afegim la dada en aplanar:
> const sessions = cataleg.flatMap((e) => e.sessions.map((s) => ({ ...s, esdeveniment: e.titol, sala: e.sala })))
undefined
> sessions[0]
{
id: 'ses-001-1',
dataHora: '2026-10-03T20:00:00',
aforament: 420,
venudes: 180,
preuCentims: 2500,
esdeveniment: 'Concierto de Otono',
sala: 'Teatro Almendra'
}L'operador ... (propagació) copia totes les propietats de l'objecte original i hi afegeix les noves. L'estudiarem formalment a la lliçó següent.
reduce: totals de negoci
> sessions.reduce((suma, s) => suma + s.aforament, 0) 3000 > sessions.reduce((suma, s) => suma + s.venudes, 0) 1811 > const ingressos = sessions.reduce((suma, s) => suma + s.venudes * s.preuCentims, 0) undefined > ingressos 6428600 > ingressos / 100 64286
Seixanta-quatre mil dos-cents vuitanta-sis euros de recaptació acumulada. Aquest és exactament el tipus de pregunta que respons en vint segons al REPL i que trigaries cinc minuts a programar, desar i executar.
sort i find
> sessions.filter((s) => s.sala === 'Auditorio Ribera').map((s) => s.id)
[ 'ses-003-1', 'ses-003-2' ]
> [...sessions].sort((a, b) => b.preuCentims - a.preuCentims)[0].id
'ses-003-2'
> sessions.find((s) => s.venudes / s.aforament < 0.2)
{ id: 'ses-002-3', ... }Fixa't en el [...sessions] abans de sort: sort modifica l'array original. Copiar-lo primer evita alterar les dades que estàs explorant. És un error clàssic que el REPL t'ajuda a descobrir.
Ocupació per sala
> const perSala = {}
undefined
> for (const s of sessions) { perSala[s.sala] = (perSala[s.sala] ?? 0) + s.venudes }
undefined
> perSala
{ 'Teatro Almendra': 276, 'Sala Boveda': 175, 'Auditorio Ribera': 1360 }
> console.table(perSala)L'operador ?? retorna el valor de la dreta només si el de l'esquerra és null o undefined. El veurem en detall a la lliçó vinent.
- El mode
.editor per a funcions de diverses línies
.editor per a funcions de diverses líniesEscriure una funció de deu línies al REPL línia a línia és incòmode: si t'equivoques a la tercera, no pots tornar enrere. Per a això hi ha .editor.
> .editor
// Entering editor mode (Ctrl+D to finish, Ctrl+C to cancel)
function resumSala(esdeveniments, sala) {
const sessions = esdeveniments
.filter((esdeveniment) => esdeveniment.sala === sala)
.flatMap((esdeveniment) => esdeveniment.sessions);
const aforament = sessions.reduce((total, s) => total + s.aforament, 0);
const venudes = sessions.reduce((total, s) => total + s.venudes, 0);
return {
sala,
sessions: sessions.length,
aforament,
venudes,
ocupacio: `${Math.round((venudes / aforament) * 100)}%`
};
}Prem Ctrl+D per sortir del mode editor i avaluar tot el bloc de cop. Després prova-la:
> resumSala(cataleg, 'Teatro Almendra')
{ sala: 'Teatro Almendra', sessions: 2, aforament: 840, venudes: 276, ocupacio: '33%' }
> ['Teatro Almendra', 'Sala Boveda', 'Auditorio Ribera'].map((s) => resumSala(cataleg, s))> console.table(['Teatro Almendra', 'Sala Boveda', 'Auditorio Ribera'].map((s) => resumSala(cataleg, s))) ┌─────────┬────────────────────┬──────────┬───────────┬─────────┬──────────┐ │ (index) │ sala │ sessions │ aforament │ venudes │ ocupacio │ ├─────────┼────────────────────┼──────────┼───────────┼─────────┼──────────┤ │ 0 │ 'Teatro Almendra' │ 2 │ 840 │ 276 │ '33%' │ │ 1 │ 'Sala Boveda' │ 3 │ 360 │ 175 │ '49%' │ │ 2 │ 'Auditorio Ribera' │ 2 │ 1800 │ 1360 │ '76%' │ └─────────┴────────────────────┴──────────┴───────────┴─────────┴──────────┘
Quan la funció funciona, .save informes/exploracio.js desa la sessió i ja tens el codi a punt per enganxar-lo a src/.
Ctrl+Dacaba,Ctrl+Ccancel·la. Confondre'ls fa perdre el bloc sencer. A Windows, siCtrl+Dno respon, prova ambCtrl+Zseguit d'Enter.
- Executar codi solt sense REPL:
node -e i node -p
node -e i node -pDe vegades només vols una resposta i no una sessió interactiva. Node accepta codi directament des de la línia d'ordres.
| Opció | Significat | Imprimeix el resultat |
|---|---|---|
node -e "codi" |
evaluate: executa el codi | No (fes servir console.log) |
node -p "codi" |
print: executa i imprimeix el valor | Sí, automàticament |
# -e: cal imprimir explicitament
node -e "console.log(2 + 2)"
# 4
# -p: imprimeix el valor de l'expressio
node -p "2 + 2"
# 4
# Consultar la versio des d'un script de desplegament
node -p "process.version"
# v24.5.0
# Comprovar si un paquet esta installat i quina versio te
node -p "require('express/package.json').version"Un cas molt pràctic: processar un fitxer JSON des del terminal sense instal·lar eines addicionals.
# Quants esdeveniments hi ha al fitxer llavor
node -p "require('./dades/esdeveniments.json').length"
# Titols dels esdeveniments, un per linia
node -e "require('./dades/esdeveniments.json').forEach(e => console.log(e.titol))"Node sap llegir un .json amb require i retornar-lo ja convertit en objecte. Aquest truc et resoldrà moltes comprovacions ràpides a partir del Mòdul 3, quan el fitxer dades/esdeveniments.json sigui la font real del catàleg.
També pots encadenar el REPL amb una canonada, encara que en aquest cas no veuràs el símbol >:
- Peculiaritats: promeses,
await de nivell superior i altres sorpreses
await de nivell superior i altres sorpresesPromeses i await
El REPL de Node admet await al nivell superior, cosa que en un fitxer .js de tipus CommonJS no es pot fer. Això el converteix en un banc de proves excel·lent per a codi asíncron (tema del Mòdul 2).
> const fs = require('node:fs/promises')
undefined
> const text = await fs.readFile('src/cataleg-dades.js', 'utf8')
undefined
> text.length
1893Si no fas servir await, el REPL et mostra la promesa, no el seu valor:
Poc després el REPL imprimeix el resultat resolt pel seu compte, cosa que pot semblar que «apareix del no-res». No t'alarmis: és el REPL informant que la promesa s'ha resolt.
Altres peculiaritats que convé conèixer
| Situació | Què passa | Per què |
|---|---|---|
{ a: 1 } retorna 1 |
El REPL interpreta {} com un bloc, no com un objecte |
Embolcalla'l entre parèntesis: ({ a: 1 }) |
let x = 1 dues vegades dona error |
Redeclaració al mateix àmbit | Fes servir var, o .clear, o canvia de nom |
Un array llarg es retalla amb ... 73 more items |
Límit d'impressió de l'inspector | console.dir(arr, { maxArrayLength: null }) |
Els objectes profunds mostren [Object] |
Profunditat d'inspecció per defecte: 2 | console.dir(obj, { depth: null }) |
El REPL no veu les variables d'un fitxer carregat amb require |
require aïlla el mòdul |
Fes servir .load per explorar |
| Un error no tanca el REPL | Els errors es capturen i es mostren | És intencionat: pots continuar treballant |
Prova tu mateix la primera:
> { titol: 'Concierto de Otono' }
'Concierto de Otono'
> ({ titol: 'Concierto de Otono' })
{ titol: 'Concierto de Otono' }En el primer cas, JavaScript llegeix { com a inici de bloc i titol: com una etiqueta; el valor del bloc és l'última expressió. Amb parèntesis, es força la interpretació com a objecte literal.
- Quan fer servir el REPL i quan no
El REPL és una eina d'exploració, no de construcció. Aquesta taula resumeix l'elecció correcta:
| Necessitat | Eina adequada |
|---|---|
| Comprovar què retorna una expressió | REPL |
| Explorar la forma d'unes dades desconegudes | REPL (.load + console.dir) |
| Provar una transformació abans d'escriure-la | REPL o .editor |
| Consultar l'API d'un mòdul | REPL + Tab |
| Una comprovació puntual des d'un script de shell | node -p |
| Codi que s'ha de repetir o versionar | Un fitxer a src/ |
| Lògica de més de 30 línies | Un fitxer, encara que l'hagis prototipada al REPL |
| Entendre per què falla un programa complex en un punt concret | El depurador (Mòdul 9) |
| Garantir que una cosa continua funcionant demà | Proves automatitzades (Mòdul 9) |
La regla és senzilla: si necessitaràs el resultat més d'una vegada, no pertany al REPL. Prototipa al REPL, desa amb .save, refina en un fitxer.
I sobre el depurador: el REPL et diu què fa una expressió aïllada; el depurador et deixa aturar un programa en marxa, a la línia que vulguis, i inspeccionar-ne totes les variables en aquell instant. Són complementaris, no alternatius.
Errors Comuns i Consells
Error 1: alarmar-se pel undefined després de cada declaració.
És el valor de l'expressió, no una errada. const x = 5 no produeix cap valor.
Error 2: escriure { clau: valor } esperant un objecte.
El REPL ho llegeix com un bloc. Embolcalla'l entre parèntesis.
Error 3: quedar-se atrapat al símbol ....
Has deixat una clau, un parèntesi o una cometa sense tancar. Surt-ne amb .break o Ctrl+C.
Error 4: confondre .load amb require.
.load avalua el text a la teva sessió (veus totes les variables). require retorna només el que s'ha exportat.
Error 5: fer servir .clear sense voler.
Esborra totes les variables de la sessió. Si has invertit temps a carregar i transformar dades, primer .save.
Error 6: ordenar amb sort i espatllar l'array original.
sort, reverse, splice, push i pop modifiquen l'array. Copia amb [...array] abans d'ordenar.
Consell 1: fes servir _ sense por. Encadenar _ és la manera més ràpida de refinar un càlcul pas a pas.
Consell 2: .save en acabar una exploració productiva. Desar a informes/ la sessió t'estalvia reconstruir el raonament demà.
Consell 3: el Tab és la teva documentació. Abans de buscar a internet quins mètodes té path, escriu path. i prem Tab dues vegades.
Consell 4: mantén un REPL obert en una pestanya del terminal. Amb el catàleg carregat, resoldre dubtes costa segons.
Exercicis
Exercici 1: exploració guiada del catàleg
Obre el REPL, carrega src/cataleg-dades.js amb .load i respon aquestes preguntes fent servir una sola expressió cada vegada. Anota l'ordre i el resultat.
- Quantes sessions hi ha en total al catàleg?
- Quin és el preu mitjà d'una entrada, en euros?
- Quins esdeveniments tenen més de dues sessions?
- Quantes entrades queden sense vendre a tot el catàleg?
- Quina és la sessió més cara i a quin esdeveniment pertany?
Exercici 2: funció en mode editor
Fent servir .editor, escriu una funció sessionsPerMes(esdeveniments) que retorni un objecte on cada clau sigui el mes en format AAAA-MM i el valor el nombre de sessions programades aquell mes. Prova-la amb el catàleg i mostra'n el resultat amb console.table. Després desa la sessió a informes/exploracio-mesos.js amb .save.
Pista: sessio.dataHora és una cadena ISO com '2026-10-03T20:00:00', així que el mes es pot extreure amb slice(0, 7).
Exercici 3: comprovacions des del terminal
Sense obrir el REPL, escriu les ordres node -e o node -p que resolguin el següent:
- Imprimir la versió major de Node instal·lada (només el número, per exemple
24). - Imprimir quants mil·lisegons falten des d'ara fins al
Concierto de Otono(2026-10-03T20:00:00). - Convertir
4200cèntims a la cadena'42.00'. - Comprovar si la carpeta
informesexisteix al projecte (imprimirtrueofalse).
Solucions
Solució 1
> .load src/cataleg-dades.js # 1. Total de sessions > cataleg.reduce((total, e) => total + e.sessions.length, 0) 7 # 2. Preu mitja en euros > cataleg.flatMap(e => e.sessions).reduce((s, x, i, a) => s + x.preuCentims / a.length, 0) / 100 25.428571428571427
Alternativa més llegible, en dos passos amb _:
> cataleg.flatMap(e => e.sessions).map(s => s.preuCentims) [ 2500, 2200, 1800, 1800, 1500, 3800, 4200 ] > _.reduce((a, b) => a + b, 0) / _.length / 100 25.428571428571427
(17.800 cèntims entre 7 sessions = 2.542,86 cèntims, és a dir 25,43 EUR.)
# 3. Esdeveniments amb mes de dues sessions
> cataleg.filter(e => e.sessions.length > 2).map(e => e.titol)
[ 'Noche de Monologos' ]
# 4. Entrades sense vendre
> cataleg.flatMap(e => e.sessions).reduce((t, s) => t + (s.aforament - s.venudes), 0)
1189
# 5. Sessio mes cara i el seu esdeveniment
> cataleg.flatMap(e => e.sessions.map(s => ({ ...s, esdeveniment: e.titol })))
.sort((a, b) => b.preuCentims - a.preuCentims)[0]
{ id: 'ses-003-2', ..., preuCentims: 4200, esdeveniment: 'Festival de Jazz de Primavera' }Aquí sort sobre el resultat de flatMap és segur: aquest array és nou, no l'original.
Solució 2
> .editor
function sessionsPerMes(esdeveniments) {
const recompte = {};
for (const esdeveniment of esdeveniments) {
for (const sessio of esdeveniment.sessions) {
// '2026-10-03T20:00:00'.slice(0, 7) === '2026-10'
const mes = sessio.dataHora.slice(0, 7);
recompte[mes] = (recompte[mes] ?? 0) + 1;
}
}
return recompte;
}Ctrl+D i a provar:
> sessionsPerMes(cataleg)
{ '2026-10': 5, '2027-04': 2 }
> console.table(sessionsPerMes(cataleg))
┌─────────┬────────┐
│ (index) │ Values │
├─────────┼────────┤
│ 2026-10 │ 5 │
│ 2027-04 │ 2 │
└─────────┴────────┘
> .save informes/exploracio-mesos.js
Session saved to: informes/exploracio-mesos.jsTingues en compte que .save desa tota la sessió, incloses les línies fallides. Revisa el fitxer abans de reutilitzar-lo.
Solució 3
# 1. Versio major de Node
node -p "process.versions.node.split('.')[0]"
# 24
# 2. Millisegons fins al Concierto de Otono
node -p "new Date('2026-10-03T20:00:00') - new Date()"
# 4483200000 (varia segons quan ho executis)
# 3. Centims a cadena amb dos decimals
node -p "(4200 / 100).toFixed(2)"
# 42.00
# 4. Comprovar si existeix la carpeta informes
node -p "require('node:fs').existsSync('informes')"
# trueAl punt 2, restar dos objectes Date els converteix automàticament a mil·lisegons des de l'època i retorna la diferència. Si prefereixes dies:
Conclusió
El REPL és el laboratori de Node.js: un entorn on provar idees costa zero. Has après a arrencar-lo amb node, a interpretar l'undefined de les declaracions, a encadenar càlculs amb _, a moure't amb Tab i l'historial, i a manejar les ordres de punt —.help, .editor, .save, .load, .break, .clear, .exit—.
Ho has aplicat a Escena Viva creant src/cataleg-dades.js i carregant-lo amb .load per explorar en directe: aplanar sessions amb flatMap, calcular la recaptació acumulada amb reduce, detectar la sessió més cara amb sort o descobrir que hi ha 1.189 entrades per vendre. També has vist node -e i node -p per a comprovacions des del terminal, i les peculiaritats que confonen al principi: els objectes literals que necessiten parèntesis, les promeses pendents i l'await de nivell superior.
I sobretot tens clar el límit: el REPL serveix per explorar; el que s'ha de repetir va a un fitxer, i el que s'ha de garantir va a un test.
En aquesta exploració han aparegut, gairebé de contraban, eines del JavaScript modern: flatMap, l'operador de propagació ..., la coalescència nul·la ??, les funcions fletxa i la desestructuració. A la lliçó següent, JavaScript Modern per a Node.js, les estudiarem una per una i amb calma, sempre resolent un problema real del catàleg d'Escena Viva. És el repàs que sostindrà tot el codi que escriguis d'aquí al final del curs.
Curs de Node.js: De Principiant a Avançat
Mòdul 1: Introducció a Node.js
- Què és Node.js?
- Instal·lació i Configuració de l'Entorn
- El Teu Primer Programa en Node.js
- El REPL de Node.js
- JavaScript Modern per a Node.js
- El Projecte del Curs: la Plataforma Escena Viva
Mòdul 2: Conceptes Bàsics
- Arquitectura de Node.js
- El Bucle d'Esdeveniments (Event Loop)
- Callbacks i Programació Asíncrona
- Promeses i async/await
- Esdeveniments i EventEmitter
- Mòduls CommonJS i require()
- Mòduls ES i Interoperabilitat
Mòdul 3: Sistema de Fitxers i E/S
- Lectura i Escriptura de Fitxers
- El Mòdul fs a Fons
- Rutes Multiplataforma amb el Mòdul path
- Treballant amb Streams
- Streams de Transformació i pipeline
- Buffers i Dades Binàries
Mòdul 4: HTTP i Servidors Web
- Creant un Servidor HTTP Simple
- Gestió de Sol·licituds i Respostes
- Enrutament Manual
- Servint Fitxers Estàtics
- Rebent Dades: Cossos de Petició i JSON
- Consumint APIs Externes des de Node.js
Mòdul 5: NPM i Gestió de Paquets
- Introducció a NPM i package.json
- Instal·lació i Ús de Paquets
- Versionat Semàntic i package-lock
- Scripts d'npm i Automatització del Projecte
- Creació i Publicació de Paquets
- Seguretat i Manteniment de Dependències
Mòdul 6: Framework Express.js
- Introducció a Express.js
- Configuració d'una Aplicació Express
- Enrutament a Express
- Middleware
- Middleware de Tercers Essencials
- Validació de Dades d'Entrada
- Gestió d'Errors
Mòdul 7: Bases de Dades i ORMs
- Introducció a les Bases de Dades
- Usant MongoDB amb Mongoose
- Operacions CRUD
- Relacions, Poblat i Consultes Avançades
- Usant Bases de Dades SQL amb Sequelize
- Migracions, Transaccions i Dades de Prova
Mòdul 8: Autenticació i Autorització
- Introducció a l'Autenticació
- Registre d'Usuaris i Hash de Contrasenyes
- Sessions i Galetes amb Passport.js
- Autenticació amb JWT
- Control d'Accés Basat en Rols
- Bones Pràctiques de Seguretat en APIs
Mòdul 9: Proves i Depuració
- Introducció a les Proves
- Proves Unitàries amb Mocha i Chai
- Dobles de Prova amb Sinon
- Proves d'Integració
- Cobertura i Automatització de les Proves
- Depuració d'Aplicacions Node.js
Mòdul 10: Temes Avançats
- El Mòdul Cluster
- Fils de Treball (Worker Threads)
- Memòria Cau i Cues de Treball amb Redis
- Optimització del Rendiment
- Construcció d'APIs RESTful
- GraphQL amb Node.js
Mòdul 11: Desplegament i DevOps
- Configuració i Variables d'Entorn
- Registre i Monitoratge en Producció
- Usant PM2 per a la Gestió de Processos
- Empaquetatge amb Docker
- Desplegant a Heroku i Altres PaaS
- Integració i Desplegament Continus
