Módulo de comunidad impresionante

Mapa fuente

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

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 instancia de SourceMapConsumer 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 use SourceMapConsumer fuera de node.js, por ejemplo en la Web, necesita saber desde qué URL cargar lib/mappings.wasm . Debe informarlo llamando a initialize antes de construir cualquier SourceMapConsumer s.

El objeto de opciones tiene las siguientes propiedades:

  • "lib/mappings.wasm" : una String contiene la URL del archivo lib/mappings.wasm .
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 puede ser JSON.parse o 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 fuente originales.

  • names : una matriz de identificadores que pueden ser referenciados por 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 el SourceMapConsumer ya no se use más, debe llamar a su método de destroy .

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

Alternativamente, puede usar SourceMapConsumer.with para evitar tener que recordar llamar a destroy .

SourceMapConsumer.with

Construya un nuevo SourceMapConsumer partir de rawSourceMap y sourceMapUrl (consulte el constructor SourceMapConsumer para obtener detalles de Then, Invoke The. async function f(SourceMapConsumer) -> T con el consumidor recién construido, la espera de f para completar, Call destroy ON The Consumer, y devuelve f Valor devuelto.

¡No debe usar el consumidor después de que se complete f !

Al usar with , no tiene que recordar llamar manualmente a destroy en el consumidor, ya que se llamará automáticamente una vez que f 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 ()

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

1
consumer.destroy();

Alternativamente, puede usar SourceMapConsumer.with para evitar tener que recordar llamar a 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 original de la fuente, línea y columna 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 : SourceMapConsumer.GREATEST_LOWER_BOUND o SourceMapConsumer.LEAST_UPPER_BOUND . Especifica si se debe devolver el elemento más cercano que sea más pequeño 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 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 (originalPosition)

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 se basa en 0.

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

SourceMapConsumer.prototype.allGeneratedPositionsFor (originalPosition)

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 devuelve true , entonces consumer.sourceContentFor(s) tendrá éxito para cada fuente s en 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 de la fuente para la fuente dada, se genera un error. Opcionalmente, pase true como segundo parámetro para que se devuelva un null .

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 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 se llame a la callback llamada.

  • order : O SourceMapConsumer.GENERATED_ORDER o 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. El valor predeterminado es 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 es 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 un nuevo SourceMapGenerator partir de una instancia de SourceMapConsumer existente.

  • 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 suministrado. 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 SourceMap.

    Si se omite, se asume que ambos SourceMaps están en el mismo directorio, por lo que no es necesario reescribirlos (proporcionar '.' 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 sobre 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 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 : 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 El SourceMap para el código generado

  • relativePath La ruta opcional que las fuentes relativas en sourceMapConsumer deben ser relativas a.

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 de origen.

  • chunk : un fragmento de cadena de código JS generado, otra instancia de SourceNode o 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 SourceNode o una matriz donde 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 SourceMap en el sourcesContent campo.

  • sourceFile : el nombre 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 fuente y se 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 (sep)

Como Array.prototype.join excepto 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 a String.prototype.replace en el 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 : el elemento con el que se reemplaza 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 de origen, más un SourceMapGenerator que contiene todas las asignaciones entre las fuentes generadas y originales.

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