Impresionante módulo comunitario

Mapa de orixe

Estado de construción

NPM

Esta é unha biblioteca para xerar e consumir o formato de mapa fonte descrito aquí .

Usar con Node

1
$ npm install source-map

Use na 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>

Táboa de contidos

Exemplos

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

Guía en profundidade: compilación en JavaScript e depuración con mapas de orixe

Con SourceNode (API de alto nivel)

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] }

Con SourceMapGenerator (API de baixo nivel)

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

Obter unha referencia ao módulo:

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

Unha SourceMapConsumerinstancia representa un mapa de orixe analizado que podemos consultar para obter información sobre as posicións orixinais do ficheiro dándolle unha posición de ficheiro na fonte xerada.

SourceMapConsumer.initialize(opcións)

Cando se usa SourceMapConsumerfóra de node.js, por exemplo na web, necesita saber de que URL cargar lib/mappings.wasm. Debes informarlle chamando initializeantes de construír calquera SourceMapConsumers.

O obxecto de opcións ten as seguintes propiedades:

  • "lib/mappings.wasm": A que Stringcontén o URL do lib/mappings.wasmficheiro.
1 2 3
sourceMap.SourceMapConsumer.initialize({ "lib/mappings.wasm": "https://example.com/source-map/lib/mappings.wasm" });

novo SourceMapConsumer (rawSourceMap)

O único parámetro é o mapa de orixe en bruto (como unha cadea que pode ser JSON.parse'd ou un obxecto). Segundo a especificación, os mapas de orixe teñen os seguintes atributos:

  • version: que versión da especificación do mapa fonte segue este mapa.

  • sources: unha matriz de URL para os ficheiros de orixe orixinais.

  • names: unha matriz de identificadores aos que se pode facer referencia mediante asignacións individuais.

  • sourceRoot: Opcional. O URL raíz do que todas as fontes son relativas.

  • sourcesContent: Opcional. Unha matriz de contidos dos ficheiros de orixe orixinais.

  • mappings: Unha cadea de VLQ base64 que conteñen as asignacións reais.

  • file: Opcional. O nome de ficheiro xerado ao que está asociado este mapa de orixe.

Devólvese a promesa do consumidor do mapa de orixe construído.

Cando SourceMapConsumerxa non se use, debes chamar ao seu destroymétodo.

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

Alternativamente, pode usar SourceMapConsumer.withpara evitar ter que lembrar de chamar destroy.

SourceMapConsumer.con

Constrúe un novo SourceMapConsumera partir de rawSourceMape sourceMapUrl (consulte o SourceMapConsumerconstrutor para obter máis detalles. A continuación, invoque o async function f(SourceMapConsumer) -> Tco consumidor recén construído, agarde a que fse complete, chame destroyao consumidor e devolva fo valor de retorno.

Non debes usar o consumidor despois de fcompletar!

Ao usar with, non tes que lembrar de chamar manualmente destroyao consumidor, xa que chamarase automaticamente unha vez que fse complete.

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()

Libere os datos wasm asociados ao consumidor deste mapa fonte que se xestionan manualmente.

1
consumer.destroy();

Alternativamente, pode usar SourceMapConsumer.withpara evitar ter que lembrar de chamar destroy.

SourceMapConsumer.prototype.computeColumnSpans()

Calcula a última columna para cada asignación xerada. A última columna é 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)

Devolve a información orixinal da fonte, da liña e da columna para as posicións da liña e columna da fonte xerada proporcionadas. O único argumento é un obxecto coas seguintes propiedades:

  • line: o número de liña na fonte xerada. Os números de liña nesta biblioteca están baseados en 1 (teña en conta que a especificación do mapa de orixe subxacente usa números de liña baseados en 0; esta biblioteca xestiona a tradución).

  • column: o número de columna da fonte xerada. Os números de columna desta biblioteca están baseados en 0.

  • biasSourceMapConsumer.GREATEST_LOWER_BOUNDEspecifica se SourceMapConsumer.LEAST_UPPER_BOUNDse devolve o elemento máis próximo que sexa menor ou maior que o que estamos a buscar, respectivamente, se non se pode atopar o elemento exacto. Por defecto é SourceMapConsumer.GREATEST_LOWER_BOUND.

e devólvese un obxecto coas seguintes propiedades:

  • source: o ficheiro fonte orixinal ou nulo se esta información non está dispoñible.

  • line: o número de liña na fonte orixinal ou nulo se esta información non está dispoñible. O número de liña está baseado en 1.

  • column: o número de columna na fonte orixinal ou nulo se esta información non está dispoñible. O número de columna está baseado en 0.

  • name: o identificador orixinal ou nulo se esta información non está dispoñible.

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)

