Módulo de comunidad impresionante

Mapa de origen

Estado de la construcción

NPM

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

Usar con Node

1
$ npm install source-map

Usar 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 de

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": Que Stringcontiene 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 de origen sin formato (ya sea como una cadena que se puede convertir JSON.parseo un objeto). Según la especificación, los mapas de origen tienen los siguientes atributos:

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

  • sources: Una matriz de URL a los archivos de origen originales.

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

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

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

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

  • file: Opcional. El nombre de archivo generado con el que está asociado este mapa de origen.

Se devuelve la promesa del consumidor de mapas de origen construido.

Cuando SourceMapConsumerya no se utilice más, debe llamar a su destroymétodo.

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

Alternativamente, puede usar SourceMapConsumer.withpara evitar tener que recordar llamar destroy.

SourceMapConsumer.with

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 fque se complete, llame destroyal consumidor y devuelva fel valor de retorno).

¡No debe usar el consumidor después de fcompletar!

Al usar with, no tiene que recordar llamar manualmente destroyal consumidor, ya que se llamará automáticamente una vez que se fcomplete.

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

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

1
consumer.destroy();

Alternativamente, puede usar SourceMapConsumer.withpara evitar tener que recordar 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 (generatePosition)

Devuelve la información de la 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 se basan en 1 (tenga en cuenta que la especificación del mapa de 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_BOUNDbien 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 SourceMapConsumer.GREATEST_LOWER_BOUND.

y se devuelve un objeto con las siguientes propiedades:

  • source: El archivo de origen 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 se basa 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 se basa en 1.

  • column: El número de columna en la fuente original. El número de columna se basa 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 se basa 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 original, la línea y la columna proporcionada. Si no se proporciona ninguna columna, devuelve todas las asignaciones correspondientes a la línea que estamos buscando o la siguiente línea más cercana que tenga alguna asignación. De lo contrario, devuelve todas las asignaciones correspondientes a la línea dada y la columna que estamos buscando o la siguiente columna más cercana que tenga alguna compensación.

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 se basa 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 se basa 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 de origen incrustado para cada fuente enumerada en el mapa de origen, falso en caso contrario

En otras palabras, si este método regresa 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 fuente original de la fuente proporcionada. El único argumento es la URL del archivo fuente original.

Si no se encuentra el contenido de la fuente para la fuente dada, entonces se genera un error. Opcionalmente, pase truecomo el segundo parámetro que se haya nulldevuelto en su lugar.

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)

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

  • callback: La función que se llama con cada asignación. Las asignaciones 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 SourceMapConsumer.GENERATED_ORDERbien SourceMapConsumer.ORIGINAL_ORDER. Especifica si desea iterar sobre las asignaciones ordenadas por el orden de línea / columna del archivo generado o 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 de origen que se está construyendo de forma incremental.

nuevo SourceMapGenerator ([startOfSourceMap])

Puede pasar un objeto con las siguientes propiedades:

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

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

  • skipValidation: Opcional. Cuando true, deshabilita la validación de las 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 esta marca 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 (sourceMapConsumer)

Crea una instancia nueva a SourceMapGeneratorpartir de una existente SourceMapConsumer.

  • sourceMapConsumer El SourceMap.
1
var generator = sourceMap.SourceMapGenerator.fromSourceMap(consumer);

SourceMapGenerator.prototype.addMapping (mapeo)

Agregue un único mapeo 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 mapeo 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 (sourceFile, sourceContent)

Establezca el contenido de origen de un archivo de origen original.

  • sourceFile la URL del archivo fuente original.

  • sourceContent el 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 de origen. Si se omite, se utilizará sourceMapConsumer.file, si existe. De lo contrario, se producirá 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 SourceMaps 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 reescribirlos (el suministro '.'tiene el mismo efecto).

SourceMapGenerator.prototype.toString ()

Renderiza el mapa de origen 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 la interpolación y / o concatenación de fragmentos de código fuente JavaScript generado, mientras se mantiene la información de línea y columna asociada entre esos fragmentos y el código fuente original. Esto es útil como la representación intermedia final que un compilador podría usar antes de generar la salida. el JS generado y el mapa de origen.

new 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 se basa 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 de 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 [, relativaPath])

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

  • code: El código generado

  • sourceMapConsumer 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 un trozo de JS generado a este nodo de origen.

  • chunk: Un fragmento de cadena de código JS generado, otra instancia de SourceNodeo una matriz en la que 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 en la que cada miembro es una de esas cosas.
1
node.prepend("/** Build Id: f783haef86324gf **/\n\n");

SourceNode.prototype.setSourceContent (sourceFile, sourceContent)

Establecer el contenido de código para un archivo de origen. Esto se añade a la SourceMapen el sourcesContentcampo.

  • sourceFile: El nombre de archivo del archivo de origen

  • sourceContent: El contenido del archivo fuente

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

SourceNode.prototype.walk (fn)

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

  • 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 de archivo de origen y se pasa el nombre del archivo y el contenido de origen.

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

Me gusta 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 situado más a la derecha. Útil para recortar el espacio en blanco del final de un nodo fuente, etc.

  • pattern: El patrón a reemplazar.

  • replacement: Lo que se debe reemplazar el patrón.

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

SourceNode.prototype.toString ()

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

Devuelve la representación de cadena de este árbol de nodos fuente, más un SourceMapGenerator que contiene todas las asignaciones entre las fuentes generadas 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] }