Che cosa sono le mappe di origine?

Le mappe di origine sono uno strumento fondamentale nel moderno sviluppo web che rendono il debug molto più semplice. Questa pagina illustra le nozioni di base delle mappe di origine, come vengono generate e in che modo migliorano l'esperienza di debug.

La necessità di utilizzare le mappe di origine

Le prime app web erano poco complesse. Gli sviluppatori hanno implementato i file HTML, CSS e JavaScript direttamente sul web.

Le app web più moderne e complesse possono richiedere una varietà di strumenti nel flusso di lavoro di sviluppo. Ad esempio:

Una breve panoramica dei vari strumenti.
Alcuni degli strumenti più comuni per lo sviluppo di app web.

Questi strumenti richiedono un processo di compilazione per eseguire il transpile del tuo codice in HTML, JavaScript e CSS standard comprensibili dai browser. È pratica comune anche ottimizzare il rendimento minimizzando e combinando questi file, utilizzando uno strumento come Terser.

Ad esempio, con gli strumenti di creazione, possiamo eseguire il transpile e comprimere il seguente file TypeScript in un'unica riga di JavaScript. Puoi fare una prova in questa demo su GitHub.

/* A TypeScript demo: example.ts */

document.querySelector('button')?.addEventListener('click', () => {
  const num: number = Math.floor(Math.random() * 101);
  const greet: string = 'Hello';
  (document.querySelector('p') as HTMLParagraphElement).innerText = `${greet}, you are no. ${num}!`;
  console.log(num);
});

Una versione compressa sarebbe:

/* A compressed JavaScript version of the TypeScript demo: example.min.js  */

document.querySelector("button")?.addEventListener("click",(()=>{const e=Math.floor(101*Math.random());document.querySelector("p").innerText=`Hello, you are no. ${e}!`,console.log(e)}));

Tuttavia, la compressione del codice può rendere più difficile il debug. Le mappe di origine possono risolvere il problema: mappando il codice compilato al codice originale, possono aiutarti a trovare rapidamente l'origine di un errore.

Genera mappe di origine

Le mappe di origine sono file i cui nomi terminano con .map (ad esempio, example.min.js.map e styles.css.map). Possono essere generate dalla maggior parte degli strumenti di creazione, tra cui Vite, webpack, Rollup, Parcel ed esbuild.

Alcuni strumenti includono le mappe di origine per impostazione predefinita. Altre potrebbero aver bisogno di configurazioni aggiuntive per produrle:

/* Example configuration: vite.config.js */
/* https://vitejs.dev/config/ */

export default defineConfig({
  build: {
    sourcemap: true, // enable production source maps
  },
  css: {
    devSourcemap: true // enable CSS source maps during development
  }
})

Informazioni sulla mappa di origine

Per facilitare il debug, questi file delle mappe di origine contengono informazioni essenziali su come il codice compilato viene mappato al codice originale. Ecco un esempio di mappa di origine:

{
  "mappings": "AAAAA,SAASC,cAAc,WAAWC, ...",
  "sources": ["src/script.ts"],
  "sourcesContent": ["document.querySelector('button')..."],
  "names": ["document","querySelector", ...],
  "version": 3,
  "file": "example.min.js.map"
}

Per comprendere ognuno di questi campi, puoi leggere la specifica della mappa di origine o L'anatomia di una mappa di origine.

La parte più importante di una mappa di origine è il campo mappings. Utilizza una stringa codificata in base 64 VLQ per mappare le righe e le posizioni nel file compilato al file originale corrispondente. Puoi visualizzare questa mappatura utilizzando un visualizzatore delle mappe di origine come source-map-visualizzazione o Visualizzazione mappa di origine.

Una visualizzazione della mappa di origine.
Una visualizzazione dell'esempio di codice precedente, generato da un visualizzatore.

La colonna Generato a sinistra mostra i contenuti compressi, mentre la colonna Originale mostra la sorgente originale.

Il visualizzatore codifica con un colore ogni riga nella colonna original con il codice corrispondente nella colonna generate.

La sezione mappature mostra le mappature decodificate del codice. Ad esempio, la voce 65 -> 2:2 indica:

  • Codice generato: la parola const inizia in posizione 65 nei contenuti compressi.
  • Codice originale: la parola const inizia dalla riga 2 e dalla colonna 2 nei contenuti originali.
Mappatura della voce in corso.
La visualizzazione mappatura, incentrata sulla voce 65 -> 2:2.

In questo modo gli sviluppatori possono identificare rapidamente la relazione tra il codice minimizzato e il codice originale e semplificare il processo di debug.

Gli strumenti per sviluppatori del browser applicano queste mappe di origine per aiutarti a individuare rapidamente i problemi di debug nel browser.

Strumenti per sviluppatori che applicano una mappa di origine.
Un esempio di come gli strumenti per sviluppatori dei browser applicano le mappe di origine e mostrano le mappature tra i file.

Estensioni mappa di origine

Le mappe di origine supportano i campi di estensioni personalizzate che iniziano con un prefisso x_. Un esempio è il campo dell'estensione x_google_ignoreList proposto da Chrome DevTools. Consulta x_google_ignoreList per scoprire di più su come queste estensioni ti aiutano a concentrarti sul codice.

Svantaggi della mappa di origine

Purtroppo, le mappature delle fonti non sono sempre complete come dovrebbero. Nel nostro primo esempio, la variabile greet è stata ottimizzata durante il processo di compilazione, anche se il suo valore è incorporato direttamente nell'output finale della stringa.

Il greet variabile non è mappato.
La variabile greet nel codice originale non è presente nel mapping.

In questo caso, quando esegui il debug del codice, gli strumenti per sviluppatori potrebbero non riuscire a dedurre e visualizzare il valore effettivo. Questo tipo di errore può rendere più difficile il monitoraggio e l'analisi del codice.

Il greet variabile non è definito.
Lo strumento per sviluppatori non riesce a trovare un valore per greet.

Questo è un problema che deve essere risolto nella progettazione delle mappe di origine. Una potenziale soluzione è includere le informazioni sull'ambito nelle mappe di origine nello stesso modo in cui altri linguaggi di programmazione fanno con le loro informazioni di debug.

Tuttavia, ciò richiede la collaborazione dell'intero ecosistema per migliorare la specifica e l'implementazione delle mappe di origine. Per continuare a migliorare la possibilità di debug con le mappe di origine, fai riferimento alla proposta per Source Maps v4 su GitHub.