Devolve a información xerada da liña e da columna para as posicións orixinais da fonte, da liña e da columna proporcionadas. O único argumento é un obxecto coas seguintes propiedades:

  • source: O nome do ficheiro da fonte orixinal.

  • line: o número de liña na fonte orixinal. O número de liña está baseado en 1.

  • column: o número de columna da fonte orixinal. O número de columna está baseado en 0.

e devólvese un obxecto coas seguintes propiedades:

  • line: o número de liña na fonte xerada ou nulo. O número de liña está baseado en 1.

  • column: o número de columna da fonte xerada ou nulo. O número de columna está baseado en 0.

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

SourceMapConsumer.prototype.allGeneratedPositionsFor(originalPosition)

Devolve toda a información xerada de liñas e columnas para a fonte, a liña e a columna orixinais proporcionadas. Se non se fornece ningunha columna, devolve todas as asignacións correspondentes á liña que estamos a buscar ou á seguinte liña máis próxima que teña ningunha asignación. En caso contrario, devolve todas as asignacións correspondentes á liña indicada e á columna que estamos a buscar ou á seguinte columna máis próxima que teña algún desfase.

O único argumento é un obxecto coas seguintes propiedades:

  • source: O nome do ficheiro da fonte orixinal.

  • line: o número de liña na fonte orixinal. O número de liña está baseado en 1.

  • column: Opcional. O número de columna da fonte orixinal. O número de columna está baseado en 0.

e devólvese unha matriz de obxectos, cada un coas seguintes propiedades:

  • line: o número de liña na fonte xerada ou nulo. O número de liña está baseado en 1.

  • column: o número de columna da fonte xerada ou nulo. O número de columna está baseado 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()

Devolve verdadeiro se temos o contido fonte incrustado para todas as fontes listadas no mapa de orixe, false en caso contrario.

Noutras palabras, se este método devolve true, entón consumer.sourceContentFor(s)terá éxito para cada fonte sen consumer.sources.

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

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

Devolve o contido orixinal da fonte proporcionada. O único argumento é o URL do ficheiro fonte orixinal.

Se non se atopa o contido da fonte dada, bótase un erro. Opcionalmente, pasa truecomo o segundo parámetro para ter nulldevolto.

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ón de chamada, contexto, orde)

Itera sobre cada asignación entre unha fonte/liña/columna orixinal e unha liña/columna xerada neste mapa fonte.

  • callback: A función que se chama con cada asignación. As asignacións teñen a forma{ source, generatedLine, generatedColumn, originalLine, originalColumn, name }

  • context: Opcional. Se se especifica, este obxecto será o valor de this cada vez que callbackse chame.

  • order: ou SourceMapConsumer.GENERATED_ORDERben SourceMapConsumer.ORIGINAL_ORDER. Especifica se quere iterar sobre as asignacións ordenadas pola orde de liñas/columnas do ficheiro xerado ou a orde de orixe/liña/columna do orixinal, respectivamente. Por defecto é 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

Unha instancia de SourceMapGenerator representa un mapa de orixe que se está construíndo de forma incremental.

novo SourceMapGenerator([startOfSourceMap])

Podes pasar un obxecto coas seguintes propiedades:

  • file: O nome do ficheiro da fonte xerada coa que está asociado este mapa de orixe.

  • sourceRoot: unha raíz para todos os URL relativos neste mapa de orixe.

  • skipValidation: Opcional. Cando true, desactiva a validación das asignacións a medida que se engaden. Isto pode mellorar o rendemento, pero debe usarse con discreción, como último recurso. Aínda así, débese evitar usar esta marca cando se executan probas, se é posible.

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 unha nova SourceMapGeneratora partir dunha instancia existente SourceMapConsumer.

  • sourceMapConsumerO mapa de orixe.
1
var generator = sourceMap.SourceMapGenerator.fromSourceMap(consumer);

SourceMapGenerator.prototype.addMapping(mapeo)

Engade unha única asignación desde a liña e columna de orixe orixinais á liña e columna da fonte xerada para este mapa de orixe que se está creando. O obxecto de asignación debe ter as seguintes propiedades:

  • generated: Un obxecto coas posicións de liña e columna xeradas.

  • original: Un obxecto coas posicións orixinais da liña e da columna.

  • source: O ficheiro fonte orixinal (relativo ao sourceRoot).

  • name: un nome de token orixinal opcional para esta asignación.

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)

Establece o contido de orixe para un ficheiro de orixe orixinal.

  • sourceFileo URL do ficheiro fonte orixinal.

  • sourceContento contido do ficheiro fonte.

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

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

