Impresionante módulo comunitario

Mapa fuente

Estado de construcción

MNP

Esta es una biblioteca para generar y consumir el formato de mapa fuente que se describe aquí .

Usar con nodo

1
$ npm install source-map

Uso en 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>

Tabla de contenido

Ejemplos

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 detallada: compilación en JavaScript y depuración con mapas de origen

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 bajo 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

Obtenga una referencia al 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

Una SourceMapConsumerinstancia representa un mapa fuente analizado que podemos consultar para obtener información sobre las posiciones del archivo original dándole una posición del archivo en la fuente generada.

SourceMapConsumer.initialize(opciones)

Cuando se usa SourceMapConsumerfuera de node.js, por ejemplo en la Web, necesita saber desde qué URL cargar lib/mappings.wasm. Debe informarlo llamando initializeantes de construir cualquier SourceMapConsumers.

El objeto de opciones tiene las siguientes propiedades:

  • "lib/mappings.wasm": A Stringque contiene la URL del lib/mappings.wasmarchivo.
1 2 3
sourceMap.SourceMapConsumer.initialize({ "lib/mappings.wasm": "https://example.com/source-map/lib/mappings.wasm" });

nuevo SourceMapConsumer (rawSourceMap)

El único parámetro es el mapa fuente sin formato (ya sea como una cadena que puede ser JSON.parse'd o un objeto). Según la especificación, los mapas fuente tienen los siguientes atributos:

  • version: Qué versión de la especificación del mapa fuente sigue este mapa.

  • sources: una serie de URL a los archivos fuente originales.

  • names: una serie de identificadores a los que se puede hacer referencia mediante asignaciones individuales.

  • sourceRoot: Opcional. La raíz URL desde la cual todas las fuentes son relativas.

  • sourcesContent: Opcional. Una matriz de contenidos de los archivos fuente originales.

  • mappings: una cadena de VLQ base64 que contienen las asignaciones reales.

  • file: Opcional. El nombre de archivo generado al que está asociado este mapa fuente.

Se devuelve la promesa del consumidor del mapa fuente construido.

Cuando ya SourceMapConsumerno se utilice, debe llamar a su destroymétodo.

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

Alternativamente, puedes usar SourceMapConsumer.withpara evitar tener que acordarte de llamar destroy.

FuenteMapConsumer.con

Construya un nuevo SourceMapConsumerdesde rawSourceMapy sourceMapUrl (consulte el SourceMapConsumerconstructor para obtener más detalles. Luego, invoque async function f(SourceMapConsumer) -> Tcon el consumidor recién construido, espere a que fse complete, llame destroyal consumidor y devuelva fel valor de retorno.

¡No debes utilizar el consumidor después de fcompletarlo!

Al utilizar with, no es necesario recordar llamar manualmente destroyal consumidor, ya que se llamará automáticamente una 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);

FuenteMapConsumer.prototype.destroy()

Libere los datos wasm asociados de este consumidor de mapas de origen que se administran manualmente.

1
consumer.destroy();

Alternativamente, puedes usar SourceMapConsumer.withpara evitar tener que acordarte de llamar destroy.

SourceMapConsumer.prototype.computeColumnSpans()

Calcule la última columna para cada mapeo generado. La última columna es 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)

Devuelve la información de fuente, línea y columna original para las posiciones de línea y columna de la fuente generada proporcionadas. El único argumento es un objeto con las siguientes propiedades:

  • line: El número de línea en la fuente generada. Los números de línea en esta biblioteca están basados ​​en 1 (tenga en cuenta que la especificación del mapa fuente subyacente utiliza números de línea basados ​​en 0; esta biblioteca maneja la traducción).

  • column: El número de columna en la fuente generada. Los números de columna en esta biblioteca están basados ​​en 0.

  • bias: O SourceMapConsumer.GREATEST_LOWER_BOUNDo SourceMapConsumer.LEAST_UPPER_BOUND.Especifica si se debe devolver el elemento más cercano que sea menor o mayor que el que estamos buscando, respectivamente, si no se puede encontrar el elemento exacto. El valor predeterminado es SourceMapConsumer.GREATEST_LOWER_BOUND.

y se devuelve un objeto con las siguientes propiedades:

  • source: El archivo fuente original, o nulo si esta información no está disponible.

  • line: El número de línea en la fuente original, o nulo si esta información no está disponible. El número de línea está basado en 1.

  • column: El número de columna en la fuente original, o nulo si esta información no está disponible. El número de columna está basado en 0.

  • name: El identificador original, o nulo si esta información 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(posición original)

