Mòdul comunitari fantàstic

Mapa font

Estat de construcció

NPM

Aquesta és una biblioteca per generar i consumir el format de mapa font que es descriu aquí .

Utilitza amb Node

1
$ npm install source-map

Ús a la web

1 2 3 4 5 6
<script src="https://unpkg.com/source-map@0.7.2/dist/source-map.js"></script> <script> sourceMap.SourceMapConsumer.initialize({ "lib/mappings.wasm": "https://unpkg.com/source-map@0.7.2/lib/mappings.wasm" }); </script>

Taula de continguts

Exemples

Consuming a source map

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
const rawSourceMap = { version: 3, file: 'min.js', names: ['bar', 'baz', 'n'], sources: ['one.js', 'two.js'], sourceRoot: 'http://example.com/www/js/', mappings: 'CAAC,IAAI,IAAM,SAAUA,GAClB,OAAOC,IAAID;CCDb,IAAI,IAAM,SAAUE,GAClB,OAAOA' }; const whatever = await SourceMapConsumer.with(rawSourceMap, null, consumer => { console.log(consumer.sources); // [ 'http://example.com/www/js/one.js', // 'http://example.com/www/js/two.js' ] console.log(consumer.originalPositionFor({ line: 2, column: 28 })); // { source: 'http://example.com/www/js/two.js', // line: 2, // column: 10, // name: 'n' } console.log(consumer.generatedPositionFor({ source: 'http://example.com/www/js/two.js', line: 2, column: 10 })); // { line: 2, column: 28 } consumer.eachMapping(function (m) { // ... }); return computeWhatever(); });

Generating a source map

Guia en profunditat: compilació a JavaScript i depuració amb mapes font

Amb SourceNode (API d'alt nivell)

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
function compile(ast) { switch (ast.type) { case 'BinaryExpression': return new SourceNode( ast.location.line, ast.location.column, ast.location.source, [compile(ast.left), " + ", compile(ast.right)] ); case 'Literal': return new SourceNode( ast.location.line, ast.location.column, ast.location.source, String(ast.value) ); // ... default: throw new Error("Bad AST"); } } var ast = parse("40 + 2", "add.js"); console.log(compile(ast).toStringWithSourceMap({ file: 'add.js' })); // { code: '40 + 2', // map: [object SourceMapGenerator] }

Amb SourceMapGenerator (API de baix nivell)

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
var map = new SourceMapGenerator({ file: "source-mapped.js" }); map.addMapping({ generated: { line: 10, column: 35 }, source: "foo.js", original: { line: 33, column: 2 }, name: "christopher" }); console.log(map.toString()); // '{"version":3,"file":"source-mapped.js","sources":["foo.js"],"names":["christopher"],"mappings":";;;;;;;;;mCAgCEA"}'

API

Obteniu una referència al mòdul:

1 2 3 4 5 6 7 8
// Node.js var sourceMap = require('source-map'); // Browser builds var sourceMap = window.sourceMap; // Inside Firefox const sourceMap = require("devtools/toolkit/sourcemap/source-map.js");

SourceMapConsumer

Una SourceMapConsumerinstància representa un mapa d'origen analitzat que podem consultar per obtenir informació sobre les posicions dels fitxers originals donant-li una posició de fitxer a la font generada.

SourceMapConsumer.initialize(opcions)

Quan s'utilitza SourceMapConsumerfora de node.js, per exemple al web, ha de saber des de quina URL carregar lib/mappings.wasm. Heu d'informar-ho trucant initializeabans de construir qualsevol SourceMapConsumers.

L'objecte d'opcions té les propietats següents:

  • "lib/mappings.wasm": A Stringque conté l'URL del lib/mappings.wasmfitxer.
1 2 3
sourceMap.SourceMapConsumer.initialize({ "lib/mappings.wasm": "https://example.com/source-map/lib/mappings.wasm" });

nou SourceMapConsumer (rawSourceMap)

L'únic paràmetre és el mapa d'origen en brut (ja sigui com una cadena que pot ser JSON.parse'd o un objecte). Segons l'especificació, els mapes d'origen tenen els atributs següents:

  • version: quina versió de l'especificació del mapa font segueix aquest mapa.

  • sources: una matriu d'URL als fitxers font originals.

  • names: una matriu d'identificadors als quals es pot fer referència mitjançant mapes individuals.

  • sourceRoot: Opcional. L'arrel de l'URL des del qual totes les fonts són relatives.

  • sourcesContent: Opcional. Un conjunt de continguts dels fitxers font originals.

  • mappings: una cadena de VLQ base64 que contenen els mapes reals.

  • file: Opcional. El nom de fitxer generat al qual està associat aquest mapa font.

Es retorna la promesa del consumidor del mapa de font construït.

Quan ja SourceMapConsumerno s'utilitzarà, haureu d'anomenar el seu destroymètode.

1 2 3
const consumer = await new sourceMap.SourceMapConsumer(rawSourceMapJsonData); doStuffWith(consumer); consumer.destroy();

Alternativament, podeu utilitzar SourceMapConsumer.withper evitar haver de recordar trucar destroy.

SourceMapConsumer.with

Construeix un nou SourceMapConsumera partir de rawSourceMapi sourceMapUrl (vegeu el SourceMapConsumerconstructor per obtenir-ne més detalls. A continuació, invoqueu el async function f(SourceMapConsumer) -> Tamb el consumidor acabat de construir, espereu que fes completi, truqueu destroyal consumidor i retorneu fel valor de retorn.

No heu d'utilitzar el consumidor després de fcompletar-lo!

En utilitzar with, no cal que recordeu trucar manualment destroyal consumidor, ja que es trucarà automàticament un cop fs'hagi completat.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
const xSquared = await SourceMapConsumer.with( myRawSourceMap, null, async function (consumer) { // Use `consumer` inside here and don't worry about remembering // to call `destroy`. const x = await whatever(consumer); return x * x; } ); // You may not use that `consumer` anymore out here; it has // been destroyed. But you can use `xSquared`. console.log(xSquared);

SourceMapConsumer.prototype.destroy()

Allibereu les dades wasm associades al consumidor d'aquest mapa font que es gestionen manualment.

1
consumer.destroy();

Alternativament, podeu utilitzar SourceMapConsumer.withper evitar haver de recordar trucar destroy.

SourceMapConsumer.prototype.computeColumnSpans()

Calculeu l'última columna per a cada mapatge generat. L'última columna és inclusiva.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
// Before: consumer.allGeneratedPositionsFor({ line: 2, source: "foo.coffee" }) // [ { line: 2, // column: 1 }, // { line: 2, // column: 10 }, // { line: 2, // column: 20 } ] consumer.computeColumnSpans(); // After: consumer.allGeneratedPositionsFor({ line: 2, source: "foo.coffee" }) // [ { line: 2, // column: 1, // lastColumn: 9 }, // { line: 2, // column: 10, // lastColumn: 19 }, // { line: 2, // column: 20, // lastColumn: Infinity } ]

SourceMapConsumer.prototype.originalPositionFor(generatedPosition)

Retorna la informació original de la font, la línia i la columna per a les posicions de línia i columna de la font generada proporcionades. L'únic argument és un objecte amb les propietats següents:

  • line: el número de línia de la font generada. Els números de línia d'aquesta biblioteca es basen en 1 (tingueu en compte que l'especificació del mapa font subjacent utilitza números de línia basats en 0; aquesta biblioteca s'encarrega de la traducció).

  • column: el número de columna de la font generada. Els números de columna d'aquesta biblioteca es basen en 0.

  • biasEspecifica SourceMapConsumer.GREATEST_LOWER_BOUNDsi SourceMapConsumer.LEAST_UPPER_BOUNDs'ha de tornar l'element més proper que sigui més petit o més gran que el que estem cercant, respectivament, si no es pot trobar l'element exacte. Per defecte és SourceMapConsumer.GREATEST_LOWER_BOUND.

i es retorna un objecte amb les propietats següents:

  • source: el fitxer font original, o nul si aquesta informació no està disponible.

  • line: el número de línia a la font original o nul si aquesta informació no està disponible. El número de línia es basa en 1.

  • column: el número de columna de la font original o nul si aquesta informació no està disponible. El número de columna es basa en 0.

  • name: l'identificador original, o nul si aquesta informació no està disponible.

1 2 3 4 5 6 7 8 9 10 11
consumer.originalPositionFor({ line: 2, column: 10 }) // { source: 'foo.coffee', // line: 2, // column: 2, // name: null } consumer.originalPositionFor({ line: 99999999999999999, column: 999999999999999 }) // { source: null, // line: null, // column: null, // name: null }

SourceMapConsumer.prototype.generatedPositionFor(originalPosition)

Retorna la informació de línia i columna generada per a les posicions originals de la font, la línia i la columna proporcionades. L'únic argument és un objecte amb les propietats següents:

  • source: El nom del fitxer de la font original.

  • line: el número de línia a la font original. El número de línia es basa en 1.

  • column: el número de columna de la font original. El número de columna es basa en 0.

i es retorna un objecte amb les propietats següents:

  • line: el número de línia a la font generada o nul. El número de línia es basa en 1.

  • column: el número de columna de la font generada o nul. El número de columna es basa en 0.

1 2 3
consumer.generatedPositionFor({ source: "example.js", line: 2, column: 10 }) // { line: 1, // column: 56 }

SourceMapConsumer.prototype.allGeneratedPositionsFor(originalPosition)

Retorna tota la informació de la línia i la columna generada per a la font, la línia i la columna originals proporcionades. Si no es proporciona cap columna, retorna totes les assignacions corresponents a la línia que estem cercant o a la següent línia més propera que tingui mapes. En cas contrari, retorna tots els mapes corresponents a la línia donada i la columna que estem cercant o la següent columna més propera que tingui desplaçaments.

L'únic argument és un objecte amb les següents propietats:

  • source: El nom del fitxer de la font original.

  • line: el número de línia a la font original. El número de línia es basa en 1.

  • column: Opcional. El número de columna de la font original. El número de columna es basa en 0.

i es retorna una matriu d'objectes, cadascun amb les propietats següents:

  • line: el número de línia a la font generada o nul. El número de línia es basa en 1.

  • column: el número de columna de la font generada o nul. El número de columna es basa en 0.

1 2 3 4 5 6 7
consumer.allGeneratedpositionsfor({ line: 2, source: "foo.coffee" }) // [ { line: 2, // column: 1 }, // { line: 2, // column: 10 }, // { line: 2, // column: 20 } ]

SourceMapConsumer.prototype.hasContentsOfAllSources()

Retorna true si tenim el contingut d'origen incrustat per a totes les fonts enumerades al mapa font, fals en cas contrari.

En altres paraules, si aquest mètode torna true, llavors consumer.sourceContentFor(s)tindrà èxit per a totes les fonts sen consumer.sources.

1 2 3 4 5 6 7
// ... if (consumer.hasContentsOfAllSources()) { consumerReadyCallback(consumer); } else { fetchSources(consumer, consumerReadyCallback); } // ...

SourceMapConsumer.prototype.sourceContentFor(source[, returnNullOnMissing])

Retorna el contingut d'origen original de la font proporcionada. L'únic argument és l'URL del fitxer d'origen original.

Si no es troba el contingut d'origen de la font donada, es genera un error. Opcionalment, passa truecom a segon paràmetre per haver nullretornat.

1 2 3 4 5 6 7 8 9 10 11
consumer.sources // [ "my-cool-lib.clj" ] consumer.sourceContentFor("my-cool-lib.clj") // "..." consumer.sourceContentFor("this is not in the source map"); // Error: "this is not in the source map" is not in the source map consumer.sourceContentFor("this is not in the source map", true); // null

SourceMapConsumer.prototype.eachMapping (devolució de trucada, context, ordre)

Itereu sobre cada mapatge entre una font/línia/columna original i una línia/columna generada en aquest mapa font.

  • callback: La funció que s'anomena amb cada mapeig. Els mappings tenen la forma{ source, generatedLine, generatedColumn, originalLine, originalColumn, name }

  • context: Opcional. Si s'especifica, aquest objecte serà el valor de this cada cop que callbackes cridi.

  • order: o SourceMapConsumer.GENERATED_ORDERSourceMapConsumer.ORIGINAL_ORDER. Especifica si voleu iterar sobre les assignacions ordenades per l'ordre de línia/columna del fitxer generat o per l'ordre d'origen/línia/columna de l'original, respectivament. El valor per defecte és SourceMapConsumer.GENERATED_ORDER.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
consumer.eachMapping(function (m) { console.log(m); }) // ... // { source: 'illmatic.js', // generatedLine: 1, // generatedColumn: 0, // originalLine: 1, // originalColumn: 0, // name: null } // { source: 'illmatic.js', // generatedLine: 2, // generatedColumn: 0, // originalLine: 2, // originalColumn: 0, // name: null } // ...

SourceMapGenerator

Una instància del SourceMapGenerator representa un mapa font que s'està construint de manera incremental.

nou SourceMapGenerator([startOfSourceMap])

Podeu passar un objecte amb les propietats següents:

  • file: el nom de fitxer de la font generada amb la qual està associat aquest mapa font.

  • sourceRoot: una arrel per a tots els URL relatius en aquest mapa font.

  • skipValidation: Opcional. Quan true, desactiva la validació dels mapes a mesura que s'afegeixen. Això pot millorar el rendiment, però s'ha d'utilitzar amb discreció, com a últim recurs. Tot i així, s'ha d'evitar utilitzar aquest senyalador quan s'executen proves, si és possible.

1 2 3 4
var generator = new sourceMap.SourceMapGenerator({ file: "my-generated-javascript-file.js", sourceRoot: "http://example.com/app/js/" });

SourceMapGenerator.fromSourceMap(sourceMapConsumer)

Crea un nou SourceMapGeneratora partir d'una instància existent SourceMapConsumer.

  • sourceMapConsumerEl Mapa Font.
1
var generator = sourceMap.SourceMapGenerator.fromSourceMap(consumer);

SourceMapGenerator.prototype.addMapping(mapa)

Afegiu una única assignació de la línia i columna d'origen originals a la línia i columna de la font generada per a aquest mapa d'origen que s'està creant. L'objecte de mapeig ha de tenir les propietats següents:

  • generated: Un objecte amb les posicions de línia i columna generades.

  • original: Un objecte amb les posicions originals de línia i columna.

  • source: El fitxer font original (relatiu al sourceRoot).

  • name: un nom de testimoni original opcional per a aquest mapatge.

1 2 3 4 5
generator.addMapping({ source: "module-one.scm", original: { line: 128, column: 0 }, generated: { line: 3, column: 456 } })

SourceMapGenerator.prototype.setSourceContent(sourceFile, sourceContent)

Estableix el contingut d'origen per a un fitxer d'origen original.

  • sourceFilel'URL del fitxer font original.

  • sourceContentel contingut del fitxer font.

1 2
generator.setSourceContent("module-one.scm", fs.readFileSync("path/to/module-one.scm"))

SourceMapGenerator.prototype.applySourceMap(sourceMapConsumer[, sourceFile[, sourceMapPath]])

Aplica un SourceMap per a un fitxer font al SourceMap. Cada mapatge al fitxer font subministrat es reescriu amb el SourceMap subministrat. Nota: La resolució dels mapes resultants és el mínim d'aquest mapa i del mapa subministrat.

  • sourceMapConsumer: el mapa d'origen que s'ha d'aplicar.

  • sourceFile: Opcional. El nom del fitxer font. Si s'omet, s'utilitzarà sourceMapConsumer.file, si existeix. En cas contrari, es generarà un error.

  • sourceMapPath: Opcional. El dirname de la ruta al SourceMap que s'ha d'aplicar. Si és relatiu, és relatiu al SourceMap.

    Aquest paràmetre és necessari quan els dos mapes d'origen no es troben al mateix directori i el mapa d'origen que s'ha d'aplicar conté camins d'origen relatius. Si és així, aquests s'han de reescriure en relació amb el mapa d'origen.

    Si s'omet, s'assumeix que els dos mapes font estan al mateix directori, per la qual cosa no necessita cap reescriptura (el subministrament '.'té el mateix efecte).

SourceMapGenerator.prototype.toString()

Representa el mapa font que s'està generant en una cadena.

1 2
generator.toString() // '{"version":3,"sources":["module-one.scm"],"names":[],"mappings":"...snip...","file":"my-generated-javascript-file.js","sourceRoot":"http://example.com/app/js/"}'

SourceNode

Els SourceNodes ofereixen una manera d'abstraure sobre la interpolació i/o la concatenació de fragments del codi font de JavaScript generat, alhora que mantenen la informació de línia i columna associada entre aquests fragments i el codi font original. Això és útil com a representació intermèdia final que un compilador pot utilitzar abans de sortir. el JS generat i el mapa font.

nou SourceNode([línia, columna, font[, tros[, nom]]])

  • line: el número de línia original associat a aquest node font, o nul si no està associat amb una línia original. El número de línia es basa en 1.

  • column: el número de columna original associat amb aquest node d'origen o nul si no està associat a una columna original. El número de columna està basat en 0.

  • source: el nom de fitxer de la font original; nul si no es proporciona cap nom de fitxer.

  • chunk: Opcional. Es passa immediatament a SourceNode.prototype.add, vegeu a continuació.

  • name: Opcional. L'identificador original.

1 2 3 4 5
var node = new SourceNode(1, 2, "a.cpp", [ new SourceNode(3, 4, "b.cpp", "extern int status;\n"), new SourceNode(5, 6, "c.cpp", "std::string* make_string(size_t n);\n"), new SourceNode(7, 8, "d.cpp", "int main(int argc, char** argv) {}\n"), ]);

SourceNode.fromStringWithSourceMap(codi, sourceMapConsumer[, relativePath])

Crea un SourceNode a partir del codi generat i un SourceMapConsumer.

  • code: El codi generat

  • sourceMapConsumerEl mapa font per al codi generat

  • relativePathEl camí opcional al qual sourceMapConsumer haurien de ser les fonts relatives.

1 2
const consumer = await new SourceMapConsumer(fs.readFileSync("path/to/my-file.js.map", "utf8")); const node = SourceNode.fromStringWithSourceMap(fs.readFileSync("path/to/my-file.js"), consumer);

SourceNode.prototype.add(tros)

Afegiu un tros de JS generat a aquest node font.

  • chunk: un fragment de cadena del codi JS generat, una altra instància de SourceNode, o una matriu on cada membre és una d'aquestes coses.
1 2 3
node.add(" + "); node.add(otherNode); node.add([leftHandOperandNode, " + ", rightHandOperandNode]);

SourceNode.prototype.prepend(tros)

Afegiu un tros de JS generat a aquest node font.

  • chunk: un fragment de cadena del codi JS generat, una altra instància de SourceNode, o una matriu on cada membre és una d'aquestes coses.
1
node.prepend("/** Build Id: f783haef86324gf **/\n\n");

SourceNode.prototype.setSourceContent(sourceFile, sourceContent)

Estableix el contingut d'origen d'un fitxer d'origen. Això s'afegirà al SourceMapcamp sourcesContent.

  • sourceFile: El nom del fitxer font

  • sourceContent: El contingut del fitxer font

1 2
node.setSourceContent("module-one.scm", fs.readFileSync("path/to/module-one.scm"))

SourceNode.prototype.walk(fn)

Passeu per l'arbre dels fragments de JS d'aquest node i dels seus fills. La funció de caminada es crida una vegada per a cada fragment de JS i se li passa aquest fragment i la ubicació de la línia/columna de la font associada original.

  • fn: La funció transversal.
1 2 3 4 5 6 7 8 9 10 11 12 13 14
var node = new SourceNode(1, 2, "a.js", [ new SourceNode(3, 4, "b.js", "uno"), "dos", [ "tres", new SourceNode(5, 6, "c.js", "quatro") ] ]); node.walk(function (code, loc) { console.log("WALK:", code, loc); }) // WALK: uno { source: 'b.js', line: 3, column: 4, name: null } // WALK: dos { source: 'a.js', line: 1, column: 2, name: null } // WALK: tres { source: 'a.js', line: 1, column: 2, name: null } // WALK: quatro { source: 'c.js', line: 5, column: 6, name: null }

SourceNode.prototype.walkSourceContents(fn)

Passeu per l'arbre de SourceNodes. La funció de caminada es crida per a cada contingut del fitxer font i se'ls passa el nom del fitxer i el contingut d'origen.

  • fn: La funció transversal.
1 2 3 4 5 6 7 8 9 10 11 12
var a = new SourceNode(1, 2, "a.js", "generated from a"); a.setSourceContent("a.js", "original a"); var b = new SourceNode(1, 2, "b.js", "generated from b"); b.setSourceContent("b.js", "original b"); var c = new SourceNode(1, 2, "c.js", "generated from c"); c.setSourceContent("c.js", "original c"); var node = new SourceNode(null, null, null, [a, b, c]); node.walkSourceContents(function (source, contents) { console.log("WALK:", source, ":", contents); }) // WALK: a.js : original a // WALK: b.js : original b // WALK: c.js : original c

SourceNode.prototype.join(set)

Igual que Array.prototype.joinexcepte per a SourceNodes. Insereix el separador entre cadascun dels fills d'aquest node font.

  • sep: El separador.
1 2 3 4 5 6
var lhs = new SourceNode(1, 2, "a.rs", "my_copy"); var operand = new SourceNode(3, 4, "a.rs", "="); var rhs = new SourceNode(5, 6, "a.rs", "orig.clone()"); var node = new SourceNode(null, null, null, [ lhs, operand, rhs ]); var joinedNode = node.join(" ");

SourceNode.prototype.replaceRight (patró, substitució)

Truqueu String.prototype.replaceal fragment d'origen més a la dreta. Útil per retallar l'espai en blanc des del final d'un node font, etc.

  • pattern: el patró a substituir.

  • replacement: La cosa per substituir el patró.

1 2
// Trim trailing white space. node.replaceRight(/\s*$/, "");

SourceNode.prototype.toString()

Retorna la representació de cadena d'aquest node font. Passa per l'arbre i concatena tots els diferents fragments en una cadena.

1 2 3 4 5 6 7 8 9 10 11
var node = new SourceNode(1, 2, "a.js", [ new SourceNode(3, 4, "b.js", "uno"), "dos", [ "tres", new SourceNode(5, 6, "c.js", "quatro") ] ]); node.toString() // 'unodostresquatro'

SourceNode.prototype.toStringWithSourceMap([startOfSourceMap])

Retorna la representació de cadena d'aquest arbre de nodes font, més un SourceMapGenerator que conté tots els mapes entre les fonts generades i originals.

Els arguments són els mateixos que els de new SourceMapGenerator.

1 2 3 4 5 6 7 8 9 10 11 12
var node = new SourceNode(1, 2, "a.js", [ new SourceNode(3, 4, "b.js", "uno"), "dos", [ "tres", new SourceNode(5, 6, "c.js", "quatro") ] ]); node.toStringWithSourceMap({ file: "my-output-file.js" }) // { code: 'unodostresquatro', // map: [object SourceMapGenerator] }