Aplica un SourceMap para un ficheiro fonte ao SourceMap. Cada asignación ao ficheiro fonte fornecido reescríbese usando o SourceMap fornecido. Nota: A resolución das asignacións resultantes é a mínima deste mapa e do mapa fornecido.

  • sourceMapConsumer: o mapa de orixe que se vai aplicar.

  • sourceFile: Opcional. O nome do ficheiro de orixe. Se se omite, utilizarase sourceMapConsumer.file, se existe. En caso contrario, xerarase un erro.

  • sourceMapPath: Opcional. O nome directo da ruta ao mapa de orixe que se vai aplicar. Se é relativo, é relativo ao mapa de orixe.

    Este parámetro é necesario cando os dous mapas de orixe non están no mesmo directorio e o mapa de orixe que se vai aplicar contén rutas de orixe relativas. Se é así, estas rutas de orixe deben reescribirse en relación co mapa de orixe.

    Se se omite, suponse que ambos os mapas de orixe están no mesmo directorio, polo que non precisan reescrituras (o fornecemento '.'ten o mesmo efecto).

SourceMapGenerator.prototype.toString()

Renderiza o mapa de orixe que se está xerando nunha cadea.

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

Os SourceNodes proporcionan unha forma de abstraer por interpolar e/ou concatenar fragmentos do código fonte de JavaScript xerado, mantendo a información de liña e columna asociada entre eses fragmentos e o código fonte orixinal. Isto é útil como a representación intermedia final que un compilador pode usar antes de emitir. o JS xerado e o mapa fonte.

novo SourceNode([liña, columna, fonte[, anaco[, nome]]])

  • line: o número de liña orixinal asociado a este nodo fonte ou nulo se non está asociado a unha liña orixinal. O número de liña está baseado en 1.

  • column: o número de columna orixinal asociado a este nodo fonte ou nulo se non está asociado a unha columna orixinal. O número de columna está baseado en 0.

  • source: o nome do ficheiro da fonte orixinal; nulo se non se proporciona ningún nome de ficheiro.

  • chunk: Opcional. Pásase inmediatamente a SourceNode.prototype.add, consulte a continuación.

  • name: Opcional. O identificador orixinal.

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(código, sourceMapConsumer[, relativePath])

Crea un SourceNode a partir do código xerado e un SourceMapConsumer.

  • code: O código xerado

  • sourceMapConsumerO mapa de orixe para o código xerado

  • relativePathO camiño opcional no que sourceMapConsumer deberían ser relativos as fontes relativas.

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 (anaco)

Engade un anaco de JS xerado a este nodo fonte.

  • chunk: un fragmento de cadea do código JS xerado, outra instancia de SourceNode, ou unha matriz onde cada membro é unha desas cousas.
1 2 3
node.add(" + "); node.add(otherNode); node.add([leftHandOperandNode, " + ", rightHandOperandNode]);

SourceNode.prototype.prepend(anaco)

Anteponga un anaco de JS xerado a este nodo fonte.

  • chunk: un fragmento de cadea do código JS xerado, outra instancia de SourceNode, ou unha matriz onde cada membro é unha desas cousas.
1
node.prepend("/** Build Id: f783haef86324gf **/\n\n");

SourceNode.prototype.setSourceContent(sourceFile, sourceContent)

Establece o contido de orixe dun ficheiro de orixe. Este engadirase ao SourceMapcampo sourcesContent.

  • sourceFile: O nome do ficheiro de orixe

  • sourceContent: O contido do ficheiro fonte

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

SourceNode.prototype.walk(fn)

Pasea sobre a árbore de fragmentos de JS deste nodo e dos seus fillos. A función de andar chámase unha vez por cada fragmento de JS e pásase ese fragmento e a localización da liña/columna da orixe asociada orixinal.

  • fn: A función 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)

Paseo sobre a árbore de SourceNodes. A función de andar é chamada para cada contido do ficheiro de orixe e pásase o nome do ficheiro e o contido de orixe.

  • fn: A función 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 Array.prototype.join, excepto para SourceNodes. Insire o separador entre cada un dos fillos deste nodo fonte.

  • sep: O 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ón, substitución)

Chama String.prototype.replaceao fragmento de fonte máis á dereita. Útil para recortar espazos en branco desde o final dun nodo fonte, etc.

  • pattern: o patrón a substituír.

  • replacement: A cousa coa que substituír o patrón.

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

SourceNode.prototype.toString()

Devolve a representación en cadea deste nodo fonte. Percorre a árbore e concatena todos os distintos fragmentos nunha soa cadea.

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])

Devolve a representación en cadea desta árbore de nodos fonte, ademais dun SourceMapGenerator que contén todas as asignacións entre as fontes xeradas e orixinais.

Os argumentos son os mesmos que os 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] }