Devuelve la información de línea y columna generada para las posiciones de fuente, línea y columna originales proporcionadas. El único argumento es un objeto con las siguientes propiedades:

  • source: El nombre de archivo de la fuente original.

  • line: El número de línea en la fuente original. El número de línea está basado en 1.

  • column: El número de columna en la fuente original. El número de columna está basado en 0.

y se devuelve un objeto con las siguientes propiedades:

  • line: El número de línea en la fuente generada, o nulo. El número de línea está basado en 1.

  • column: El número de columna en la fuente generada, o nulo. El número de columna está basado en 0.

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

SourceMapConsumer.prototype.allGeneratedPositionsFor(posición original)

Devuelve toda la información de línea y columna generada para la fuente, línea y columna original proporcionada. Si no se proporciona ninguna columna, devuelve todas las asignaciones correspondientes a la línea que estamos buscando o a la siguiente línea más cercana que tenga asignaciones. De lo contrario, devuelve todas las asignaciones correspondientes a la línea dada y a la columna que estamos buscando o a la siguiente columna más cercana que tenga desplazamientos.

El único argumento es un objeto con las siguientes propiedades:

  • source: El nombre de archivo de la fuente original.

  • line: El número de línea en la fuente original. El número de línea está basado en 1.

  • column: Opcional. El número de columna en la fuente original. El número de columna está basado en 0.

y se devuelve una matriz de objetos, cada uno con las siguientes propiedades:

  • line: El número de línea en la fuente generada, o nulo. El número de línea está basado en 1.

  • column: El número de columna en la fuente generada, o nulo. El número de columna está basado 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()

Devuelve verdadero si tenemos el contenido fuente incrustado para cada fuente enumerada en el mapa fuente; en caso contrario, falso.

En otras palabras, si este método devuelve true, consumer.sourceContentFor(s)tendrá éxito para todas las fuentes sen consumer.sources.

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

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

Devuelve el contenido original de la fuente proporcionada. El único argumento es la URL del archivo fuente original.

Si no se encuentra el contenido fuente de la fuente dada, se genera un error. Opcionalmente, páselo truecomo el segundo parámetro que se nulldevolvió.

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 llamada, contexto, orden)

Itere sobre cada mapeo entre una fuente/línea/columna original y una línea/columna generada en este mapa fuente.

  • callback: La función que se llama con cada mapeo. Los mapeos tienen la forma{ source, generatedLine, generatedColumn, originalLine, originalColumn, name }

  • context: Opcional. Si se especifica, este objeto será el valor de this cada vez que callbackse llame.

  • order: O bien SourceMapConsumer.GENERATED_ORDERo SourceMapConsumer.ORIGINAL_ORDEREspecifica si desea iterar sobre las asignaciones ordenadas por el orden de líneas/columnas del archivo generado o por el orden de fuente/línea/columna del original, respectivamente 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 instancia de SourceMapGenerator representa un mapa fuente que se construye de forma incremental.

nuevo SourceMapGenerator([inicioDeSourceMap])

Puede pasar un objeto con las siguientes propiedades:

  • file: El nombre de archivo de la fuente generada a la que está asociado este mapa de fuente.

  • sourceRoot: una raíz para todas las URL relativas en este mapa de origen.

  • skipValidation: Opcional. Cuando true, deshabilita la validación de asignaciones a medida que se agregan. Esto puede mejorar el rendimiento, pero debe usarse con discreción, como último recurso. Incluso entonces, se debe evitar el uso de este indicador al ejecutar pruebas, si es posible.

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

SourceMapGenerator.fromSourceMap(fuenteMapConsumer)

Crea una nueva instancia SourceMapGeneratora partir de una instancia existente SourceMapConsumer.

  • sourceMapConsumerEl mapa fuente.
1
var generator = sourceMap.SourceMapGenerator.fromSourceMap(consumer);

SourceMapGenerator.prototype.addMapping(mapeo)

Agregue una única asignación de la línea y columna de la fuente original a la línea y columna de la fuente generada para este mapa de origen que se está creando. El objeto de asignación debe tener las siguientes propiedades:

  • generated: Un objeto con las posiciones de línea y columna generadas.

  • original: Un objeto con las posiciones originales de línea y columna.

  • source: El archivo fuente original (relativo a sourceRoot).

  • name: un nombre de token original 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 (archivo fuente, contenido fuente)

