Tutte le novità di Node.js 20
Node.js 20.0.0 è stato rilasciato il 18 aprile 2023 e rappresenta la prima versione ufficiale della serie 20. La versione 20 è una versione LTS e quindi rimarrà per parecchio tempo in circolazione: sarà supportata fino al 30 aprile 2026.
La versione 20.0.0 è stata solo la prima versione della serie 20 e, ad oggi (dicembre 2024), quasi altre 30 versioni della stessa serie sono state rilasciate, arrivando alla 20.18.0.
Le novità principali della 20.0.0
Le novità principali introdotte nella versione 20.0.0 di Node.js sono le quattro elencate di seguito.
Permission model
Il permission model permette di avviare un’applicazione limitando le risorse a cui Node.js (e quindi l’applicazione in esecuzione) può accedere e cosa può farci.
Lo scopo del permission model rappresenta un altro passo importante verso il miglioramento della sicurezza delle applicazioni Node.js.
Con questo modello diventa possibile limitare l’accesso a risorse specifiche durante l’esecuzione del programma, come operazioni sul file system, la creazione di child process e di worker thread.
La funzionalità è sperimentale e richiede l’utilizzo del flag --experimental-permission
per essere attivata.
Esempio che abilita solo la lettura e scrittura sul filesystem:
node --experimental-permission --allow-fs-read=* --allow-fs-write=* index.js
Documentazione a questo link.
V8 versione 11.3
La nuova versione di V8 inclusa in Node.js è la 11.3 che porta nuove aggiunte alle API JavaScript:
- il metodo
String.prototype.isWellFormed()
per verificare se la stringa è valida rispetto a UTF-16, eString.prototype.toWellFormed()
per trasformarla in una valida (proposal-is-usv-string); - i metodi
toReversed()
,toSorted(compareFn)
,toSpliced(start, deleteCount, ...items)
ewith(index, value)
per trasformare l’Array (o un TypedArray e derivati - es.Uint8Array
) e restituire una nuova copia senza alterare l’originale (proposal-change-array-by-copy); - supporto per il ridimensionamento di
ArrayBuffer
eSharedArrayBuffer
(proposal); - nuove funionalità per RegExp (proposal-regexp-v-flag);
- supporto per la ricorsione di coda in WebAssembly (proposal-tail-call);
Test runner stabile
Il test runner integrato in Node.js e introdotto come experimental nella serie 18 è ora segnato come stabile e pronto per la produzione.
import { test } from "node:test";
import assert from "node:assert";
test("an addition", () => {
assert.strictEqual(1 + 1, 2);
});
ARM64 per Windows
Il supporto alla piattaforma ARM64 Windows è ora passata al tier 2 e permette l’esecuzione nativa di Node.js. Ogni nuova build di Node.js è ora verificata anche per ARM64 Windows affinché non ci siano bug o regressioni.
Altre novità
- il parser di URL Ada è stato aggiornato alla versione 2.0 con i relativi miglioramenti di prestazioni;
- i loader ESM personalizzati sono ora eseguiti in un thread separato;
import.meta.resolve()
viene eseguito in modo sincrono in modo simile a quanto fatto dai browser;- le funzioni delle API Web Crypto API sono validate usando la specifica per migliorare la compatibilità con le altre implementazioni;
20.1.0
Rilascio con correzioni e piccole migliore sulle funzionalità esistenti
20.2.0
Rlascio con correzioni e piccole migliore sulle funzionalità esistenti
20.3.0
La modifica principale è l’aggiornamento di libuv
alla versione 1.45.0.
Questa versione aggiunge il supporto a io_uring per alcune operazioni asincrone:
read
,write
fsync
,fdatasync
stat
,fstat
,lstat
Questa funzionalità si attiva solo quando Node.js viene eseguito su Linux e solo se il kernel in uso è almeno il 5.13.
Il throughput aumenta di 8 volte rispetto all’utilizzo del thread pool standard per questo tipo di operazioni.
20.3.1
Questo rilascio contiene patch di sicurezza, principalmente correlati al permission model introdotto con la 20.0.0. C’è un motivo se è segnato come experimental, ed è proprio questo.
20.4.0
Mock timers
Il modulo node:test
riceve la possibilità di usare dei mock per i timer (setTimeout
, setInterval
più tutti quelli presenti in node:timers
e node:timers/promises
). Questi mock permettono di scrivere dei test che dipendono dal tempo senza la necessità di dover effettivamente attendere il passaggio di quel tempo.
Grazie a questi mock i test diventano più semplici e il loro risultanto più certo. Tra le funzionalità esposte da questi mock ci sono quelle di poter far avanzare il tempo, scegliere quale timer attivare e quale rilasciare.
Un esempio che mostra le varie possibilità:
import assert from "node:assert";
import { test } from "node:test";
test("mocks setTimeout to be executed synchronously without having to actually wait for it", (context) => {
const fn = context.mock.fn();
// Optionally choose what to mock
context.mock.timers.enable(["setTimeout"]);
const nineSecs = 9000;
setTimeout(fn, nineSecs);
const threeSeconds = 3000;
context.mock.timers.tick(threeSeconds);
context.mock.timers.tick(threeSeconds);
context.mock.timers.tick(threeSeconds);
assert.strictEqual(fn.mock.callCount(), 1);
});
Supporto per la gestione esplicita delle risorse
È stato aggiunto il supporto alla proposal-explicit-resource-management per fornire il supporto, a livello di linguaggio, del pattern di gestione delle risorse.
20.5.0
Rilascio con correzioni e piccole migliore sulle funzionalità esistenti.
20.5.1
Questo rilascio contiene patch di sicurezza, principalmente correlati al permission model introdotto con la 20.0.0. Sì, di nuovo.
20.6.0
Supporto per i file .env
Node.js ora supporta i file .env
per configurare le variabili d’ambiente. Questo permette di definire le variabili d’ambiente direttamente nei file .env
, eliminando la necessità di includerle nel package.json
o di usare moduli esterni.
I file .env
devono essere in formato INI dove ogni linea è nel formato chiave-valore per una singola variabile d’ambiente.
Per far leggere il file ad un’applicazione è necessario usare un’opzione aggiuntiva: node --env-file=config.env index.js
.
Dato il file config.env
:
SECRET=my-password
DB_URI=mongodb://localhost:27017
È possibile accedere a queste variabili attraverso process.env.SECRET
e process.env.DB_URI
.
Anche la variabile NODE_OPTIONS
è definibile all’interno di questo file.
Altre novità
import.meta.resolve(specifier)
non è più sperimentale e può essere usata per ottnere l’URL in cui viene risolto il parametrospecifier
. Questo è simile a require.resolve() di CommonJS ed è stato aggiunto per allineare il funzionamento di Node.js con quello dei browser e degli altri runtime che implementano la specifica ESM;- API register() e hook
initialize
per i moduli ESM, hook load() anche per i moduli CommonJS; - aggiunto il supporto per il garbace collector
cppgc
(Oilpan);
20.6.1
Correzioni.
20.7.0
- supporto per il passaggio di più file
.env
attraverso l’opzione--env-file
; - supporto per più opzioni
--allow-fs-*
; - l’output dei test inviato al reporter include la posizione del file di test eseguito e le linee/colonne in caso d’errore;
20.8.0
Performance degli Stream
In questa versione le performance degli stream (readable e writable) sono migliorate. La creazione e distruzione degli stream è ora più veloce come anche l’utilizzo della memoria usata da ogni stream è diminuita.
Anche i readable webstream hanno subito miglioramenti di performance.
Altro
- aggiunto il reporter nel formato
junit
al test runner; - refactor della gestione della memoria del modulo
vm
che risolve diversi memory leak;
20.8.1
Release di sicurezza di ottobre 2023
20.9.0
Questa release segna il passaggio della serie 20 di Node.js nello stato di Active LTS.
20.10.0
- aggiunto il supporto all’opzione
flush
per assicurarsi che i dati vengano effettivamente scritti sul disco prima che la funzionefs.writeFile()
(e le altre simili) termini l’esecuzione; - migliorate le performance degli stream;
- aggiunto il flag
--experimental-default-type
per cambiare il modo in cui i moduli devono essere interpretati (se non diversamente specificato); - aggiunto il flag
--experimental-detect-module
per caricare un modulo ambiguo (es. se la sua estensione è.js
) trattandolo come ES se la sua sintassi interna corrisponde; - aggiunto il flag
--experimental-websocket
per attivare un clientWebSocket
globale che rispetta lo standard;
20.11.0
- aggiunto il supporto a
import.meta.dirname
eimport.meta.filename
per i moduli ECMAScript;
20.11.1
Release di sicurezza.
20.12.0
util.styleText
È stata aggiunta la funzione util.styleText(format, text)
che restituisce il testo formattato secondo lo stile indicato (colori e enfasi).
const { styleText } = require("node:util");
const errorMessage = styleText("red", "Error!");
console.log(errorMessage);
crypto.hash()
La nuova funzione di utilità crypto.hash()
permette di calcolare un hash usando una singola chiamate.
Questo processo è fino a due volte più veloce del metodo createHash()
quando l’input è inferiore ai 5MB e richiede meno memoria.
const crypto = require("node:crypto");
// Hashing a string and return the result as a hex-encoded string.
const string = "Node.js";
// 10b3493287f831e81a438811a1ffba01f8cec4b7
console.log(crypto.hash("sha1", string));
Caricamento e parsing di variabili d’ambiente
Sono disponibili due nuove funzioni. La prima è process.loadEnvFile(path)
che carica il file .env
indicato (o quello presente nella directory attuale se il parametro non viene specificato).
La seconda è util.parseEnv(content)
che effettua il parsing di una stringa nello stesso formato dei file .env
(es. util.parseEnv('HELLO=world')
).
Nuovi eventi per net.createConnection
L’utilizzo di net.createConnection
espone tre nuovi eventi legati al tentativo di connessione: connectionAttempt
, connectionAttemptFailed
e connectionAttemptTimeout
.
Novità nel permission model
È stato aggiunto il nuovo flag -allow-addons
che permette l’utilizzo degli addon quando il permission model è attivo.
Inoltre, il già esistente --allow-fs-*
è stato modificato per permettere l’utilizzo di path relativi.
20.12.1
Release di sicurezza.
20.12.2
Release di sicurezza.
20.13.0
- le performance della codifica e decodifica di base64 e base64url sono migliorate in modo importante;
CustomEvent
è segnato come stabile- le API di
fs/promises
aggiungono uno stacktrace in caso d’errore; - aggiunto il supporto per i typed arrays negli stream;
util.styleText
supporta un array di formati:console.log(util.styleText(['underline', 'italic'], 'My italic underlined message'))
;- Watch Mode è ora stabile;
20.13.1
Release con correzioni.
20.14.0
Release con aggiornamenti interni.
20.15.0
- aggiunta la funzione
zlib.crc32()
; - aggiunto il flag
--inspect-wait
per attendere il collegamento del debugger; - aggiunto il support per i test plan che permette di indicare il numero di asserzioni e test che devono essere eseguiti all’interno del singolo test: in caso contrario il test fallirà;
test("top level test", (t) => {
t.plan(2);
t.assert.ok("some relevant assertion here");
t.subtest("subtest", () => {});
});
20.15.1
Release di sicurezza.
20.16.0
- aggiunta la funzione
process.getBuiltinModule(id)
che permette di caricare un modulo interno di Node.js. Questo permette di sviluppare dei moduli che devono supportare ambienti diversi da Node.js in modo più semplice; - aggiunto flag
--allow-wasi
per il supporto di WASI attraverso il permission model;
20.17.0
- aggiunto il flag
--experimental-require-module
che permette il caricamento sincrono di moduli ES (non deve avere top level async-await); - aggiunta la funzione
duplexPair()
che implementa le DuplexPair API. Quando è invocata restituisce un array con due stream, ognuno connesso all’altro: quello che viene scritto in uno diventa disponibile nell’altro:const [ sideA, sideB ] = duplexPair()
;
20.18.0
La principale novità introdotta in questa versione è il supporto (experimental) al network inspector per Node.js.
Avviando Node.js con il flag --experimental-network-inspection
diventa possibile collegare l’inspector di Chrome e fare debug delle richieste di rete.
La funzionalità è ancora in sviluppo ed è necessario che Chrome effettui dei cambiamenti. Intanto è possibile provarla usando:
node --inspect-wait --experimental-network-inspection -e "require('https').get('https://nodejs.org/en', (res) => { console.log(res.statusCode); })"
Debugger listening on ws://127.0.0.1:9229/<inspector-websocket-id>
For help, see: https://nodejs.org/en/docs/inspector
E poi aprire in Chrome l’URL devtools://devtools/bundled/inspector.html?ws=127.0.0.1:9229/<inspector-websocket-id>
usando l’id del websocket mostrato nel terminale.
20.18.1
Release con aggiornamenti interni.
Date di rilascio delle versioni
Codice | Data di Rilascio |
---|---|
20.0.0 | 18 aprile 2023 |
20.1.0 | 3 maggio 2023 |
20.2.0 | 16 maggio 2023 |
20.3.0 | 8 giugno 2023 |
20.3.1 | 20 giugno 2023 |
20.4.0 | 5 luglio 2023 |
20.5.0 | 18 luglio 2023 |
20.5.1 | 9 agosto 2023 |
20.6.0 | 4 settembre 2023 |
20.6.1 | 8 settembre 2023 |
20.7.0 | 18 settembre 2023 |
20.8.0 | 28 settembre 2023 |
20.8.1 | 5 ottobre 2023 |
20.9.0 | 24 ottobre 2023 |
20.10.0 | 22 novembre 2023 |
20.11.0 | 9 gennaio 2024 |
20.11.1 | 9 gennaio 2024 |
20.12.0 | 26 marzo 2024 |
20.12.1 | 26 marzo 2024 |
20.12.2 | 26 marzo 2024 |
20.13.0 | 7 maggio 2024 |
20.13.1 | 7 maggio 2024 |
20.14.0 | 28 maggio 2024 |
20.15.0 | 20 giugno 2024 |
20.15.1 | 20 giugno 2024 |
20.16.0 | 24 luglio 2024 |
20.17.0 | 21 agosto 2024 |
20.18.0 | 3 ottobre 2024 |
20.18.1 | 20 novembre 2024 |