Establezca el contenido fuente de un archivo fuente original.

  • sourceFilela URL del archivo fuente original.

  • sourceContentel contenido del archivo fuente.

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 archivo fuente al SourceMap. Cada asignación al archivo fuente proporcionado se reescribe utilizando el SourceMap proporcionado. Nota: La resolución de las asignaciones resultantes es la mínima de este mapa y el mapa proporcionado.

  • sourceMapConsumer: El SourceMap que se aplicará.

  • sourceFile: Opcional. El nombre del archivo fuente. Si se omite, se usará sourceMapConsumer.file, si existe. De lo contrario, se generará un error.

  • sourceMapPath: Opcional. El nombre de directorio de la ruta al SourceMap que se aplicará. Si es relativo, es relativo al SourceMap.

    Este parámetro es necesario cuando los dos SourceMap no están en el mismo directorio y el SourceMap que se va a aplicar contiene rutas de origen relativas. Si es así, esas rutas de origen relativas deben reescribirse en relación con el SourceMap.

    Si se omite, se supone que ambos SourceMaps están en el mismo directorio, por lo que no es necesario volver a escribirlos (el suministro '.'tiene el mismo efecto).

FuenteMapGenerator.prototype.toString()

Representa el mapa fuente que se genera 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

SourceNodes proporciona una forma de abstraer sobre interpolación y/o concatenación de fragmentos de código fuente JavaScript generado, manteniendo al mismo tiempo la información de línea y columna asociada entre esos fragmentos y el código fuente original. Esto es útil como representación intermedia final que un compilador podría usar antes de generar el JS generado y el mapa fuente.

nuevo SourceNode([línea, columna, fuente[, fragmento[, nombre]]])

  • line: El número de línea original asociado con este nodo de origen, o nulo si no está asociado con una línea original. El número de línea está basado en 1.

  • column: el número de columna original asociado con este nodo de origen, o nulo si no está asociado con una columna original. El número de columna está basado en 0.

  • source: El nombre del archivo de la fuente original; nulo si no se proporciona ningún nombre de archivo.

  • chunk: Opcional. Se pasa inmediatamente a SourceNode.prototype.add, ver más abajo.

  • name: Opcional El 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 (código, sourceMapConsumer [, ruta relativa])

Crea un SourceNode a partir del código generado y un SourceMapConsumer.

  • code:El código generado

  • sourceMapConsumerEl SourceMap para el código generado

  • relativePathLa ruta opcional a la que sourceMapConsumer deben ser relativas las fuentes 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(fragmento)

Agregue una parte del JS generado a este nodo fuente.

  • chunk: un fragmento de cadena de código JS generado, otra instancia de SourceNodeo una matriz donde cada miembro es una de esas cosas.
1 2 3
node.add(" + "); node.add(otherNode); node.add([leftHandOperandNode, " + ", rightHandOperandNode]);

SourceNode.prototype.prepend(fragmento)

Anteponga un fragmento de JS generado a este nodo de origen.

  • chunk: un fragmento de cadena de código JS generado, otra instancia de SourceNodeo una matriz donde cada miembro es una de esas cosas.
1
node.prepend("/** Build Id: f783haef86324gf **/\n\n");

SourceNode.prototype.setSourceContent (archivo fuente, contenido fuente)

Establezca el contenido fuente de un archivo fuente. Esto se agregará al SourceMapcampo sourcesContent.

  • sourceFile: El nombre del archivo fuente

  • sourceContent: El contenido del archivo fuente.

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

FuenteNodo.prototipo.walk(fn)

Camine sobre el árbol de fragmentos de JS en este nodo y sus hijos. La función de caminata se llama una vez para cada fragmento de JS y se pasa ese fragmento y la ubicación de línea/columna de su fuente original asociada.

  • fn: La 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)

Camine sobre el árbol de SourceNodes. La función de caminar se llama para cada contenido del archivo fuente y se le pasa el nombre del archivo y el contenido fuente.

  • fn: La 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(septiembre)

Como Array.prototype.joinexcepto para SourceNodes. Inserta el separador entre cada uno de los hijos de este nodo de origen.

  • 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ón, reemplazo)

Llame String.prototype.replaceal fragmento de código fuente más a la derecha. Útil para recortar espacios en blanco desde el final de un nodo de origen, etc.

  • pattern: El patrón a reemplazar.

  • replacement: Lo que se reemplaza con el patrón.

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

FuenteNode.prototype.toString()

Devuelve la representación de cadena de este nodo de origen. Camina sobre el árbol y concatena todos los distintos fragmentos en una sola 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([inicioDeSourceMap])

Devuelve la representación de cadena de este árbol de nodos de origen, además de un SourceMapGenerator que contiene todas las asignaciones entre los orígenes generados y originales.

Los argumentos son los mismos que los 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] }